aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorDave Chinner <dchinner@redhat.com>2014-11-06 16:31:13 -0500
committerDave Chinner <david@fromorbit.com>2014-11-06 16:31:13 -0500
commit6e57c542cb7e0e580eb53ae76a77875c7d92b4b1 (patch)
treef96da98b6e470891eee9084eff924b85b43d6e7e /fs/xfs
parent2b831ac6bc87d3cbcbb1a8816827b6923403e461 (diff)
xfs: bulkstat main loop logic is a mess
There are a bunch of variables tha tare more wildy scoped than they need to be, obfuscated user buffer checks and tortured "next inode" tracking. This all needs cleaning up to expose the real issues that need fixing. cc: <stable@vger.kernel.org> # 3.17 Signed-off-by: Dave Chinner <dchinner@redhat.com> Reviewed-by: Brian Foster <bfoster@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_itable.c56
1 files changed, 24 insertions, 32 deletions
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 7ea2b113db1b..acae3355ab22 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -348,30 +348,23 @@ xfs_bulkstat(
348 xfs_agino_t agino; /* inode # in allocation group */ 348 xfs_agino_t agino; /* inode # in allocation group */
349 xfs_agnumber_t agno; /* allocation group number */ 349 xfs_agnumber_t agno; /* allocation group number */
350 xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */ 350 xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */
351 int end_of_ag; /* set if we've seen the ag end */
352 int error; /* error code */
353 int icount; /* count of inodes good in irbuf */
354 size_t irbsize; /* size of irec buffer in bytes */ 351 size_t irbsize; /* size of irec buffer in bytes */
355 xfs_ino_t ino; /* inode number (filesystem) */
356 xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */
357 xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ 352 xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */
358 xfs_inobt_rec_incore_t *irbufend; /* end of good irec buffer entries */
359 xfs_ino_t lastino; /* last inode number returned */ 353 xfs_ino_t lastino; /* last inode number returned */
360 int nirbuf; /* size of irbuf */ 354 int nirbuf; /* size of irbuf */
361 int rval; /* return value error code */ 355 int rval; /* return value error code */
362 int ubcount; /* size of user's buffer */ 356 int ubcount; /* size of user's buffer */
363 int stat;
364 struct xfs_bulkstat_agichunk ac; 357 struct xfs_bulkstat_agichunk ac;
358 int error = 0;
365 359
366 /* 360 /*
367 * Get the last inode value, see if there's nothing to do. 361 * Get the last inode value, see if there's nothing to do.
368 */ 362 */
369 ino = (xfs_ino_t)*lastinop; 363 lastino = *lastinop;
370 lastino = ino; 364 agno = XFS_INO_TO_AGNO(mp, lastino);
371 agno = XFS_INO_TO_AGNO(mp, ino); 365 agino = XFS_INO_TO_AGINO(mp, lastino);
372 agino = XFS_INO_TO_AGINO(mp, ino);
373 if (agno >= mp->m_sb.sb_agcount || 366 if (agno >= mp->m_sb.sb_agcount ||
374 ino != XFS_AGINO_TO_INO(mp, agno, agino)) { 367 lastino != XFS_AGINO_TO_INO(mp, agno, agino)) {
375 *done = 1; 368 *done = 1;
376 *ubcountp = 0; 369 *ubcountp = 0;
377 return 0; 370 return 0;
@@ -396,8 +389,13 @@ xfs_bulkstat(
396 * inode returned; 0 means start of the allocation group. 389 * inode returned; 0 means start of the allocation group.
397 */ 390 */
398 rval = 0; 391 rval = 0;
399 while (XFS_BULKSTAT_UBLEFT(ac.ac_ubleft) && agno < mp->m_sb.sb_agcount) { 392 while (agno < mp->m_sb.sb_agcount) {
400 cond_resched(); 393 struct xfs_inobt_rec_incore *irbp = irbuf;
394 struct xfs_inobt_rec_incore *irbufend = irbuf + nirbuf;
395 bool end_of_ag = false;
396 int icount = 0;
397 int stat;
398
401 error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); 399 error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp);
402 if (error) 400 if (error)
403 break; 401 break;
@@ -407,10 +405,6 @@ xfs_bulkstat(
407 */ 405 */
408 cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno, 406 cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno,
409 XFS_BTNUM_INO); 407 XFS_BTNUM_INO);
410 irbp = irbuf;
411 irbufend = irbuf + nirbuf;
412 end_of_ag = 0;
413 icount = 0;
414 if (agino > 0) { 408 if (agino > 0) {
415 /* 409 /*
416 * In the middle of an allocation group, we need to get 410 * In the middle of an allocation group, we need to get
@@ -435,7 +429,7 @@ xfs_bulkstat(
435 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &stat); 429 error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &stat);
436 } 430 }
437 if (error || stat == 0) { 431 if (error || stat == 0) {
438 end_of_ag = 1; 432 end_of_ag = true;
439 goto del_cursor; 433 goto del_cursor;
440 } 434 }
441 435
@@ -448,7 +442,7 @@ xfs_bulkstat(
448 442
449 error = xfs_inobt_get_rec(cur, &r, &stat); 443 error = xfs_inobt_get_rec(cur, &r, &stat);
450 if (error || stat == 0) { 444 if (error || stat == 0) {
451 end_of_ag = 1; 445 end_of_ag = true;
452 goto del_cursor; 446 goto del_cursor;
453 } 447 }
454 448
@@ -470,7 +464,7 @@ xfs_bulkstat(
470 agino = r.ir_startino + XFS_INODES_PER_CHUNK; 464 agino = r.ir_startino + XFS_INODES_PER_CHUNK;
471 error = xfs_btree_increment(cur, 0, &stat); 465 error = xfs_btree_increment(cur, 0, &stat);
472 if (error || stat == 0) { 466 if (error || stat == 0) {
473 end_of_ag = 1; 467 end_of_ag = true;
474 goto del_cursor; 468 goto del_cursor;
475 } 469 }
476 cond_resched(); 470 cond_resched();
@@ -491,7 +485,7 @@ del_cursor:
491 */ 485 */
492 irbufend = irbp; 486 irbufend = irbp;
493 for (irbp = irbuf; 487 for (irbp = irbuf;
494 irbp < irbufend && XFS_BULKSTAT_UBLEFT(ac.ac_ubleft); 488 irbp < irbufend && ac.ac_ubleft >= statstruct_size;
495 irbp++) { 489 irbp++) {
496 error = xfs_bulkstat_ag_ichunk(mp, agno, irbp, 490 error = xfs_bulkstat_ag_ichunk(mp, agno, irbp,
497 formatter, statstruct_size, &ac, 491 formatter, statstruct_size, &ac,
@@ -502,17 +496,15 @@ del_cursor:
502 cond_resched(); 496 cond_resched();
503 } 497 }
504 498
505 /* 499 /* If we've run out of space, we are done */
506 * Set up for the next loop iteration. 500 if (ac.ac_ubleft < statstruct_size)
507 */
508 if (XFS_BULKSTAT_UBLEFT(ac.ac_ubleft)) {
509 if (end_of_ag) {
510 agno++;
511 agino = 0;
512 } else
513 agino = XFS_INO_TO_AGINO(mp, lastino);
514 } else
515 break; 501 break;
502
503 if (end_of_ag) {
504 agno++;
505 agino = 0;
506 } else
507 agino = XFS_INO_TO_AGINO(mp, lastino);
516 } 508 }
517 /* 509 /*
518 * Done, we're either out of filesystem or space to put the data. 510 * Done, we're either out of filesystem or space to put the data.