diff options
Diffstat (limited to 'fs/xfs/xfs_itable.c')
-rw-r--r-- | fs/xfs/xfs_itable.c | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index acae3355ab22..ff3f431671b9 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -236,8 +236,10 @@ xfs_bulkstat_grab_ichunk( | |||
236 | XFS_WANT_CORRUPTED_RETURN(stat == 1); | 236 | XFS_WANT_CORRUPTED_RETURN(stat == 1); |
237 | 237 | ||
238 | /* Check if the record contains the inode in request */ | 238 | /* Check if the record contains the inode in request */ |
239 | if (irec->ir_startino + XFS_INODES_PER_CHUNK <= agino) | 239 | if (irec->ir_startino + XFS_INODES_PER_CHUNK <= agino) { |
240 | return -EINVAL; | 240 | *icount = 0; |
241 | return 0; | ||
242 | } | ||
241 | 243 | ||
242 | idx = agino - irec->ir_startino + 1; | 244 | idx = agino - irec->ir_startino + 1; |
243 | if (idx < XFS_INODES_PER_CHUNK && | 245 | if (idx < XFS_INODES_PER_CHUNK && |
@@ -352,7 +354,6 @@ xfs_bulkstat( | |||
352 | xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ | 354 | xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ |
353 | xfs_ino_t lastino; /* last inode number returned */ | 355 | xfs_ino_t lastino; /* last inode number returned */ |
354 | int nirbuf; /* size of irbuf */ | 356 | int nirbuf; /* size of irbuf */ |
355 | int rval; /* return value error code */ | ||
356 | int ubcount; /* size of user's buffer */ | 357 | int ubcount; /* size of user's buffer */ |
357 | struct xfs_bulkstat_agichunk ac; | 358 | struct xfs_bulkstat_agichunk ac; |
358 | int error = 0; | 359 | int error = 0; |
@@ -388,7 +389,6 @@ xfs_bulkstat( | |||
388 | * Loop over the allocation groups, starting from the last | 389 | * Loop over the allocation groups, starting from the last |
389 | * inode returned; 0 means start of the allocation group. | 390 | * inode returned; 0 means start of the allocation group. |
390 | */ | 391 | */ |
391 | rval = 0; | ||
392 | while (agno < mp->m_sb.sb_agcount) { | 392 | while (agno < mp->m_sb.sb_agcount) { |
393 | struct xfs_inobt_rec_incore *irbp = irbuf; | 393 | struct xfs_inobt_rec_incore *irbp = irbuf; |
394 | struct xfs_inobt_rec_incore *irbufend = irbuf + nirbuf; | 394 | struct xfs_inobt_rec_incore *irbufend = irbuf + nirbuf; |
@@ -491,13 +491,16 @@ del_cursor: | |||
491 | formatter, statstruct_size, &ac, | 491 | formatter, statstruct_size, &ac, |
492 | &lastino); | 492 | &lastino); |
493 | if (error) | 493 | if (error) |
494 | rval = error; | 494 | break; |
495 | 495 | ||
496 | cond_resched(); | 496 | cond_resched(); |
497 | } | 497 | } |
498 | 498 | ||
499 | /* If we've run out of space, we are done */ | 499 | /* |
500 | if (ac.ac_ubleft < statstruct_size) | 500 | * If we've run out of space or had a formatting error, we |
501 | * are now done | ||
502 | */ | ||
503 | if (ac.ac_ubleft < statstruct_size || error) | ||
501 | break; | 504 | break; |
502 | 505 | ||
503 | if (end_of_ag) { | 506 | if (end_of_ag) { |
@@ -511,11 +514,17 @@ del_cursor: | |||
511 | */ | 514 | */ |
512 | kmem_free(irbuf); | 515 | kmem_free(irbuf); |
513 | *ubcountp = ac.ac_ubelem; | 516 | *ubcountp = ac.ac_ubelem; |
517 | |||
514 | /* | 518 | /* |
515 | * Found some inodes, return them now and return the error next time. | 519 | * We found some inodes, so clear the error status and return them. |
520 | * The lastino pointer will point directly at the inode that triggered | ||
521 | * any error that occurred, so on the next call the error will be | ||
522 | * triggered again and propagated to userspace as there will be no | ||
523 | * formatted inodes in the buffer. | ||
516 | */ | 524 | */ |
517 | if (ac.ac_ubelem) | 525 | if (ac.ac_ubelem) |
518 | rval = 0; | 526 | error = 0; |
527 | |||
519 | if (agno >= mp->m_sb.sb_agcount) { | 528 | if (agno >= mp->m_sb.sb_agcount) { |
520 | /* | 529 | /* |
521 | * If we ran out of filesystem, mark lastino as off | 530 | * If we ran out of filesystem, mark lastino as off |
@@ -527,7 +536,7 @@ del_cursor: | |||
527 | } else | 536 | } else |
528 | *lastinop = (xfs_ino_t)lastino; | 537 | *lastinop = (xfs_ino_t)lastino; |
529 | 538 | ||
530 | return rval; | 539 | return error; |
531 | } | 540 | } |
532 | 541 | ||
533 | int | 542 | int |