xfs: use actual inode count for sparse records in bulkstat/inumbers
The bulkstat and inumbers mechanisms make the assumption that inode records consist of a full 64 inode chunk in several places. For example, this is used to track how many inodes have been processed overall as well as to determine whether a record has allocated inodes that must be handled. This assumption is invalid for sparse inode records. While sparse inodes will be marked as free in the ir_free mask, they are not accounted as free in ir_freecount because they cannot be allocated. Therefore, ir_freecount may be less than 64 inodes in an inode record for which all physically allocated inodes are free (and in turn ir_freecount < 64 does not signify that the record has allocated inodes). The new in-core inobt record format includes the ir_count field. This holds the number of true, physical inodes tracked by the record. The in-core ir_count field is always valid as it is hardcoded to XFS_INODES_PER_CHUNK when sparse inodes is not enabled. Use ir_count to handle inode records correctly in bulkstat in a generic manner. Signed-off-by: Brian Foster <bfoster@redhat.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
This commit is contained in:
parent
5419040fc0
commit
12d0714d4b
1 changed files with 8 additions and 5 deletions
|
@ -252,7 +252,7 @@ xfs_bulkstat_grab_ichunk(
|
|||
}
|
||||
|
||||
irec->ir_free |= xfs_inobt_maskn(0, idx);
|
||||
*icount = XFS_INODES_PER_CHUNK - irec->ir_freecount;
|
||||
*icount = irec->ir_count - irec->ir_freecount;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -415,6 +415,8 @@ xfs_bulkstat(
|
|||
goto del_cursor;
|
||||
if (icount) {
|
||||
irbp->ir_startino = r.ir_startino;
|
||||
irbp->ir_holemask = r.ir_holemask;
|
||||
irbp->ir_count = r.ir_count;
|
||||
irbp->ir_freecount = r.ir_freecount;
|
||||
irbp->ir_free = r.ir_free;
|
||||
irbp++;
|
||||
|
@ -447,13 +449,15 @@ xfs_bulkstat(
|
|||
* If this chunk has any allocated inodes, save it.
|
||||
* Also start read-ahead now for this chunk.
|
||||
*/
|
||||
if (r.ir_freecount < XFS_INODES_PER_CHUNK) {
|
||||
if (r.ir_freecount < r.ir_count) {
|
||||
xfs_bulkstat_ichunk_ra(mp, agno, &r);
|
||||
irbp->ir_startino = r.ir_startino;
|
||||
irbp->ir_holemask = r.ir_holemask;
|
||||
irbp->ir_count = r.ir_count;
|
||||
irbp->ir_freecount = r.ir_freecount;
|
||||
irbp->ir_free = r.ir_free;
|
||||
irbp++;
|
||||
icount += XFS_INODES_PER_CHUNK - r.ir_freecount;
|
||||
icount += r.ir_count - r.ir_freecount;
|
||||
}
|
||||
error = xfs_btree_increment(cur, 0, &stat);
|
||||
if (error || stat == 0) {
|
||||
|
@ -599,8 +603,7 @@ xfs_inumbers(
|
|||
agino = r.ir_startino + XFS_INODES_PER_CHUNK - 1;
|
||||
buffer[bufidx].xi_startino =
|
||||
XFS_AGINO_TO_INO(mp, agno, r.ir_startino);
|
||||
buffer[bufidx].xi_alloccount =
|
||||
XFS_INODES_PER_CHUNK - r.ir_freecount;
|
||||
buffer[bufidx].xi_alloccount = r.ir_count - r.ir_freecount;
|
||||
buffer[bufidx].xi_allocmask = ~r.ir_free;
|
||||
if (++bufidx == bcount) {
|
||||
long written;
|
||||
|
|
Loading…
Reference in a new issue