aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorJie Liu <jeff.liu@oracle.com>2014-08-03 21:22:31 -0400
committerDave Chinner <david@fromorbit.com>2014-08-03 21:22:31 -0400
commit1e773c4989d2dfe08332b4c18f7e1d7ad633015c (patch)
tree1bbc729141d2aa5be746e34a701668bc272285e7 /fs/xfs
parentf3d1e587437b784635459dcfccaedd17149282cc (diff)
xfs: introduce xfs_bulkstat_ag_ichunk
Introduce xfs_bulkstat_ag_ichunk() to process inodes in chunk with a pointer to a formatter function that will iget the inode and fill in the appropriate structure. Refactor xfs_bulkstat() with it. Signed-off-by: Jie Liu <jeff.liu@oracle.com> Reviewed-by: Dave Chinner <dchinner@redhat.com> Signed-off-by: Dave Chinner <david@fromorbit.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/xfs_itable.c141
-rw-r--r--fs/xfs/xfs_itable.h16
2 files changed, 103 insertions, 54 deletions
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index 32cf52ee33bc..f71be9c68017 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -263,6 +263,79 @@ xfs_bulkstat_grab_ichunk(
263#define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size) 263#define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size)
264 264
265/* 265/*
266 * Process inodes in chunk with a pointer to a formatter function
267 * that will iget the inode and fill in the appropriate structure.
268 */
269int
270xfs_bulkstat_ag_ichunk(
271 struct xfs_mount *mp,
272 xfs_agnumber_t agno,
273 struct xfs_inobt_rec_incore *irbp,
274 bulkstat_one_pf formatter,
275 size_t statstruct_size,
276 struct xfs_bulkstat_agichunk *acp)
277{
278 xfs_ino_t lastino = acp->ac_lastino;
279 char __user **ubufp = acp->ac_ubuffer;
280 int ubleft = acp->ac_ubleft;
281 int ubelem = acp->ac_ubelem;
282 int chunkidx, clustidx;
283 int error = 0;
284 xfs_agino_t agino;
285
286 for (agino = irbp->ir_startino, chunkidx = clustidx = 0;
287 XFS_BULKSTAT_UBLEFT(ubleft) &&
288 irbp->ir_freecount < XFS_INODES_PER_CHUNK;
289 chunkidx++, clustidx++, agino++) {
290 int fmterror; /* bulkstat formatter result */
291 int ubused;
292 xfs_ino_t ino = XFS_AGINO_TO_INO(mp, agno, agino);
293
294 ASSERT(chunkidx < XFS_INODES_PER_CHUNK);
295
296 /* Skip if this inode is free */
297 if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) {
298 lastino = ino;
299 continue;
300 }
301
302 /*
303 * Count used inodes as free so we can tell when the
304 * chunk is used up.
305 */
306 irbp->ir_freecount++;
307
308 /* Get the inode and fill in a single buffer */
309 ubused = statstruct_size;
310 error = formatter(mp, ino, *ubufp, ubleft, &ubused, &fmterror);
311 if (fmterror == BULKSTAT_RV_NOTHING) {
312 if (error && error != -ENOENT && error != -EINVAL) {
313 ubleft = 0;
314 break;
315 }
316 lastino = ino;
317 continue;
318 }
319 if (fmterror == BULKSTAT_RV_GIVEUP) {
320 ubleft = 0;
321 ASSERT(error);
322 break;
323 }
324 if (*ubufp)
325 *ubufp += ubused;
326 ubleft -= ubused;
327 ubelem++;
328 lastino = ino;
329 }
330
331 acp->ac_lastino = lastino;
332 acp->ac_ubleft = ubleft;
333 acp->ac_ubelem = ubelem;
334
335 return error;
336}
337
338/*
266 * Return stat information in bulk (by-inode) for the filesystem. 339 * Return stat information in bulk (by-inode) for the filesystem.
267 */ 340 */
268int /* error status */ 341int /* error status */
@@ -279,8 +352,6 @@ xfs_bulkstat(
279 xfs_agi_t *agi; /* agi header data */ 352 xfs_agi_t *agi; /* agi header data */
280 xfs_agino_t agino; /* inode # in allocation group */ 353 xfs_agino_t agino; /* inode # in allocation group */
281 xfs_agnumber_t agno; /* allocation group number */ 354 xfs_agnumber_t agno; /* allocation group number */
282 int chunkidx; /* current index into inode chunk */
283 int clustidx; /* current index into inode cluster */
284 xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */ 355 xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */
285 int end_of_ag; /* set if we've seen the ag end */ 356 int end_of_ag; /* set if we've seen the ag end */
286 int error; /* error code */ 357 int error; /* error code */
@@ -300,7 +371,6 @@ xfs_bulkstat(
300 int ubleft; /* bytes left in user's buffer */ 371 int ubleft; /* bytes left in user's buffer */
301 char __user *ubufp; /* pointer into user's buffer */ 372 char __user *ubufp; /* pointer into user's buffer */
302 int ubelem; /* spaces used in user's buffer */ 373 int ubelem; /* spaces used in user's buffer */
303 int ubused; /* bytes used by formatter */
304 374
305 /* 375 /*
306 * Get the last inode value, see if there's nothing to do. 376 * Get the last inode value, see if there's nothing to do.
@@ -419,57 +489,20 @@ xfs_bulkstat(
419 irbufend = irbp; 489 irbufend = irbp;
420 for (irbp = irbuf; 490 for (irbp = irbuf;
421 irbp < irbufend && XFS_BULKSTAT_UBLEFT(ubleft); irbp++) { 491 irbp < irbufend && XFS_BULKSTAT_UBLEFT(ubleft); irbp++) {
422 /* 492 struct xfs_bulkstat_agichunk ac;
423 * Now process this chunk of inodes. 493
424 */ 494 ac.ac_lastino = lastino;
425 for (agino = irbp->ir_startino, chunkidx = clustidx = 0; 495 ac.ac_ubuffer = &ubuffer;
426 XFS_BULKSTAT_UBLEFT(ubleft) && 496 ac.ac_ubleft = ubleft;
427 irbp->ir_freecount < XFS_INODES_PER_CHUNK; 497 ac.ac_ubelem = ubelem;
428 chunkidx++, clustidx++, agino++) { 498 error = xfs_bulkstat_ag_ichunk(mp, agno, irbp,
429 ASSERT(chunkidx < XFS_INODES_PER_CHUNK); 499 formatter, statstruct_size, &ac);
430 500 if (error)
431 ino = XFS_AGINO_TO_INO(mp, agno, agino); 501 rval = error;
432 /* 502
433 * Skip if this inode is free. 503 lastino = ac.ac_lastino;
434 */ 504 ubleft = ac.ac_ubleft;
435 if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) { 505 ubelem = ac.ac_ubelem;
436 lastino = ino;
437 continue;
438 }
439 /*
440 * Count used inodes as free so we can tell
441 * when the chunk is used up.
442 */
443 irbp->ir_freecount++;
444
445 /*
446 * Get the inode and fill in a single buffer.
447 */
448 ubused = statstruct_size;
449 error = formatter(mp, ino, ubufp, ubleft,
450 &ubused, &fmterror);
451 if (fmterror == BULKSTAT_RV_NOTHING) {
452 if (error && error != -ENOENT &&
453 error != -EINVAL) {
454 ubleft = 0;
455 rval = error;
456 break;
457 }
458 lastino = ino;
459 continue;
460 }
461 if (fmterror == BULKSTAT_RV_GIVEUP) {
462 ubleft = 0;
463 ASSERT(error);
464 rval = error;
465 break;
466 }
467 if (ubufp)
468 ubufp += ubused;
469 ubleft -= ubused;
470 ubelem++;
471 lastino = ino;
472 }
473 506
474 cond_resched(); 507 cond_resched();
475 } 508 }
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 6ea8b3912fa4..aaed08022eb9 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -30,6 +30,22 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
30 int *ubused, 30 int *ubused,
31 int *stat); 31 int *stat);
32 32
33struct 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
40int
41xfs_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
33/* 49/*
34 * Values for stat return value. 50 * Values for stat return value.
35 */ 51 */