Commit d01cc5eb authored by Dean Roehrich's avatar Dean Roehrich Committed by Nathan Scott

[XFS] Implement dm_get_bulkall

SGI Modid: 2.5.x-xfs:slinx:159760a
parent c61fb8c3
...@@ -943,7 +943,7 @@ xfs_ioc_bulkstat( ...@@ -943,7 +943,7 @@ xfs_ioc_bulkstat(
bulkreq.ubuffer, &done); bulkreq.ubuffer, &done);
} else { } else {
error = xfs_bulkstat(mp, NULL, &inlast, &count, error = xfs_bulkstat(mp, NULL, &inlast, &count,
(bulkstat_one_pf)xfs_bulkstat_one, (bulkstat_one_pf)xfs_bulkstat_one, NULL,
sizeof(xfs_bstat_t), bulkreq.ubuffer, sizeof(xfs_bstat_t), bulkreq.ubuffer,
BULKSTAT_FG_QUICK, &done); BULKSTAT_FG_QUICK, &done);
} }
......
...@@ -1756,7 +1756,10 @@ xfs_qm_dqusage_adjust( ...@@ -1756,7 +1756,10 @@ xfs_qm_dqusage_adjust(
xfs_trans_t *tp, /* transaction pointer - NULL */ xfs_trans_t *tp, /* transaction pointer - NULL */
xfs_ino_t ino, /* inode number to get data for */ xfs_ino_t ino, /* inode number to get data for */
void *buffer, /* not used */ void *buffer, /* not used */
int ubsize, /* not used */
void *private_data, /* not used */
xfs_daddr_t bno, /* starting block of inode cluster */ xfs_daddr_t bno, /* starting block of inode cluster */
int *ubused, /* not used */
void *dip, /* on-disk inode pointer (not used) */ void *dip, /* on-disk inode pointer (not used) */
int *res) /* result code value */ int *res) /* result code value */
{ {
...@@ -1920,7 +1923,7 @@ xfs_qm_quotacheck( ...@@ -1920,7 +1923,7 @@ xfs_qm_quotacheck(
* adjusting the corresponding dquot counters in core. * adjusting the corresponding dquot counters in core.
*/ */
if ((error = xfs_bulkstat(mp, NULL, &lastino, &count, if ((error = xfs_bulkstat(mp, NULL, &lastino, &count,
xfs_qm_dqusage_adjust, xfs_qm_dqusage_adjust, NULL,
structsz, NULL, structsz, NULL,
BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED, BULKSTAT_FG_IGET|BULKSTAT_FG_VFSLOCKED,
&done))) &done)))
......
...@@ -1301,7 +1301,10 @@ xfs_qm_internalqcheck_adjust( ...@@ -1301,7 +1301,10 @@ xfs_qm_internalqcheck_adjust(
xfs_trans_t *tp, /* transaction pointer */ xfs_trans_t *tp, /* transaction pointer */
xfs_ino_t ino, /* inode number to get data for */ xfs_ino_t ino, /* inode number to get data for */
void *buffer, /* not used */ void *buffer, /* not used */
int ubsize, /* not used */
void *private_data, /* not used */
xfs_daddr_t bno, /* starting block of inode cluster */ xfs_daddr_t bno, /* starting block of inode cluster */
int *ubused, /* not used */
void *dip, /* not used */ void *dip, /* not used */
int *res) /* bulkstat result code */ int *res) /* bulkstat result code */
{ {
...@@ -1403,7 +1406,7 @@ xfs_qm_internalqcheck( ...@@ -1403,7 +1406,7 @@ xfs_qm_internalqcheck(
* adjusting the corresponding dquot counters * adjusting the corresponding dquot counters
*/ */
if ((error = xfs_bulkstat(mp, NULL, &lastino, &count, if ((error = xfs_bulkstat(mp, NULL, &lastino, &count,
xfs_qm_internalqcheck_adjust, xfs_qm_internalqcheck_adjust, NULL,
0, NULL, BULKSTAT_FG_IGET, &done))) { 0, NULL, BULKSTAT_FG_IGET, &done))) {
break; break;
} }
......
...@@ -65,7 +65,10 @@ xfs_bulkstat_one( ...@@ -65,7 +65,10 @@ xfs_bulkstat_one(
xfs_trans_t *tp, /* transaction pointer */ xfs_trans_t *tp, /* transaction pointer */
xfs_ino_t ino, /* inode number to get data for */ xfs_ino_t ino, /* inode number to get data for */
void *buffer, /* buffer to place output in */ void *buffer, /* buffer to place output in */
int ubsize, /* size of buffer */
void *private_data, /* my private data */
xfs_daddr_t bno, /* starting bno of inode cluster */ xfs_daddr_t bno, /* starting bno of inode cluster */
int *ubused, /* bytes used by me */
void *dibuff, /* on-disk inode buffer */ void *dibuff, /* on-disk inode buffer */
int *stat) /* BULKSTAT_RV_... */ int *stat) /* BULKSTAT_RV_... */
{ {
...@@ -86,6 +89,10 @@ xfs_bulkstat_one( ...@@ -86,6 +89,10 @@ xfs_bulkstat_one(
*stat = BULKSTAT_RV_NOTHING; *stat = BULKSTAT_RV_NOTHING;
return XFS_ERROR(EINVAL); return XFS_ERROR(EINVAL);
} }
if (ubsize < sizeof(*buf)) {
*stat = BULKSTAT_RV_NOTHING;
return XFS_ERROR(ENOMEM);
}
if (dip == NULL) { if (dip == NULL) {
/* We're not being passed a pointer to a dinode. This happens /* We're not being passed a pointer to a dinode. This happens
...@@ -218,6 +225,8 @@ xfs_bulkstat_one( ...@@ -218,6 +225,8 @@ xfs_bulkstat_one(
} }
*stat = BULKSTAT_RV_DIDONE; *stat = BULKSTAT_RV_DIDONE;
if (ubused)
*ubused = sizeof(*buf);
return 0; return 0;
} }
...@@ -231,6 +240,7 @@ xfs_bulkstat( ...@@ -231,6 +240,7 @@ xfs_bulkstat(
xfs_ino_t *lastinop, /* last inode returned */ xfs_ino_t *lastinop, /* last inode returned */
int *ubcountp, /* size of buffer/count returned */ int *ubcountp, /* size of buffer/count returned */
bulkstat_one_pf formatter, /* func that'd fill a single buf */ bulkstat_one_pf formatter, /* func that'd fill a single buf */
void *private_data,/* private data for formatter */
size_t statstruct_size, /* sizeof struct filling */ size_t statstruct_size, /* sizeof struct filling */
xfs_caddr_t ubuffer, /* buffer with inode stats */ xfs_caddr_t ubuffer, /* buffer with inode stats */
int flags, /* defined in xfs_itable.h */ int flags, /* defined in xfs_itable.h */
...@@ -265,8 +275,10 @@ xfs_bulkstat( ...@@ -265,8 +275,10 @@ xfs_bulkstat(
int rval; /* return value error code */ int rval; /* return value error code */
int tmp; /* result value from btree calls */ int tmp; /* result value from btree calls */
int ubcount; /* size of user's buffer */ int ubcount; /* size of user's buffer */
int ubleft; /* spaces left in user's buffer */ int ubleft; /* bytes left in user's buffer */
xfs_caddr_t ubufp; /* current pointer into user's buffer */ xfs_caddr_t ubufp; /* current pointer into user's buffer */
int ubelem; /* spaces used in user's buffer */
int ubused; /* bytes used by formatter */
xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */ xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */
xfs_dinode_t *dip; /* ptr into bp for specific inode */ xfs_dinode_t *dip; /* ptr into bp for specific inode */
xfs_inode_t *ip; /* ptr to in-core inode struct */ xfs_inode_t *ip; /* ptr to in-core inode struct */
...@@ -284,8 +296,9 @@ xfs_bulkstat( ...@@ -284,8 +296,9 @@ xfs_bulkstat(
*ubcountp = 0; *ubcountp = 0;
return 0; return 0;
} }
ubcount = ubleft = *ubcountp; ubcount = *ubcountp; /* statstruct's */
*ubcountp = 0; ubleft = ubcount * statstruct_size; /* bytes */
*ubcountp = ubelem = 0;
*done = 0; *done = 0;
fmterror = 0; fmterror = 0;
ubufp = ubuffer; ubufp = ubuffer;
...@@ -317,7 +330,7 @@ xfs_bulkstat( ...@@ -317,7 +330,7 @@ xfs_bulkstat(
* inode returned; 0 means start of the allocation group. * inode returned; 0 means start of the allocation group.
*/ */
rval = 0; rval = 0;
while (ubleft > 0 && agno < mp->m_sb.sb_agcount) { while ((ubleft/statstruct_size) > 0 && agno < mp->m_sb.sb_agcount) {
bp = NULL; bp = NULL;
down_read(&mp->m_peraglock); down_read(&mp->m_peraglock);
error = xfs_ialloc_read_agi(mp, tp, agno, &agbp); error = xfs_ialloc_read_agi(mp, tp, agno, &agbp);
...@@ -402,7 +415,7 @@ xfs_bulkstat( ...@@ -402,7 +415,7 @@ xfs_bulkstat(
* Loop through inode btree records in this ag, * Loop through inode btree records in this ag,
* until we run out of inodes or space in the buffer. * until we run out of inodes or space in the buffer.
*/ */
while (irbp < irbufend && icount < ubcount) { while (irbp < irbufend && icount < (ubleft/statstruct_size)) {
/* /*
* Loop as long as we're unable to read the * Loop as long as we're unable to read the
* inode btree. * inode btree.
...@@ -453,7 +466,8 @@ xfs_bulkstat( ...@@ -453,7 +466,8 @@ xfs_bulkstat(
* Now format all the good inodes into the user's buffer. * Now format all the good inodes into the user's buffer.
*/ */
irbufend = irbp; irbufend = irbp;
for (irbp = irbuf; irbp < irbufend && ubleft > 0; irbp++) { for (irbp = irbuf;
irbp < irbufend && (ubleft/statstruct_size) > 0; irbp++) {
/* /*
* Read-ahead the next chunk's worth of inodes. * Read-ahead the next chunk's worth of inodes.
*/ */
...@@ -561,14 +575,19 @@ xfs_bulkstat( ...@@ -561,14 +575,19 @@ xfs_bulkstat(
* Get the inode and fill in a single buffer. * Get the inode and fill in a single buffer.
* BULKSTAT_FG_QUICK uses dip to fill it in. * BULKSTAT_FG_QUICK uses dip to fill it in.
* BULKSTAT_FG_IGET uses igets. * BULKSTAT_FG_IGET uses igets.
* See: xfs_bulkstat_one & dm_bulkstat_one. * See: xfs_bulkstat_one & xfs_dm_bulkstat_one.
* This is also used to count inodes/blks, etc * This is also used to count inodes/blks, etc
* in xfs_qm_quotacheck. * in xfs_qm_quotacheck.
*/ */
error = formatter(mp, tp, ino, ubufp, bno, dip, ubused = statstruct_size;
&fmterror); error = formatter(mp, tp, ino, ubufp,
if (fmterror == BULKSTAT_RV_NOTHING) ubleft, private_data,
bno, &ubused, dip, &fmterror);
if (fmterror == BULKSTAT_RV_NOTHING) {
if (error == ENOMEM)
ubleft = 0;
continue; continue;
}
if (fmterror == BULKSTAT_RV_GIVEUP) { if (fmterror == BULKSTAT_RV_GIVEUP) {
ubleft = 0; ubleft = 0;
ASSERT(error); ASSERT(error);
...@@ -576,8 +595,9 @@ xfs_bulkstat( ...@@ -576,8 +595,9 @@ xfs_bulkstat(
break; break;
} }
if (ubufp) if (ubufp)
ubufp += statstruct_size; ubufp += ubused;
ubleft--; ubleft -= ubused;
ubelem++;
lastino = ino; lastino = ino;
} }
} }
...@@ -605,7 +625,7 @@ xfs_bulkstat( ...@@ -605,7 +625,7 @@ xfs_bulkstat(
if (ubuffer) if (ubuffer)
unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS)); unuseracc(ubuffer, ubcount * statstruct_size, (B_READ|B_PHYS));
#endif #endif
*ubcountp = ubcount - ubleft; *ubcountp = ubelem;
if (agno >= mp->m_sb.sb_agcount) { if (agno >= mp->m_sb.sb_agcount) {
/* /*
* If we ran out of filesystem, mark lastino as off * If we ran out of filesystem, mark lastino as off
...@@ -647,7 +667,8 @@ xfs_bulkstat_single( ...@@ -647,7 +667,8 @@ xfs_bulkstat_single(
*/ */
ino = (xfs_ino_t)*lastinop; ino = (xfs_ino_t)*lastinop;
error = xfs_bulkstat_one(mp, NULL, ino, &bstat, 0, 0, &res); error = xfs_bulkstat_one(mp, NULL, ino, &bstat, sizeof(bstat),
NULL, 0, NULL, NULL, &res);
if (error) { if (error) {
/* /*
* Special case way failed, do it the "long" way * Special case way failed, do it the "long" way
...@@ -656,6 +677,7 @@ xfs_bulkstat_single( ...@@ -656,6 +677,7 @@ xfs_bulkstat_single(
(*lastinop)--; (*lastinop)--;
count = 1; count = 1;
if (xfs_bulkstat(mp, NULL, lastinop, &count, xfs_bulkstat_one, if (xfs_bulkstat(mp, NULL, lastinop, &count, xfs_bulkstat_one,
NULL,
sizeof(bstat), buffer, BULKSTAT_FG_IGET, done)) sizeof(bstat), buffer, BULKSTAT_FG_IGET, done))
return error; return error;
if (count == 0 || (xfs_ino_t)*lastinop != ino) if (count == 0 || (xfs_ino_t)*lastinop != ino)
......
...@@ -36,15 +36,19 @@ ...@@ -36,15 +36,19 @@
* xfs_bulkstat() is used to fill in xfs_bstat structures as well as dm_stat * xfs_bulkstat() is used to fill in xfs_bstat structures as well as dm_stat
* structures (by the dmi library). This is a pointer to a formatter function * structures (by the dmi library). This is a pointer to a formatter function
* that will iget the inode and fill in the appropriate structure. * that will iget the inode and fill in the appropriate structure.
* see xfs_bulkstat_one() and dm_bulkstat_one() in dmi_xfs.c * see xfs_bulkstat_one() and xfs_dm_bulkstat_one() in dmapi_xfs.c
*/ */
typedef int (*bulkstat_one_pf)(struct xfs_mount *mp, typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
struct xfs_trans *tp, struct xfs_trans *tp,
xfs_ino_t ino, xfs_ino_t ino,
void *buffer, void *buffer,
int ubsize,
void *private_data,
xfs_daddr_t bno, xfs_daddr_t bno,
int *ubused,
void *dip, void *dip,
int *stat); int *stat);
/* /*
* Values for stat return value. * Values for stat return value.
*/ */
...@@ -69,6 +73,7 @@ xfs_bulkstat( ...@@ -69,6 +73,7 @@ xfs_bulkstat(
xfs_ino_t *lastino, /* last inode returned */ xfs_ino_t *lastino, /* last inode returned */
int *count, /* size of buffer/count returned */ int *count, /* size of buffer/count returned */
bulkstat_one_pf formatter, /* func that'd fill a single buf */ bulkstat_one_pf formatter, /* func that'd fill a single buf */
void *private_data, /* private data for formatter */
size_t statstruct_size,/* sizeof struct that we're filling */ size_t statstruct_size,/* sizeof struct that we're filling */
xfs_caddr_t ubuffer, /* buffer with inode stats */ xfs_caddr_t ubuffer, /* buffer with inode stats */
int flags, /* flag to control access method */ int flags, /* flag to control access method */
...@@ -87,7 +92,10 @@ xfs_bulkstat_one( ...@@ -87,7 +92,10 @@ xfs_bulkstat_one(
xfs_trans_t *tp, xfs_trans_t *tp,
xfs_ino_t ino, xfs_ino_t ino,
void *buffer, void *buffer,
int ubsize,
void *private_data,
xfs_daddr_t bno, xfs_daddr_t bno,
int *ubused,
void *dibuff, void *dibuff,
int *stat); int *stat);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment