diff options
-rw-r--r-- | fs/xfs/xfs_itable.c | 59 | ||||
-rw-r--r-- | fs/xfs/xfs_itable.h | 16 |
2 files changed, 28 insertions, 47 deletions
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index 16737cbbee17..50a3e5995dd9 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -262,20 +262,26 @@ xfs_bulkstat_grab_ichunk( | |||
262 | 262 | ||
263 | #define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size) | 263 | #define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size) |
264 | 264 | ||
265 | struct xfs_bulkstat_agichunk { | ||
266 | char __user **ac_ubuffer;/* pointer into user's buffer */ | ||
267 | int ac_ubleft; /* bytes left in user's buffer */ | ||
268 | int ac_ubelem; /* spaces used in user's buffer */ | ||
269 | }; | ||
270 | |||
265 | /* | 271 | /* |
266 | * Process inodes in chunk with a pointer to a formatter function | 272 | * Process inodes in chunk with a pointer to a formatter function |
267 | * that will iget the inode and fill in the appropriate structure. | 273 | * that will iget the inode and fill in the appropriate structure. |
268 | */ | 274 | */ |
269 | int | 275 | static int |
270 | xfs_bulkstat_ag_ichunk( | 276 | xfs_bulkstat_ag_ichunk( |
271 | struct xfs_mount *mp, | 277 | struct xfs_mount *mp, |
272 | xfs_agnumber_t agno, | 278 | xfs_agnumber_t agno, |
273 | struct xfs_inobt_rec_incore *irbp, | 279 | struct xfs_inobt_rec_incore *irbp, |
274 | bulkstat_one_pf formatter, | 280 | bulkstat_one_pf formatter, |
275 | size_t statstruct_size, | 281 | size_t statstruct_size, |
276 | struct xfs_bulkstat_agichunk *acp) | 282 | struct xfs_bulkstat_agichunk *acp, |
283 | xfs_ino_t *lastino) | ||
277 | { | 284 | { |
278 | xfs_ino_t lastino = acp->ac_lastino; | ||
279 | char __user **ubufp = acp->ac_ubuffer; | 285 | char __user **ubufp = acp->ac_ubuffer; |
280 | int ubleft = acp->ac_ubleft; | 286 | int ubleft = acp->ac_ubleft; |
281 | int ubelem = acp->ac_ubelem; | 287 | int ubelem = acp->ac_ubelem; |
@@ -295,7 +301,7 @@ xfs_bulkstat_ag_ichunk( | |||
295 | 301 | ||
296 | /* Skip if this inode is free */ | 302 | /* Skip if this inode is free */ |
297 | if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) { | 303 | if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) { |
298 | lastino = ino; | 304 | *lastino = ino; |
299 | continue; | 305 | continue; |
300 | } | 306 | } |
301 | 307 | ||
@@ -313,7 +319,7 @@ xfs_bulkstat_ag_ichunk( | |||
313 | ubleft = 0; | 319 | ubleft = 0; |
314 | break; | 320 | break; |
315 | } | 321 | } |
316 | lastino = ino; | 322 | *lastino = ino; |
317 | continue; | 323 | continue; |
318 | } | 324 | } |
319 | if (fmterror == BULKSTAT_RV_GIVEUP) { | 325 | if (fmterror == BULKSTAT_RV_GIVEUP) { |
@@ -325,10 +331,9 @@ xfs_bulkstat_ag_ichunk( | |||
325 | *ubufp += ubused; | 331 | *ubufp += ubused; |
326 | ubleft -= ubused; | 332 | ubleft -= ubused; |
327 | ubelem++; | 333 | ubelem++; |
328 | lastino = ino; | 334 | *lastino = ino; |
329 | } | 335 | } |
330 | 336 | ||
331 | acp->ac_lastino = lastino; | ||
332 | acp->ac_ubleft = ubleft; | 337 | acp->ac_ubleft = ubleft; |
333 | acp->ac_ubelem = ubelem; | 338 | acp->ac_ubelem = ubelem; |
334 | 339 | ||
@@ -355,7 +360,6 @@ xfs_bulkstat( | |||
355 | xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */ | 360 | xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */ |
356 | int end_of_ag; /* set if we've seen the ag end */ | 361 | int end_of_ag; /* set if we've seen the ag end */ |
357 | int error; /* error code */ | 362 | int error; /* error code */ |
358 | int fmterror;/* bulkstat formatter result */ | ||
359 | int icount; /* count of inodes good in irbuf */ | 363 | int icount; /* count of inodes good in irbuf */ |
360 | size_t irbsize; /* size of irec buffer in bytes */ | 364 | size_t irbsize; /* size of irec buffer in bytes */ |
361 | xfs_ino_t ino; /* inode number (filesystem) */ | 365 | xfs_ino_t ino; /* inode number (filesystem) */ |
@@ -366,10 +370,8 @@ xfs_bulkstat( | |||
366 | int nirbuf; /* size of irbuf */ | 370 | int nirbuf; /* size of irbuf */ |
367 | int rval; /* return value error code */ | 371 | int rval; /* return value error code */ |
368 | int ubcount; /* size of user's buffer */ | 372 | int ubcount; /* size of user's buffer */ |
369 | int ubleft; /* bytes left in user's buffer */ | ||
370 | char __user *ubufp; /* pointer into user's buffer */ | ||
371 | int ubelem; /* spaces used in user's buffer */ | ||
372 | int stat; | 373 | int stat; |
374 | struct xfs_bulkstat_agichunk ac; | ||
373 | 375 | ||
374 | /* | 376 | /* |
375 | * Get the last inode value, see if there's nothing to do. | 377 | * Get the last inode value, see if there's nothing to do. |
@@ -386,11 +388,13 @@ xfs_bulkstat( | |||
386 | } | 388 | } |
387 | 389 | ||
388 | ubcount = *ubcountp; /* statstruct's */ | 390 | ubcount = *ubcountp; /* statstruct's */ |
389 | ubleft = ubcount * statstruct_size; /* bytes */ | 391 | ac.ac_ubuffer = &ubuffer; |
390 | *ubcountp = ubelem = 0; | 392 | ac.ac_ubleft = ubcount * statstruct_size; /* bytes */; |
393 | ac.ac_ubelem = 0; | ||
394 | |||
395 | *ubcountp = 0; | ||
391 | *done = 0; | 396 | *done = 0; |
392 | fmterror = 0; | 397 | |
393 | ubufp = ubuffer; | ||
394 | irbuf = kmem_zalloc_greedy(&irbsize, PAGE_SIZE, PAGE_SIZE * 4); | 398 | irbuf = kmem_zalloc_greedy(&irbsize, PAGE_SIZE, PAGE_SIZE * 4); |
395 | if (!irbuf) | 399 | if (!irbuf) |
396 | return -ENOMEM; | 400 | return -ENOMEM; |
@@ -402,7 +406,7 @@ xfs_bulkstat( | |||
402 | * inode returned; 0 means start of the allocation group. | 406 | * inode returned; 0 means start of the allocation group. |
403 | */ | 407 | */ |
404 | rval = 0; | 408 | rval = 0; |
405 | while (XFS_BULKSTAT_UBLEFT(ubleft) && agno < mp->m_sb.sb_agcount) { | 409 | while (XFS_BULKSTAT_UBLEFT(ac.ac_ubleft) && agno < mp->m_sb.sb_agcount) { |
406 | cond_resched(); | 410 | cond_resched(); |
407 | error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); | 411 | error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); |
408 | if (error) | 412 | if (error) |
@@ -497,28 +501,21 @@ del_cursor: | |||
497 | */ | 501 | */ |
498 | irbufend = irbp; | 502 | irbufend = irbp; |
499 | for (irbp = irbuf; | 503 | for (irbp = irbuf; |
500 | irbp < irbufend && XFS_BULKSTAT_UBLEFT(ubleft); irbp++) { | 504 | irbp < irbufend && XFS_BULKSTAT_UBLEFT(ac.ac_ubleft); |
501 | struct xfs_bulkstat_agichunk ac; | 505 | irbp++) { |
502 | |||
503 | ac.ac_lastino = lastino; | ||
504 | ac.ac_ubuffer = &ubuffer; | ||
505 | ac.ac_ubleft = ubleft; | ||
506 | ac.ac_ubelem = ubelem; | ||
507 | error = xfs_bulkstat_ag_ichunk(mp, agno, irbp, | 506 | error = xfs_bulkstat_ag_ichunk(mp, agno, irbp, |
508 | formatter, statstruct_size, &ac); | 507 | formatter, statstruct_size, &ac, |
508 | &lastino); | ||
509 | if (error) | 509 | if (error) |
510 | rval = error; | 510 | rval = error; |
511 | 511 | ||
512 | lastino = ac.ac_lastino; | ||
513 | ubleft = ac.ac_ubleft; | ||
514 | ubelem = ac.ac_ubelem; | ||
515 | |||
516 | cond_resched(); | 512 | cond_resched(); |
517 | } | 513 | } |
514 | |||
518 | /* | 515 | /* |
519 | * Set up for the next loop iteration. | 516 | * Set up for the next loop iteration. |
520 | */ | 517 | */ |
521 | if (XFS_BULKSTAT_UBLEFT(ubleft)) { | 518 | if (XFS_BULKSTAT_UBLEFT(ac.ac_ubleft)) { |
522 | if (end_of_ag) { | 519 | if (end_of_ag) { |
523 | agno++; | 520 | agno++; |
524 | agino = 0; | 521 | agino = 0; |
@@ -531,11 +528,11 @@ del_cursor: | |||
531 | * Done, we're either out of filesystem or space to put the data. | 528 | * Done, we're either out of filesystem or space to put the data. |
532 | */ | 529 | */ |
533 | kmem_free(irbuf); | 530 | kmem_free(irbuf); |
534 | *ubcountp = ubelem; | 531 | *ubcountp = ac.ac_ubelem; |
535 | /* | 532 | /* |
536 | * Found some inodes, return them now and return the error next time. | 533 | * Found some inodes, return them now and return the error next time. |
537 | */ | 534 | */ |
538 | if (ubelem) | 535 | if (ac.ac_ubelem) |
539 | rval = 0; | 536 | rval = 0; |
540 | if (agno >= mp->m_sb.sb_agcount) { | 537 | if (agno >= mp->m_sb.sb_agcount) { |
541 | /* | 538 | /* |
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h index aaed08022eb9..6ea8b3912fa4 100644 --- a/fs/xfs/xfs_itable.h +++ b/fs/xfs/xfs_itable.h | |||
@@ -30,22 +30,6 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp, | |||
30 | int *ubused, | 30 | int *ubused, |
31 | int *stat); | 31 | int *stat); |
32 | 32 | ||
33 | struct xfs_bulkstat_agichunk { | ||
34 | xfs_ino_t ac_lastino; /* last inode returned */ | ||
35 | char __user **ac_ubuffer;/* pointer into user's buffer */ | ||
36 | int ac_ubleft; /* bytes left in user's buffer */ | ||
37 | int ac_ubelem; /* spaces used in user's buffer */ | ||
38 | }; | ||
39 | |||
40 | int | ||
41 | xfs_bulkstat_ag_ichunk( | ||
42 | struct xfs_mount *mp, | ||
43 | xfs_agnumber_t agno, | ||
44 | struct xfs_inobt_rec_incore *irbp, | ||
45 | bulkstat_one_pf formatter, | ||
46 | size_t statstruct_size, | ||
47 | struct xfs_bulkstat_agichunk *acp); | ||
48 | |||
49 | /* | 33 | /* |
50 | * Values for stat return value. | 34 | * Values for stat return value. |
51 | */ | 35 | */ |