From: Dave Chinner <david@fromorbit.com>
To: xfs@oss.sgi.com
Subject: [PATCH 6/6] xfs: track bulkstat progress by agino
Date: Fri, 7 Nov 2014 00:14:59 +1100 [thread overview]
Message-ID: <1415279699-8739-7-git-send-email-david@fromorbit.com> (raw)
In-Reply-To: <1415279699-8739-1-git-send-email-david@fromorbit.com>
From: Dave Chinner <dchinner@redhat.com>
The bulkstat main loop progress is tracked by the "lastino"
variable, which is a full 64 bit inode. However, the loop actually
works on agno/agino pairs, and so there's a significant disconnect
between the rest of the loop and the main cursor. Convert this to
use the agino, and pass the agino into the chunk formatting function
and convert it too.
This gets rid of the inconsistency in the loop processing, and
finally makes it simple for us to skip inodes at any point in the
loop simply by incrementing the agino cursor.
Signed-off-by: Dave Chinner <dchinner@redhat.com>
---
fs/xfs/xfs_itable.c | 68 ++++++++++++++++++++++++++---------------------------
1 file changed, 34 insertions(+), 34 deletions(-)
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index ff3f431..05e83a6 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -282,30 +282,31 @@ xfs_bulkstat_ag_ichunk(
bulkstat_one_pf formatter,
size_t statstruct_size,
struct xfs_bulkstat_agichunk *acp,
- xfs_ino_t *lastino)
+ xfs_agino_t *last_agino)
{
char __user **ubufp = acp->ac_ubuffer;
int chunkidx;
int error = 0;
- xfs_agino_t agino;
+ xfs_agino_t agino = irbp->ir_startino;
- agino = irbp->ir_startino;
for (chunkidx = 0; chunkidx < XFS_INODES_PER_CHUNK;
chunkidx++, agino++) {
int fmterror;
int ubused;
- xfs_ino_t ino = XFS_AGINO_TO_INO(mp, agno, agino);
+
+ /* inode won't fit in buffer, we are done */
+ if (acp->ac_ubleft < statstruct_size)
+ break;
/* Skip if this inode is free */
- if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) {
- *lastino = ino;
+ if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free)
continue;
- }
/* Get the inode and fill in a single buffer */
ubused = statstruct_size;
- error = formatter(mp, ino, *ubufp, acp->ac_ubleft,
- &ubused, &fmterror);
+ error = formatter(mp, XFS_AGINO_TO_INO(mp, agno, agino),
+ *ubufp, acp->ac_ubleft, &ubused, &fmterror);
+
if (fmterror == BULKSTAT_RV_GIVEUP ||
(error && error != -ENOENT && error != -EINVAL)) {
acp->ac_ubleft = 0;
@@ -315,7 +316,6 @@ xfs_bulkstat_ag_ichunk(
/* be careful not to leak error if at end of chunk */
if (fmterror == BULKSTAT_RV_NOTHING || error) {
- *lastino = ino;
error = 0;
continue;
}
@@ -323,12 +323,18 @@ xfs_bulkstat_ag_ichunk(
*ubufp += ubused;
acp->ac_ubleft -= ubused;
acp->ac_ubelem++;
- *lastino = ino;
-
- if (acp->ac_ubleft < statstruct_size)
- break;
}
+ /*
+ * Post-update *last_agino. At this point, agino will always point one
+ * inode past the last inode we processed successfully. Hence we
+ * substract that inode when setting the *last_agino cursor so that we
+ * return the correct cookie to userspace. On the next bulkstat call,
+ * the inode under the lastino cookie will be skipped as we have already
+ * processed it here.
+ */
+ *last_agino = agino - 1;
+
return error;
}
@@ -352,7 +358,6 @@ xfs_bulkstat(
xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */
size_t irbsize; /* size of irec buffer in bytes */
xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */
- xfs_ino_t lastino; /* last inode number returned */
int nirbuf; /* size of irbuf */
int ubcount; /* size of user's buffer */
struct xfs_bulkstat_agichunk ac;
@@ -361,11 +366,10 @@ xfs_bulkstat(
/*
* Get the last inode value, see if there's nothing to do.
*/
- lastino = *lastinop;
- agno = XFS_INO_TO_AGNO(mp, lastino);
- agino = XFS_INO_TO_AGINO(mp, lastino);
+ agno = XFS_INO_TO_AGNO(mp, *lastinop);
+ agino = XFS_INO_TO_AGINO(mp, *lastinop);
if (agno >= mp->m_sb.sb_agcount ||
- lastino != XFS_AGINO_TO_INO(mp, agno, agino)) {
+ *lastinop != XFS_AGINO_TO_INO(mp, agno, agino)) {
*done = 1;
*ubcountp = 0;
return 0;
@@ -420,7 +424,6 @@ xfs_bulkstat(
irbp->ir_freecount = r.ir_freecount;
irbp->ir_free = r.ir_free;
irbp++;
- agino = r.ir_startino + XFS_INODES_PER_CHUNK;
}
/* Increment to the next record */
error = xfs_btree_increment(cur, 0, &stat);
@@ -461,7 +464,6 @@ xfs_bulkstat(
/*
* Set agino to after this chunk and bump the cursor.
*/
- agino = r.ir_startino + XFS_INODES_PER_CHUNK;
error = xfs_btree_increment(cur, 0, &stat);
if (error || stat == 0) {
end_of_ag = true;
@@ -481,7 +483,9 @@ del_cursor:
if (error)
break;
/*
- * Now format all the good inodes into the user's buffer.
+ * Now format all the good inodes into the user's buffer. The
+ * call to xfs_bulkstat_ag_ichunk() sets up the agino pointer
+ * for the next loop iteration.
*/
irbufend = irbp;
for (irbp = irbuf;
@@ -489,7 +493,7 @@ del_cursor:
irbp++) {
error = xfs_bulkstat_ag_ichunk(mp, agno, irbp,
formatter, statstruct_size, &ac,
- &lastino);
+ &agino);
if (error)
break;
@@ -506,8 +510,7 @@ del_cursor:
if (end_of_ag) {
agno++;
agino = 0;
- } else
- agino = XFS_INO_TO_AGINO(mp, lastino);
+ }
}
/*
* Done, we're either out of filesystem or space to put the data.
@@ -525,16 +528,13 @@ del_cursor:
if (ac.ac_ubelem)
error = 0;
- if (agno >= mp->m_sb.sb_agcount) {
- /*
- * If we ran out of filesystem, mark lastino as off
- * the end of the filesystem, so the next call
- * will return immediately.
- */
- *lastinop = (xfs_ino_t)XFS_AGINO_TO_INO(mp, agno, 0);
+ /*
+ * If we ran out of filesystem, lastino will point off the end of
+ * the filesystem so the next call will return immediately.
+ */
+ *lastinop = XFS_AGINO_TO_INO(mp, agno, agino);
+ if (agno >= mp->m_sb.sb_agcount)
*done = 1;
- } else
- *lastinop = (xfs_ino_t)lastino;
return error;
}
--
2.0.0
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
next prev parent reply other threads:[~2014-11-06 13:15 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-11-06 13:14 [PATCH 0/6 v3] xfs: fix the bulkstat mess Dave Chinner
2014-11-06 13:14 ` [PATCH 1/6] xfs: bulkstat btree walk doesn't terminate Dave Chinner
2014-11-06 13:14 ` [PATCH 2/6] xfs: bulkstat chunk formatting cursor is broken Dave Chinner
2014-11-06 13:14 ` [PATCH 3/6] xfs: bulkstat chunk-formatter has issues Dave Chinner
2014-11-06 16:31 ` Brian Foster
2014-11-06 13:14 ` [PATCH 4/6] xfs: bulkstat main loop logic is a mess Dave Chinner
2014-11-06 16:32 ` Brian Foster
2014-11-06 13:14 ` [PATCH 5/6] xfs: bulkstat error handling is broken Dave Chinner
2014-11-06 13:14 ` Dave Chinner [this message]
2014-11-06 16:32 ` [PATCH 6/6] xfs: track bulkstat progress by agino Brian Foster
-- strict thread matches above, loose matches on Subject: below --
2014-11-05 0:05 [PATCH 0/6 v2] xfs: fix the bulkstat mess Dave Chinner
2014-11-05 0:05 ` [PATCH 6/6] xfs: track bulkstat progress by agino Dave Chinner
2014-11-05 15:14 ` Brian Foster
2014-11-04 12:53 [PATCH 0/6] xfs: fix the bulkstat mess Dave Chinner
2014-11-04 12:53 ` [PATCH 6/6] xfs: track bulkstat progress by agino Dave Chinner
2014-11-04 19:00 ` Brian Foster
2014-11-04 21:39 ` Dave Chinner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1415279699-8739-7-git-send-email-david@fromorbit.com \
--to=david@fromorbit.com \
--cc=xfs@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox