aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_itable.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_itable.c')
-rw-r--r--fs/xfs/xfs_itable.c29
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
533int 542int