aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs
diff options
context:
space:
mode:
authorChristoph Hellwig <hch@lst.de>2010-06-23 04:11:11 -0400
committerDave Chinner <david@fromorbit.com>2010-06-23 04:11:11 -0400
commit7dce11dbac54fce777eea0f5fb25b2694ccd7900 (patch)
tree90d6d109ca110bcbf47a954a8283ec250be07003 /fs/xfs
parent1817176a86352f65210139d4c794ad2d19fc6b63 (diff)
xfs: always use iget in bulkstat
The non-coherent bulkstat versionsthat look directly at the inode buffers causes various problems with performance optimizations that make increased use of just logging inodes. This patch makes bulkstat always use iget, which should be fast enough for normal use with the radix-tree based inode cache introduced a while ago. Signed-off-by: Christoph Hellwig <hch@lst.de> Reviewed-by: Dave Chinner <dchinner@redhat.com>
Diffstat (limited to 'fs/xfs')
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl.c7
-rw-r--r--fs/xfs/linux-2.6/xfs_ioctl32.c12
-rw-r--r--fs/xfs/quota/xfs_qm.c11
-rw-r--r--fs/xfs/quota/xfs_qm_syscalls.c16
-rw-r--r--fs/xfs/xfs_itable.c281
-rw-r--r--fs/xfs/xfs_itable.h14
6 files changed, 59 insertions, 282 deletions
diff --git a/fs/xfs/linux-2.6/xfs_ioctl.c b/fs/xfs/linux-2.6/xfs_ioctl.c
index 699b60cbab9c..e59a81062830 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl.c
@@ -679,10 +679,9 @@ xfs_ioc_bulkstat(
679 error = xfs_bulkstat_single(mp, &inlast, 679 error = xfs_bulkstat_single(mp, &inlast,
680 bulkreq.ubuffer, &done); 680 bulkreq.ubuffer, &done);
681 else /* XFS_IOC_FSBULKSTAT */ 681 else /* XFS_IOC_FSBULKSTAT */
682 error = xfs_bulkstat(mp, &inlast, &count, 682 error = xfs_bulkstat(mp, &inlast, &count, xfs_bulkstat_one,
683 (bulkstat_one_pf)xfs_bulkstat_one, NULL, 683 sizeof(xfs_bstat_t), bulkreq.ubuffer,
684 sizeof(xfs_bstat_t), bulkreq.ubuffer, 684 &done);
685 BULKSTAT_FG_QUICK, &done);
686 685
687 if (error) 686 if (error)
688 return -error; 687 return -error;
diff --git a/fs/xfs/linux-2.6/xfs_ioctl32.c b/fs/xfs/linux-2.6/xfs_ioctl32.c
index 9287135e9bfc..e1d8380b049d 100644
--- a/fs/xfs/linux-2.6/xfs_ioctl32.c
+++ b/fs/xfs/linux-2.6/xfs_ioctl32.c
@@ -237,15 +237,13 @@ xfs_bulkstat_one_compat(
237 xfs_ino_t ino, /* inode number to get data for */ 237 xfs_ino_t ino, /* inode number to get data for */
238 void __user *buffer, /* buffer to place output in */ 238 void __user *buffer, /* buffer to place output in */
239 int ubsize, /* size of buffer */ 239 int ubsize, /* size of buffer */
240 void *private_data, /* my private data */
241 xfs_daddr_t bno, /* starting bno of inode cluster */ 240 xfs_daddr_t bno, /* starting bno of inode cluster */
242 int *ubused, /* bytes used by me */ 241 int *ubused, /* bytes used by me */
243 void *dibuff, /* on-disk inode buffer */
244 int *stat) /* BULKSTAT_RV_... */ 242 int *stat) /* BULKSTAT_RV_... */
245{ 243{
246 return xfs_bulkstat_one_int(mp, ino, buffer, ubsize, 244 return xfs_bulkstat_one_int(mp, ino, buffer, ubsize,
247 xfs_bulkstat_one_fmt_compat, bno, 245 xfs_bulkstat_one_fmt_compat, bno,
248 ubused, dibuff, stat); 246 ubused, stat);
249} 247}
250 248
251/* copied from xfs_ioctl.c */ 249/* copied from xfs_ioctl.c */
@@ -298,13 +296,11 @@ xfs_compat_ioc_bulkstat(
298 int res; 296 int res;
299 297
300 error = xfs_bulkstat_one_compat(mp, inlast, bulkreq.ubuffer, 298 error = xfs_bulkstat_one_compat(mp, inlast, bulkreq.ubuffer,
301 sizeof(compat_xfs_bstat_t), 299 sizeof(compat_xfs_bstat_t), 0, NULL, &res);
302 NULL, 0, NULL, NULL, &res);
303 } else if (cmd == XFS_IOC_FSBULKSTAT_32) { 300 } else if (cmd == XFS_IOC_FSBULKSTAT_32) {
304 error = xfs_bulkstat(mp, &inlast, &count, 301 error = xfs_bulkstat(mp, &inlast, &count,
305 xfs_bulkstat_one_compat, NULL, 302 xfs_bulkstat_one_compat, sizeof(compat_xfs_bstat_t),
306 sizeof(compat_xfs_bstat_t), bulkreq.ubuffer, 303 bulkreq.ubuffer, &done);
307 BULKSTAT_FG_QUICK, &done);
308 } else 304 } else
309 error = XFS_ERROR(EINVAL); 305 error = XFS_ERROR(EINVAL);
310 if (error) 306 if (error)
diff --git a/fs/xfs/quota/xfs_qm.c b/fs/xfs/quota/xfs_qm.c
index 2d8b7bc792c9..f19f94c4cb9f 100644
--- a/fs/xfs/quota/xfs_qm.c
+++ b/fs/xfs/quota/xfs_qm.c
@@ -1632,10 +1632,8 @@ xfs_qm_dqusage_adjust(
1632 xfs_ino_t ino, /* inode number to get data for */ 1632 xfs_ino_t ino, /* inode number to get data for */
1633 void __user *buffer, /* not used */ 1633 void __user *buffer, /* not used */
1634 int ubsize, /* not used */ 1634 int ubsize, /* not used */
1635 void *private_data, /* not used */
1636 xfs_daddr_t bno, /* starting block of inode cluster */ 1635 xfs_daddr_t bno, /* starting block of inode cluster */
1637 int *ubused, /* not used */ 1636 int *ubused, /* not used */
1638 void *dip, /* on-disk inode pointer (not used) */
1639 int *res) /* result code value */ 1637 int *res) /* result code value */
1640{ 1638{
1641 xfs_inode_t *ip; 1639 xfs_inode_t *ip;
@@ -1796,12 +1794,13 @@ xfs_qm_quotacheck(
1796 * Iterate thru all the inodes in the file system, 1794 * Iterate thru all the inodes in the file system,
1797 * adjusting the corresponding dquot counters in core. 1795 * adjusting the corresponding dquot counters in core.
1798 */ 1796 */
1799 if ((error = xfs_bulkstat(mp, &lastino, &count, 1797 error = xfs_bulkstat(mp, &lastino, &count,
1800 xfs_qm_dqusage_adjust, NULL, 1798 xfs_qm_dqusage_adjust,
1801 structsz, NULL, BULKSTAT_FG_IGET, &done))) 1799 structsz, NULL, &done);
1800 if (error)
1802 break; 1801 break;
1803 1802
1804 } while (! done); 1803 } while (!done);
1805 1804
1806 /* 1805 /*
1807 * We've made all the changes that we need to make incore. 1806 * We've made all the changes that we need to make incore.
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c
index 92b002f1805f..99a2d8e0f173 100644
--- a/fs/xfs/quota/xfs_qm_syscalls.c
+++ b/fs/xfs/quota/xfs_qm_syscalls.c
@@ -1109,10 +1109,8 @@ xfs_qm_internalqcheck_adjust(
1109 xfs_ino_t ino, /* inode number to get data for */ 1109 xfs_ino_t ino, /* inode number to get data for */
1110 void __user *buffer, /* not used */ 1110 void __user *buffer, /* not used */
1111 int ubsize, /* not used */ 1111 int ubsize, /* not used */
1112 void *private_data, /* not used */
1113 xfs_daddr_t bno, /* starting block of inode cluster */ 1112 xfs_daddr_t bno, /* starting block of inode cluster */
1114 int *ubused, /* not used */ 1113 int *ubused, /* not used */
1115 void *dip, /* not used */
1116 int *res) /* bulkstat result code */ 1114 int *res) /* bulkstat result code */
1117{ 1115{
1118 xfs_inode_t *ip; 1116 xfs_inode_t *ip;
@@ -1205,15 +1203,15 @@ xfs_qm_internalqcheck(
1205 * Iterate thru all the inodes in the file system, 1203 * Iterate thru all the inodes in the file system,
1206 * adjusting the corresponding dquot counters 1204 * adjusting the corresponding dquot counters
1207 */ 1205 */
1208 if ((error = xfs_bulkstat(mp, &lastino, &count, 1206 error = xfs_bulkstat(mp, &lastino, &count,
1209 xfs_qm_internalqcheck_adjust, NULL, 1207 xfs_qm_internalqcheck_adjust,
1210 0, NULL, BULKSTAT_FG_IGET, &done))) { 1208 0, NULL, &done);
1209 if (error) {
1210 cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error);
1211 break; 1211 break;
1212 } 1212 }
1213 } while (! done); 1213 } while (!done);
1214 if (error) { 1214
1215 cmn_err(CE_DEBUG, "Bulkstat returned error 0x%x", error);
1216 }
1217 cmn_err(CE_DEBUG, "Checking results against system dquots"); 1215 cmn_err(CE_DEBUG, "Checking results against system dquots");
1218 for (i = 0; i < qmtest_hashmask; i++) { 1216 for (i = 0; i < qmtest_hashmask; i++) {
1219 xfs_dqtest_t *d, *n; 1217 xfs_dqtest_t *d, *n;
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c
index b1b801e4a28e..83d7827793e4 100644
--- a/fs/xfs/xfs_itable.c
+++ b/fs/xfs/xfs_itable.c
@@ -49,24 +49,41 @@ xfs_internal_inum(
49 (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))); 49 (ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino)));
50} 50}
51 51
52STATIC int 52/*
53xfs_bulkstat_one_iget( 53 * Return stat information for one inode.
54 xfs_mount_t *mp, /* mount point for filesystem */ 54 * Return 0 if ok, else errno.
55 xfs_ino_t ino, /* inode number to get data for */ 55 */
56 xfs_daddr_t bno, /* starting bno of inode cluster */ 56int
57 xfs_bstat_t *buf, /* return buffer */ 57xfs_bulkstat_one_int(
58 int *stat) /* BULKSTAT_RV_... */ 58 struct xfs_mount *mp, /* mount point for filesystem */
59 xfs_ino_t ino, /* inode to get data for */
60 void __user *buffer, /* buffer to place output in */
61 int ubsize, /* size of buffer */
62 bulkstat_one_fmt_pf formatter, /* formatter, copy to user */
63 xfs_daddr_t bno, /* starting bno of cluster */
64 int *ubused, /* bytes used by me */
65 int *stat) /* BULKSTAT_RV_... */
59{ 66{
60 xfs_icdinode_t *dic; /* dinode core info pointer */ 67 struct xfs_icdinode *dic; /* dinode core info pointer */
61 xfs_inode_t *ip; /* incore inode pointer */ 68 struct xfs_inode *ip; /* incore inode pointer */
62 struct inode *inode; 69 struct inode *inode;
63 int error; 70 struct xfs_bstat *buf; /* return buffer */
71 int error = 0; /* error value */
72
73 *stat = BULKSTAT_RV_NOTHING;
74
75 if (!buffer || xfs_internal_inum(mp, ino))
76 return XFS_ERROR(EINVAL);
77
78 buf = kmem_alloc(sizeof(*buf), KM_SLEEP | KM_MAYFAIL);
79 if (!buf)
80 return XFS_ERROR(ENOMEM);
64 81
65 error = xfs_iget(mp, NULL, ino, 82 error = xfs_iget(mp, NULL, ino,
66 XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno); 83 XFS_IGET_BULKSTAT, XFS_ILOCK_SHARED, &ip, bno);
67 if (error) { 84 if (error) {
68 *stat = BULKSTAT_RV_NOTHING; 85 *stat = BULKSTAT_RV_NOTHING;
69 return error; 86 goto out_free;
70 } 87 }
71 88
72 ASSERT(ip != NULL); 89 ASSERT(ip != NULL);
@@ -127,77 +144,16 @@ xfs_bulkstat_one_iget(
127 buf->bs_blocks = dic->di_nblocks + ip->i_delayed_blks; 144 buf->bs_blocks = dic->di_nblocks + ip->i_delayed_blks;
128 break; 145 break;
129 } 146 }
130
131 xfs_iput(ip, XFS_ILOCK_SHARED); 147 xfs_iput(ip, XFS_ILOCK_SHARED);
132 return error;
133}
134 148
135STATIC void 149 error = formatter(buffer, ubsize, ubused, buf);
136xfs_bulkstat_one_dinode(
137 xfs_mount_t *mp, /* mount point for filesystem */
138 xfs_ino_t ino, /* inode number to get data for */
139 xfs_dinode_t *dic, /* dinode inode pointer */
140 xfs_bstat_t *buf) /* return buffer */
141{
142 /*
143 * The inode format changed when we moved the link count and
144 * made it 32 bits long. If this is an old format inode,
145 * convert it in memory to look like a new one. If it gets
146 * flushed to disk we will convert back before flushing or
147 * logging it. We zero out the new projid field and the old link
148 * count field. We'll handle clearing the pad field (the remains
149 * of the old uuid field) when we actually convert the inode to
150 * the new format. We don't change the version number so that we
151 * can distinguish this from a real new format inode.
152 */
153 if (dic->di_version == 1) {
154 buf->bs_nlink = be16_to_cpu(dic->di_onlink);
155 buf->bs_projid = 0;
156 } else {
157 buf->bs_nlink = be32_to_cpu(dic->di_nlink);
158 buf->bs_projid = be16_to_cpu(dic->di_projid);
159 }
160 150
161 buf->bs_ino = ino; 151 if (!error)
162 buf->bs_mode = be16_to_cpu(dic->di_mode); 152 *stat = BULKSTAT_RV_DIDONE;
163 buf->bs_uid = be32_to_cpu(dic->di_uid);
164 buf->bs_gid = be32_to_cpu(dic->di_gid);
165 buf->bs_size = be64_to_cpu(dic->di_size);
166 buf->bs_atime.tv_sec = be32_to_cpu(dic->di_atime.t_sec);
167 buf->bs_atime.tv_nsec = be32_to_cpu(dic->di_atime.t_nsec);
168 buf->bs_mtime.tv_sec = be32_to_cpu(dic->di_mtime.t_sec);
169 buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec);
170 buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec);
171 buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec);
172 buf->bs_xflags = xfs_dic2xflags(dic);
173 buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog;
174 buf->bs_extents = be32_to_cpu(dic->di_nextents);
175 buf->bs_gen = be32_to_cpu(dic->di_gen);
176 memset(buf->bs_pad, 0, sizeof(buf->bs_pad));
177 buf->bs_dmevmask = be32_to_cpu(dic->di_dmevmask);
178 buf->bs_dmstate = be16_to_cpu(dic->di_dmstate);
179 buf->bs_aextents = be16_to_cpu(dic->di_anextents);
180 buf->bs_forkoff = XFS_DFORK_BOFF(dic);
181 153
182 switch (dic->di_format) { 154 out_free:
183 case XFS_DINODE_FMT_DEV: 155 kmem_free(buf);
184 buf->bs_rdev = xfs_dinode_get_rdev(dic); 156 return error;
185 buf->bs_blksize = BLKDEV_IOSIZE;
186 buf->bs_blocks = 0;
187 break;
188 case XFS_DINODE_FMT_LOCAL:
189 case XFS_DINODE_FMT_UUID:
190 buf->bs_rdev = 0;
191 buf->bs_blksize = mp->m_sb.sb_blocksize;
192 buf->bs_blocks = 0;
193 break;
194 case XFS_DINODE_FMT_EXTENTS:
195 case XFS_DINODE_FMT_BTREE:
196 buf->bs_rdev = 0;
197 buf->bs_blksize = mp->m_sb.sb_blocksize;
198 buf->bs_blocks = be64_to_cpu(dic->di_nblocks);
199 break;
200 }
201} 157}
202 158
203/* Return 0 on success or positive error */ 159/* Return 0 on success or positive error */
@@ -217,118 +173,19 @@ xfs_bulkstat_one_fmt(
217 return 0; 173 return 0;
218} 174}
219 175
220/*
221 * Return stat information for one inode.
222 * Return 0 if ok, else errno.
223 */
224int /* error status */
225xfs_bulkstat_one_int(
226 xfs_mount_t *mp, /* mount point for filesystem */
227 xfs_ino_t ino, /* inode number to get data for */
228 void __user *buffer, /* buffer to place output in */
229 int ubsize, /* size of buffer */
230 bulkstat_one_fmt_pf formatter, /* formatter, copy to user */
231 xfs_daddr_t bno, /* starting bno of inode cluster */
232 int *ubused, /* bytes used by me */
233 void *dibuff, /* on-disk inode buffer */
234 int *stat) /* BULKSTAT_RV_... */
235{
236 xfs_bstat_t *buf; /* return buffer */
237 int error = 0; /* error value */
238 xfs_dinode_t *dip; /* dinode inode pointer */
239
240 dip = (xfs_dinode_t *)dibuff;
241 *stat = BULKSTAT_RV_NOTHING;
242
243 if (!buffer || xfs_internal_inum(mp, ino))
244 return XFS_ERROR(EINVAL);
245
246 buf = kmem_alloc(sizeof(*buf), KM_SLEEP);
247
248 if (dip == NULL) {
249 /* We're not being passed a pointer to a dinode. This happens
250 * if BULKSTAT_FG_IGET is selected. Do the iget.
251 */
252 error = xfs_bulkstat_one_iget(mp, ino, bno, buf, stat);
253 if (error)
254 goto out_free;
255 } else {
256 xfs_bulkstat_one_dinode(mp, ino, dip, buf);
257 }
258
259 error = formatter(buffer, ubsize, ubused, buf);
260 if (error)
261 goto out_free;
262
263 *stat = BULKSTAT_RV_DIDONE;
264
265 out_free:
266 kmem_free(buf);
267 return error;
268}
269
270int 176int
271xfs_bulkstat_one( 177xfs_bulkstat_one(
272 xfs_mount_t *mp, /* mount point for filesystem */ 178 xfs_mount_t *mp, /* mount point for filesystem */
273 xfs_ino_t ino, /* inode number to get data for */ 179 xfs_ino_t ino, /* inode number to get data for */
274 void __user *buffer, /* buffer to place output in */ 180 void __user *buffer, /* buffer to place output in */
275 int ubsize, /* size of buffer */ 181 int ubsize, /* size of buffer */
276 void *private_data, /* my private data */
277 xfs_daddr_t bno, /* starting bno of inode cluster */ 182 xfs_daddr_t bno, /* starting bno of inode cluster */
278 int *ubused, /* bytes used by me */ 183 int *ubused, /* bytes used by me */
279 void *dibuff, /* on-disk inode buffer */
280 int *stat) /* BULKSTAT_RV_... */ 184 int *stat) /* BULKSTAT_RV_... */
281{ 185{
282 return xfs_bulkstat_one_int(mp, ino, buffer, ubsize, 186 return xfs_bulkstat_one_int(mp, ino, buffer, ubsize,
283 xfs_bulkstat_one_fmt, bno, 187 xfs_bulkstat_one_fmt, bno,
284 ubused, dibuff, stat); 188 ubused, stat);
285}
286
287/*
288 * Test to see whether we can use the ondisk inode directly, based
289 * on the given bulkstat flags, filling in dipp accordingly.
290 * Returns zero if the inode is dodgey.
291 */
292STATIC int
293xfs_bulkstat_use_dinode(
294 xfs_mount_t *mp,
295 int flags,
296 xfs_buf_t *bp,
297 int clustidx,
298 xfs_dinode_t **dipp)
299{
300 xfs_dinode_t *dip;
301 unsigned int aformat;
302
303 *dipp = NULL;
304 if (!bp || (flags & BULKSTAT_FG_IGET))
305 return 1;
306 dip = (xfs_dinode_t *)
307 xfs_buf_offset(bp, clustidx << mp->m_sb.sb_inodelog);
308 /*
309 * Check the buffer containing the on-disk inode for di_mode == 0.
310 * This is to prevent xfs_bulkstat from picking up just reclaimed
311 * inodes that have their in-core state initialized but not flushed
312 * to disk yet. This is a temporary hack that would require a proper
313 * fix in the future.
314 */
315 if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC ||
316 !XFS_DINODE_GOOD_VERSION(dip->di_version) ||
317 !dip->di_mode)
318 return 0;
319 if (flags & BULKSTAT_FG_QUICK) {
320 *dipp = dip;
321 return 1;
322 }
323 /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */
324 aformat = dip->di_aformat;
325 if ((XFS_DFORK_Q(dip) == 0) ||
326 (aformat == XFS_DINODE_FMT_LOCAL) ||
327 (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_anextents)) {
328 *dipp = dip;
329 return 1;
330 }
331 return 1;
332} 189}
333 190
334#define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size) 191#define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size)
@@ -342,10 +199,8 @@ xfs_bulkstat(
342 xfs_ino_t *lastinop, /* last inode returned */ 199 xfs_ino_t *lastinop, /* last inode returned */
343 int *ubcountp, /* size of buffer/count returned */ 200 int *ubcountp, /* size of buffer/count returned */
344 bulkstat_one_pf formatter, /* func that'd fill a single buf */ 201 bulkstat_one_pf formatter, /* func that'd fill a single buf */
345 void *private_data,/* private data for formatter */
346 size_t statstruct_size, /* sizeof struct filling */ 202 size_t statstruct_size, /* sizeof struct filling */
347 char __user *ubuffer, /* buffer with inode stats */ 203 char __user *ubuffer, /* buffer with inode stats */
348 int flags, /* defined in xfs_itable.h */
349 int *done) /* 1 if there are more stats to get */ 204 int *done) /* 1 if there are more stats to get */
350{ 205{
351 xfs_agblock_t agbno=0;/* allocation group block number */ 206 xfs_agblock_t agbno=0;/* allocation group block number */
@@ -380,14 +235,12 @@ xfs_bulkstat(
380 int ubelem; /* spaces used in user's buffer */ 235 int ubelem; /* spaces used in user's buffer */
381 int ubused; /* bytes used by formatter */ 236 int ubused; /* bytes used by formatter */
382 xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */ 237 xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */
383 xfs_dinode_t *dip; /* ptr into bp for specific inode */
384 238
385 /* 239 /*
386 * Get the last inode value, see if there's nothing to do. 240 * Get the last inode value, see if there's nothing to do.
387 */ 241 */
388 ino = (xfs_ino_t)*lastinop; 242 ino = (xfs_ino_t)*lastinop;
389 lastino = ino; 243 lastino = ino;
390 dip = NULL;
391 agno = XFS_INO_TO_AGNO(mp, ino); 244 agno = XFS_INO_TO_AGNO(mp, ino);
392 agino = XFS_INO_TO_AGINO(mp, ino); 245 agino = XFS_INO_TO_AGINO(mp, ino);
393 if (agno >= mp->m_sb.sb_agcount || 246 if (agno >= mp->m_sb.sb_agcount ||
@@ -612,37 +465,6 @@ xfs_bulkstat(
612 irbp->ir_startino) + 465 irbp->ir_startino) +
613 ((chunkidx & nimask) >> 466 ((chunkidx & nimask) >>
614 mp->m_sb.sb_inopblog); 467 mp->m_sb.sb_inopblog);
615
616 if (flags & (BULKSTAT_FG_QUICK |
617 BULKSTAT_FG_INLINE)) {
618 int offset;
619
620 ino = XFS_AGINO_TO_INO(mp, agno,
621 agino);
622 bno = XFS_AGB_TO_DADDR(mp, agno,
623 agbno);
624
625 /*
626 * Get the inode cluster buffer
627 */
628 if (bp)
629 xfs_buf_relse(bp);
630
631 error = xfs_inotobp(mp, NULL, ino, &dip,
632 &bp, &offset,
633 XFS_IGET_BULKSTAT);
634
635 if (!error)
636 clustidx = offset / mp->m_sb.sb_inodesize;
637 if (XFS_TEST_ERROR(error != 0,
638 mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK,
639 XFS_RANDOM_BULKSTAT_READ_CHUNK)) {
640 bp = NULL;
641 ubleft = 0;
642 rval = error;
643 break;
644 }
645 }
646 } 468 }
647 ino = XFS_AGINO_TO_INO(mp, agno, agino); 469 ino = XFS_AGINO_TO_INO(mp, agno, agino);
648 bno = XFS_AGB_TO_DADDR(mp, agno, agbno); 470 bno = XFS_AGB_TO_DADDR(mp, agno, agbno);
@@ -658,35 +480,13 @@ xfs_bulkstat(
658 * when the chunk is used up. 480 * when the chunk is used up.
659 */ 481 */
660 irbp->ir_freecount++; 482 irbp->ir_freecount++;
661 if (!xfs_bulkstat_use_dinode(mp, flags, bp,
662 clustidx, &dip)) {
663 lastino = ino;
664 continue;
665 }
666 /*
667 * If we need to do an iget, cannot hold bp.
668 * Drop it, until starting the next cluster.
669 */
670 if ((flags & BULKSTAT_FG_INLINE) && !dip) {
671 if (bp)
672 xfs_buf_relse(bp);
673 bp = NULL;
674 }
675 483
676 /* 484 /*
677 * Get the inode and fill in a single buffer. 485 * Get the inode and fill in a single buffer.
678 * BULKSTAT_FG_QUICK uses dip to fill it in.
679 * BULKSTAT_FG_IGET uses igets.
680 * BULKSTAT_FG_INLINE uses dip if we have an
681 * inline attr fork, else igets.
682 * See: xfs_bulkstat_one & xfs_dm_bulkstat_one.
683 * This is also used to count inodes/blks, etc
684 * in xfs_qm_quotacheck.
685 */ 486 */
686 ubused = statstruct_size; 487 ubused = statstruct_size;
687 error = formatter(mp, ino, ubufp, 488 error = formatter(mp, ino, ubufp, ubleft, bno,
688 ubleft, private_data, 489 &ubused, &fmterror);
689 bno, &ubused, dip, &fmterror);
690 if (fmterror == BULKSTAT_RV_NOTHING) { 490 if (fmterror == BULKSTAT_RV_NOTHING) {
691 if (error && error != ENOENT && 491 if (error && error != ENOENT &&
692 error != EINVAL) { 492 error != EINVAL) {
@@ -779,7 +579,7 @@ xfs_bulkstat_single(
779 579
780 ino = (xfs_ino_t)*lastinop; 580 ino = (xfs_ino_t)*lastinop;
781 error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t), 581 error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t),
782 NULL, 0, NULL, NULL, &res); 582 0, NULL, &res);
783 if (error) { 583 if (error) {
784 /* 584 /*
785 * Special case way failed, do it the "long" way 585 * Special case way failed, do it the "long" way
@@ -788,8 +588,7 @@ xfs_bulkstat_single(
788 (*lastinop)--; 588 (*lastinop)--;
789 count = 1; 589 count = 1;
790 if (xfs_bulkstat(mp, lastinop, &count, xfs_bulkstat_one, 590 if (xfs_bulkstat(mp, lastinop, &count, xfs_bulkstat_one,
791 NULL, sizeof(xfs_bstat_t), buffer, 591 sizeof(xfs_bstat_t), buffer, done))
792 BULKSTAT_FG_IGET, done))
793 return error; 592 return error;
794 if (count == 0 || (xfs_ino_t)*lastinop != ino) 593 if (count == 0 || (xfs_ino_t)*lastinop != ino)
795 return error == EFSCORRUPTED ? 594 return error == EFSCORRUPTED ?
diff --git a/fs/xfs/xfs_itable.h b/fs/xfs/xfs_itable.h
index 20792bf45946..fea03397a3ab 100644
--- a/fs/xfs/xfs_itable.h
+++ b/fs/xfs/xfs_itable.h
@@ -27,10 +27,8 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
27 xfs_ino_t ino, 27 xfs_ino_t ino,
28 void __user *buffer, 28 void __user *buffer,
29 int ubsize, 29 int ubsize,
30 void *private_data,
31 xfs_daddr_t bno, 30 xfs_daddr_t bno,
32 int *ubused, 31 int *ubused,
33 void *dip,
34 int *stat); 32 int *stat);
35 33
36/* 34/*
@@ -41,13 +39,6 @@ typedef int (*bulkstat_one_pf)(struct xfs_mount *mp,
41#define BULKSTAT_RV_GIVEUP 2 39#define BULKSTAT_RV_GIVEUP 2
42 40
43/* 41/*
44 * Values for bulkstat flag argument.
45 */
46#define BULKSTAT_FG_IGET 0x1 /* Go through the buffer cache */
47#define BULKSTAT_FG_QUICK 0x2 /* No iget, walk the dinode cluster */
48#define BULKSTAT_FG_INLINE 0x4 /* No iget if inline attrs */
49
50/*
51 * Return stat information in bulk (by-inode) for the filesystem. 42 * Return stat information in bulk (by-inode) for the filesystem.
52 */ 43 */
53int /* error status */ 44int /* error status */
@@ -56,10 +47,8 @@ xfs_bulkstat(
56 xfs_ino_t *lastino, /* last inode returned */ 47 xfs_ino_t *lastino, /* last inode returned */
57 int *count, /* size of buffer/count returned */ 48 int *count, /* size of buffer/count returned */
58 bulkstat_one_pf formatter, /* func that'd fill a single buf */ 49 bulkstat_one_pf formatter, /* func that'd fill a single buf */
59 void *private_data, /* private data for formatter */
60 size_t statstruct_size,/* sizeof struct that we're filling */ 50 size_t statstruct_size,/* sizeof struct that we're filling */
61 char __user *ubuffer,/* buffer with inode stats */ 51 char __user *ubuffer,/* buffer with inode stats */
62 int flags, /* flag to control access method */
63 int *done); /* 1 if there are more stats to get */ 52 int *done); /* 1 if there are more stats to get */
64 53
65int 54int
@@ -84,7 +73,6 @@ xfs_bulkstat_one_int(
84 bulkstat_one_fmt_pf formatter, 73 bulkstat_one_fmt_pf formatter,
85 xfs_daddr_t bno, 74 xfs_daddr_t bno,
86 int *ubused, 75 int *ubused,
87 void *dibuff,
88 int *stat); 76 int *stat);
89 77
90int 78int
@@ -93,10 +81,8 @@ xfs_bulkstat_one(
93 xfs_ino_t ino, 81 xfs_ino_t ino,
94 void __user *buffer, 82 void __user *buffer,
95 int ubsize, 83 int ubsize,
96 void *private_data,
97 xfs_daddr_t bno, 84 xfs_daddr_t bno,
98 int *ubused, 85 int *ubused,
99 void *dibuff,
100 int *stat); 86 int *stat);
101 87
102typedef int (*inumbers_fmt_pf)( 88typedef int (*inumbers_fmt_pf)(