Blame view
fs/xfs/xfs_itable.c
19.8 KB
1da177e4c Linux-2.6.12-rc2 |
1 |
/* |
7b7187698 [XFS] Update lice... |
2 3 |
* Copyright (c) 2000-2002,2005 Silicon Graphics, Inc. * All Rights Reserved. |
1da177e4c Linux-2.6.12-rc2 |
4 |
* |
7b7187698 [XFS] Update lice... |
5 6 |
* This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as |
1da177e4c Linux-2.6.12-rc2 |
7 8 |
* published by the Free Software Foundation. * |
7b7187698 [XFS] Update lice... |
9 10 11 12 |
* This program is distributed in the hope that it would be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. |
1da177e4c Linux-2.6.12-rc2 |
13 |
* |
7b7187698 [XFS] Update lice... |
14 15 16 |
* You should have received a copy of the GNU General Public License * along with this program; if not, write the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
1da177e4c Linux-2.6.12-rc2 |
17 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
18 |
#include "xfs.h" |
a844f4510 [XFS] Remove xfs_... |
19 |
#include "xfs_fs.h" |
1da177e4c Linux-2.6.12-rc2 |
20 |
#include "xfs_types.h" |
a844f4510 [XFS] Remove xfs_... |
21 |
#include "xfs_bit.h" |
1da177e4c Linux-2.6.12-rc2 |
22 |
#include "xfs_log.h" |
a844f4510 [XFS] Remove xfs_... |
23 |
#include "xfs_inum.h" |
1da177e4c Linux-2.6.12-rc2 |
24 25 |
#include "xfs_trans.h" #include "xfs_sb.h" |
a844f4510 [XFS] Remove xfs_... |
26 |
#include "xfs_ag.h" |
1da177e4c Linux-2.6.12-rc2 |
27 |
#include "xfs_mount.h" |
1da177e4c Linux-2.6.12-rc2 |
28 |
#include "xfs_bmap_btree.h" |
a844f4510 [XFS] Remove xfs_... |
29 |
#include "xfs_alloc_btree.h" |
1da177e4c Linux-2.6.12-rc2 |
30 |
#include "xfs_ialloc_btree.h" |
1da177e4c Linux-2.6.12-rc2 |
31 32 33 34 35 |
#include "xfs_dinode.h" #include "xfs_inode.h" #include "xfs_ialloc.h" #include "xfs_itable.h" #include "xfs_error.h" |
a844f4510 [XFS] Remove xfs_... |
36 |
#include "xfs_btree.h" |
f2d676143 xfs: remove xfs_iput |
37 |
#include "xfs_trace.h" |
1da177e4c Linux-2.6.12-rc2 |
38 |
|
d96f8f891 xfs: add more sta... |
39 |
STATIC int |
6f1f21684 [XFS] pv 956241, ... |
40 41 42 43 44 |
xfs_internal_inum( xfs_mount_t *mp, xfs_ino_t ino) { return (ino == mp->m_sb.sb_rbmino || ino == mp->m_sb.sb_rsumino || |
621187099 [XFS] remove shou... |
45 |
(xfs_sb_version_hasquota(&mp->m_sb) && |
6f1f21684 [XFS] pv 956241, ... |
46 47 |
(ino == mp->m_sb.sb_uquotino || ino == mp->m_sb.sb_gquotino))); } |
7dce11dba xfs: always use i... |
48 49 50 51 52 53 54 55 56 57 58 |
/* * Return stat information for one inode. * Return 0 if ok, else errno. */ int xfs_bulkstat_one_int( struct xfs_mount *mp, /* mount point for filesystem */ xfs_ino_t ino, /* inode to get data for */ void __user *buffer, /* buffer to place output in */ int ubsize, /* size of buffer */ bulkstat_one_fmt_pf formatter, /* formatter, copy to user */ |
7dce11dba xfs: always use i... |
59 60 |
int *ubused, /* bytes used by me */ int *stat) /* BULKSTAT_RV_... */ |
1da177e4c Linux-2.6.12-rc2 |
61 |
{ |
7dce11dba xfs: always use i... |
62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
struct xfs_icdinode *dic; /* dinode core info pointer */ struct xfs_inode *ip; /* incore inode pointer */ struct inode *inode; struct xfs_bstat *buf; /* return buffer */ int error = 0; /* error value */ *stat = BULKSTAT_RV_NOTHING; if (!buffer || xfs_internal_inum(mp, ino)) return XFS_ERROR(EINVAL); buf = kmem_alloc(sizeof(*buf), KM_SLEEP | KM_MAYFAIL); if (!buf) return XFS_ERROR(ENOMEM); |
1da177e4c Linux-2.6.12-rc2 |
76 |
|
745b1f47f [XFS] Remove last... |
77 |
error = xfs_iget(mp, NULL, ino, |
7b6259e7a xfs: remove block... |
78 |
XFS_IGET_UNTRUSTED, XFS_ILOCK_SHARED, &ip); |
1da177e4c Linux-2.6.12-rc2 |
79 80 |
if (error) { *stat = BULKSTAT_RV_NOTHING; |
7dce11dba xfs: always use i... |
81 |
goto out_free; |
1da177e4c Linux-2.6.12-rc2 |
82 83 84 |
} ASSERT(ip != NULL); |
92bfc6e7c [XFS] embededd st... |
85 |
ASSERT(ip->i_imap.im_blkno != 0); |
1da177e4c Linux-2.6.12-rc2 |
86 87 |
dic = &ip->i_d; |
f9581b144 xfs: implement ->... |
88 |
inode = VFS_I(ip); |
1da177e4c Linux-2.6.12-rc2 |
89 90 91 92 93 |
/* xfs_iget returns the following without needing * further change. */ buf->bs_nlink = dic->di_nlink; |
6743099ce xfs: Extend proje... |
94 95 |
buf->bs_projid_lo = dic->di_projid_lo; buf->bs_projid_hi = dic->di_projid_hi; |
1da177e4c Linux-2.6.12-rc2 |
96 97 98 99 100 |
buf->bs_ino = ino; buf->bs_mode = dic->di_mode; buf->bs_uid = dic->di_uid; buf->bs_gid = dic->di_gid; buf->bs_size = dic->di_size; |
f9581b144 xfs: implement ->... |
101 |
|
8fab451e3 xfs: kill vn_atim... |
102 |
/* |
f9581b144 xfs: implement ->... |
103 104 105 |
* We need to read the timestamps from the Linux inode because * the VFS keeps writing directly into the inode structure instead * of telling us about the updates. |
8fab451e3 xfs: kill vn_atim... |
106 |
*/ |
f9581b144 xfs: implement ->... |
107 108 109 110 111 112 |
buf->bs_atime.tv_sec = inode->i_atime.tv_sec; buf->bs_atime.tv_nsec = inode->i_atime.tv_nsec; buf->bs_mtime.tv_sec = inode->i_mtime.tv_sec; buf->bs_mtime.tv_nsec = inode->i_mtime.tv_nsec; buf->bs_ctime.tv_sec = inode->i_ctime.tv_sec; buf->bs_ctime.tv_nsec = inode->i_ctime.tv_nsec; |
1da177e4c Linux-2.6.12-rc2 |
113 114 115 116 117 118 119 120 |
buf->bs_xflags = xfs_ip2xflags(ip); buf->bs_extsize = dic->di_extsize << mp->m_sb.sb_blocklog; buf->bs_extents = dic->di_nextents; buf->bs_gen = dic->di_gen; memset(buf->bs_pad, 0, sizeof(buf->bs_pad)); buf->bs_dmevmask = dic->di_dmevmask; buf->bs_dmstate = dic->di_dmstate; buf->bs_aextents = dic->di_anextents; |
07000ee68 xfs: return inode... |
121 |
buf->bs_forkoff = XFS_IFORK_BOFF(ip); |
1da177e4c Linux-2.6.12-rc2 |
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
switch (dic->di_format) { case XFS_DINODE_FMT_DEV: buf->bs_rdev = ip->i_df.if_u2.if_rdev; buf->bs_blksize = BLKDEV_IOSIZE; buf->bs_blocks = 0; break; case XFS_DINODE_FMT_LOCAL: case XFS_DINODE_FMT_UUID: buf->bs_rdev = 0; buf->bs_blksize = mp->m_sb.sb_blocksize; buf->bs_blocks = 0; break; case XFS_DINODE_FMT_EXTENTS: case XFS_DINODE_FMT_BTREE: buf->bs_rdev = 0; buf->bs_blksize = mp->m_sb.sb_blocksize; buf->bs_blocks = dic->di_nblocks + ip->i_delayed_blks; break; } |
f2d676143 xfs: remove xfs_iput |
142 143 |
xfs_iunlock(ip, XFS_ILOCK_SHARED); IRELE(ip); |
1da177e4c Linux-2.6.12-rc2 |
144 |
|
7dce11dba xfs: always use i... |
145 |
error = formatter(buffer, ubsize, ubused, buf); |
1da177e4c Linux-2.6.12-rc2 |
146 |
|
7dce11dba xfs: always use i... |
147 148 |
if (!error) *stat = BULKSTAT_RV_DIDONE; |
1da177e4c Linux-2.6.12-rc2 |
149 |
|
7dce11dba xfs: always use i... |
150 151 152 |
out_free: kmem_free(buf); return error; |
1da177e4c Linux-2.6.12-rc2 |
153 |
} |
65fbaf248 [XFS] Fix xfs_bul... |
154 |
/* Return 0 on success or positive error */ |
faa63e958 [XFS] Fix XFS_IOC... |
155 156 157 |
STATIC int xfs_bulkstat_one_fmt( void __user *ubuffer, |
65fbaf248 [XFS] Fix xfs_bul... |
158 159 |
int ubsize, int *ubused, |
faa63e958 [XFS] Fix XFS_IOC... |
160 161 |
const xfs_bstat_t *buffer) { |
65fbaf248 [XFS] Fix xfs_bul... |
162 163 |
if (ubsize < sizeof(*buffer)) return XFS_ERROR(ENOMEM); |
faa63e958 [XFS] Fix XFS_IOC... |
164 |
if (copy_to_user(ubuffer, buffer, sizeof(*buffer))) |
65fbaf248 [XFS] Fix xfs_bul... |
165 166 167 168 |
return XFS_ERROR(EFAULT); if (ubused) *ubused = sizeof(*buffer); return 0; |
faa63e958 [XFS] Fix XFS_IOC... |
169 |
} |
2ee4fa5cb [XFS] Make the bu... |
170 171 172 173 174 175 |
int xfs_bulkstat_one( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t ino, /* inode number to get data for */ void __user *buffer, /* buffer to place output in */ int ubsize, /* size of buffer */ |
2ee4fa5cb [XFS] Make the bu... |
176 |
int *ubused, /* bytes used by me */ |
2ee4fa5cb [XFS] Make the bu... |
177 178 179 |
int *stat) /* BULKSTAT_RV_... */ { return xfs_bulkstat_one_int(mp, ino, buffer, ubsize, |
7b6259e7a xfs: remove block... |
180 |
xfs_bulkstat_one_fmt, ubused, stat); |
8b56f083c [XFS] Rework DMAP... |
181 |
} |
cd57e594a [XFS] 971064 Vari... |
182 |
#define XFS_BULKSTAT_UBLEFT(ubleft) ((ubleft) >= statstruct_size) |
8b56f083c [XFS] Rework DMAP... |
183 |
/* |
1da177e4c Linux-2.6.12-rc2 |
184 185 186 187 188 189 190 191 |
* Return stat information in bulk (by-inode) for the filesystem. */ int /* error status */ xfs_bulkstat( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t *lastinop, /* last inode returned */ int *ubcountp, /* size of buffer/count returned */ bulkstat_one_pf formatter, /* func that'd fill a single buf */ |
1da177e4c Linux-2.6.12-rc2 |
192 193 |
size_t statstruct_size, /* sizeof struct filling */ char __user *ubuffer, /* buffer with inode stats */ |
c41564b5a [XFS] We really s... |
194 |
int *done) /* 1 if there are more stats to get */ |
1da177e4c Linux-2.6.12-rc2 |
195 196 197 198 199 200 |
{ xfs_agblock_t agbno=0;/* allocation group block number */ xfs_buf_t *agbp; /* agi header buffer */ xfs_agi_t *agi; /* agi header data */ xfs_agino_t agino; /* inode # in allocation group */ xfs_agnumber_t agno; /* allocation group number */ |
1da177e4c Linux-2.6.12-rc2 |
201 202 203 204 205 206 |
int chunkidx; /* current index into inode chunk */ int clustidx; /* current index into inode cluster */ xfs_btree_cur_t *cur; /* btree cursor for ialloc btree */ int end_of_ag; /* set if we've seen the ag end */ int error; /* error code */ int fmterror;/* bulkstat formatter result */ |
1da177e4c Linux-2.6.12-rc2 |
207 208 |
int i; /* loop index */ int icount; /* count of inodes good in irbuf */ |
215101c36 [XFS] Fix kmem_za... |
209 |
size_t irbsize; /* size of irec buffer in bytes */ |
1da177e4c Linux-2.6.12-rc2 |
210 |
xfs_ino_t ino; /* inode number (filesystem) */ |
262750933 [XFS] Drop unneed... |
211 212 213 |
xfs_inobt_rec_incore_t *irbp; /* current irec buffer pointer */ xfs_inobt_rec_incore_t *irbuf; /* start of irec buffer */ xfs_inobt_rec_incore_t *irbufend; /* end of good irec buffer entries */ |
cd57e594a [XFS] 971064 Vari... |
214 |
xfs_ino_t lastino; /* last inode number returned */ |
1da177e4c Linux-2.6.12-rc2 |
215 216 217 218 219 220 221 222 223 224 225 226 |
int nbcluster; /* # of blocks in a cluster */ int nicluster; /* # of inodes in a cluster */ int nimask; /* mask for inode clusters */ int nirbuf; /* size of irbuf */ int rval; /* return value error code */ int tmp; /* result value from btree calls */ int ubcount; /* size of user's buffer */ int ubleft; /* bytes left in user's buffer */ char __user *ubufp; /* 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 */ |
1da177e4c Linux-2.6.12-rc2 |
227 228 229 230 231 |
/* * Get the last inode value, see if there's nothing to do. */ ino = (xfs_ino_t)*lastinop; |
cd57e594a [XFS] 971064 Vari... |
232 |
lastino = ino; |
1da177e4c Linux-2.6.12-rc2 |
233 234 235 236 237 238 239 240 |
agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); if (agno >= mp->m_sb.sb_agcount || ino != XFS_AGINO_TO_INO(mp, agno, agino)) { *done = 1; *ubcountp = 0; return 0; } |
cd57e594a [XFS] 971064 Vari... |
241 242 243 |
if (!ubcountp || *ubcountp <= 0) { return EINVAL; } |
1da177e4c Linux-2.6.12-rc2 |
244 245 246 247 248 249 250 251 252 253 254 |
ubcount = *ubcountp; /* statstruct's */ ubleft = ubcount * statstruct_size; /* bytes */ *ubcountp = ubelem = 0; *done = 0; fmterror = 0; ubufp = ubuffer; nicluster = mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp) ? mp->m_sb.sb_inopblock : (XFS_INODE_CLUSTER_SIZE(mp) >> mp->m_sb.sb_inodelog); nimask = ~(nicluster - 1); nbcluster = nicluster >> mp->m_sb.sb_inopblog; |
bdfb04301 xfs: replace KM_L... |
255 256 257 |
irbuf = kmem_zalloc_greedy(&irbsize, PAGE_SIZE, PAGE_SIZE * 4); if (!irbuf) return ENOMEM; |
bb3c7d293 [XFS] Increase th... |
258 |
nirbuf = irbsize / sizeof(*irbuf); |
1da177e4c Linux-2.6.12-rc2 |
259 260 261 262 263 |
/* * Loop over the allocation groups, starting from the last * inode returned; 0 means start of the allocation group. */ rval = 0; |
cd57e594a [XFS] 971064 Vari... |
264 265 |
while (XFS_BULKSTAT_UBLEFT(ubleft) && agno < mp->m_sb.sb_agcount) { cond_resched(); |
1da177e4c Linux-2.6.12-rc2 |
266 |
bp = NULL; |
1da177e4c Linux-2.6.12-rc2 |
267 |
error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); |
1da177e4c Linux-2.6.12-rc2 |
268 269 270 271 272 273 274 275 276 277 278 279 |
if (error) { /* * Skip this allocation group and go to the next one. */ agno++; agino = 0; continue; } agi = XFS_BUF_TO_AGI(agbp); /* * Allocate and initialize a btree cursor for ialloc btree. */ |
561f7d173 [XFS] split up xf... |
280 |
cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno); |
1da177e4c Linux-2.6.12-rc2 |
281 282 283 284 285 286 287 288 |
irbp = irbuf; irbufend = irbuf + nirbuf; end_of_ag = 0; /* * If we're returning in the middle of an allocation group, * we need to get the remainder of the chunk we're in. */ if (agino > 0) { |
2e287a731 xfs: improve xfs_... |
289 |
xfs_inobt_rec_incore_t r; |
1da177e4c Linux-2.6.12-rc2 |
290 291 292 |
/* * Lookup the inode chunk that this inode lives in. */ |
218755052 xfs: rationalize ... |
293 294 |
error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_LE, &tmp); |
1da177e4c Linux-2.6.12-rc2 |
295 296 297 |
if (!error && /* no I/O error */ tmp && /* lookup succeeded */ /* got the record, should always work */ |
2e287a731 xfs: improve xfs_... |
298 |
!(error = xfs_inobt_get_rec(cur, &r, &i)) && |
1da177e4c Linux-2.6.12-rc2 |
299 300 |
i == 1 && /* this is the right chunk */ |
2e287a731 xfs: improve xfs_... |
301 |
agino < r.ir_startino + XFS_INODES_PER_CHUNK && |
1da177e4c Linux-2.6.12-rc2 |
302 |
/* lastino was not last in chunk */ |
2e287a731 xfs: improve xfs_... |
303 |
(chunkidx = agino - r.ir_startino + 1) < |
1da177e4c Linux-2.6.12-rc2 |
304 305 |
XFS_INODES_PER_CHUNK && /* there are some left allocated */ |
9d87c3192 [XFS] Remove the ... |
306 |
xfs_inobt_maskn(chunkidx, |
2e287a731 xfs: improve xfs_... |
307 308 |
XFS_INODES_PER_CHUNK - chunkidx) & ~r.ir_free) { |
1da177e4c Linux-2.6.12-rc2 |
309 310 311 312 313 314 |
/* * Grab the chunk record. Mark all the * uninteresting inodes (because they're * before our start point) free. */ for (i = 0; i < chunkidx; i++) { |
2e287a731 xfs: improve xfs_... |
315 316 |
if (XFS_INOBT_MASK(i) & ~r.ir_free) r.ir_freecount++; |
1da177e4c Linux-2.6.12-rc2 |
317 |
} |
2e287a731 xfs: improve xfs_... |
318 319 320 321 |
r.ir_free |= xfs_inobt_maskn(0, chunkidx); irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount; irbp->ir_free = r.ir_free; |
1da177e4c Linux-2.6.12-rc2 |
322 |
irbp++; |
2e287a731 xfs: improve xfs_... |
323 324 |
agino = r.ir_startino + XFS_INODES_PER_CHUNK; icount = XFS_INODES_PER_CHUNK - r.ir_freecount; |
1da177e4c Linux-2.6.12-rc2 |
325 326 327 328 329 330 331 332 333 334 335 336 |
} else { /* * If any of those tests failed, bump the * inode number (just in case). */ agino++; icount = 0; } /* * In any case, increment to the next record. */ if (!error) |
637aa50f4 [XFS] implement g... |
337 |
error = xfs_btree_increment(cur, 0, &tmp); |
1da177e4c Linux-2.6.12-rc2 |
338 339 340 341 |
} else { /* * Start of ag. Lookup the first inode chunk. */ |
218755052 xfs: rationalize ... |
342 |
error = xfs_inobt_lookup(cur, 0, XFS_LOOKUP_GE, &tmp); |
1da177e4c Linux-2.6.12-rc2 |
343 344 345 346 347 348 349 |
icount = 0; } /* * Loop through inode btree records in this ag, * until we run out of inodes or space in the buffer. */ while (irbp < irbufend && icount < ubcount) { |
2e287a731 xfs: improve xfs_... |
350 |
xfs_inobt_rec_incore_t r; |
1da177e4c Linux-2.6.12-rc2 |
351 352 353 354 355 356 357 |
/* * Loop as long as we're unable to read the * inode btree. */ while (error) { agino += XFS_INODES_PER_CHUNK; if (XFS_AGINO_TO_AGBNO(mp, agino) >= |
16259e7d9 [XFS] Endianess a... |
358 |
be32_to_cpu(agi->agi_length)) |
1da177e4c Linux-2.6.12-rc2 |
359 |
break; |
218755052 xfs: rationalize ... |
360 361 |
error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_GE, &tmp); |
cd57e594a [XFS] 971064 Vari... |
362 |
cond_resched(); |
1da177e4c Linux-2.6.12-rc2 |
363 364 365 366 367 |
} /* * If ran off the end of the ag either with an error, * or the normal way, set end and stop collecting. */ |
2e287a731 xfs: improve xfs_... |
368 369 370 371 372 373 374 |
if (error) { end_of_ag = 1; break; } error = xfs_inobt_get_rec(cur, &r, &i); if (error || i == 0) { |
1da177e4c Linux-2.6.12-rc2 |
375 376 377 |
end_of_ag = 1; break; } |
2e287a731 xfs: improve xfs_... |
378 |
|
1da177e4c Linux-2.6.12-rc2 |
379 380 |
/* * If this chunk has any allocated inodes, save it. |
262750933 [XFS] Drop unneed... |
381 |
* Also start read-ahead now for this chunk. |
1da177e4c Linux-2.6.12-rc2 |
382 |
*/ |
2e287a731 xfs: improve xfs_... |
383 |
if (r.ir_freecount < XFS_INODES_PER_CHUNK) { |
262750933 [XFS] Drop unneed... |
384 385 386 387 388 |
/* * Loop over all clusters in the next chunk. * Do a readahead if there are any allocated * inodes in that cluster. */ |
2e287a731 xfs: improve xfs_... |
389 390 |
agbno = XFS_AGINO_TO_AGBNO(mp, r.ir_startino); for (chunkidx = 0; |
262750933 [XFS] Drop unneed... |
391 392 393 |
chunkidx < XFS_INODES_PER_CHUNK; chunkidx += nicluster, agbno += nbcluster) { |
2e287a731 xfs: improve xfs_... |
394 395 |
if (xfs_inobt_maskn(chunkidx, nicluster) & ~r.ir_free) |
262750933 [XFS] Drop unneed... |
396 397 398 |
xfs_btree_reada_bufs(mp, agno, agbno, nbcluster); } |
2e287a731 xfs: improve xfs_... |
399 400 401 |
irbp->ir_startino = r.ir_startino; irbp->ir_freecount = r.ir_freecount; irbp->ir_free = r.ir_free; |
1da177e4c Linux-2.6.12-rc2 |
402 |
irbp++; |
2e287a731 xfs: improve xfs_... |
403 |
icount += XFS_INODES_PER_CHUNK - r.ir_freecount; |
1da177e4c Linux-2.6.12-rc2 |
404 405 406 407 |
} /* * Set agino to after this chunk and bump the cursor. */ |
2e287a731 xfs: improve xfs_... |
408 |
agino = r.ir_startino + XFS_INODES_PER_CHUNK; |
637aa50f4 [XFS] implement g... |
409 |
error = xfs_btree_increment(cur, 0, &tmp); |
cd57e594a [XFS] 971064 Vari... |
410 |
cond_resched(); |
1da177e4c Linux-2.6.12-rc2 |
411 412 413 414 415 416 417 418 419 420 421 422 423 |
} /* * Drop the btree buffers and the agi buffer. * We can't hold any of the locks these represent * when calling iget. */ xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); xfs_buf_relse(agbp); /* * Now format all the good inodes into the user's buffer. */ irbufend = irbp; for (irbp = irbuf; |
cd57e594a [XFS] 971064 Vari... |
424 |
irbp < irbufend && XFS_BULKSTAT_UBLEFT(ubleft); irbp++) { |
1da177e4c Linux-2.6.12-rc2 |
425 |
/* |
1da177e4c Linux-2.6.12-rc2 |
426 427 |
* Now process this chunk of inodes. */ |
262750933 [XFS] Drop unneed... |
428 |
for (agino = irbp->ir_startino, chunkidx = clustidx = 0; |
cd57e594a [XFS] 971064 Vari... |
429 |
XFS_BULKSTAT_UBLEFT(ubleft) && |
262750933 [XFS] Drop unneed... |
430 |
irbp->ir_freecount < XFS_INODES_PER_CHUNK; |
1da177e4c Linux-2.6.12-rc2 |
431 432 433 434 435 436 437 |
chunkidx++, clustidx++, agino++) { ASSERT(chunkidx < XFS_INODES_PER_CHUNK); /* * Recompute agbno if this is the * first inode of the cluster. * * Careful with clustidx. There can be |
9da096fd1 xfs: fix various ... |
438 |
* multiple clusters per chunk, a single |
1da177e4c Linux-2.6.12-rc2 |
439 440 441 442 443 444 445 446 447 448 449 |
* cluster per chunk or a cluster that has * inodes represented from several different * chunks (if blocksize is large). * * Because of this, the starting clustidx is * initialized to zero in this loop but must * later be reset after reading in the cluster * buffer. */ if ((chunkidx & (nicluster - 1)) == 0) { agbno = XFS_AGINO_TO_AGBNO(mp, |
262750933 [XFS] Drop unneed... |
450 |
irbp->ir_startino) + |
1da177e4c Linux-2.6.12-rc2 |
451 452 |
((chunkidx & nimask) >> mp->m_sb.sb_inopblog); |
1da177e4c Linux-2.6.12-rc2 |
453 |
} |
c2cba57e8 [XFS] This fix pr... |
454 |
ino = XFS_AGINO_TO_INO(mp, agno, agino); |
1da177e4c Linux-2.6.12-rc2 |
455 456 457 |
/* * Skip if this inode is free. */ |
c2cba57e8 [XFS] This fix pr... |
458 459 |
if (XFS_INOBT_MASK(chunkidx) & irbp->ir_free) { lastino = ino; |
1da177e4c Linux-2.6.12-rc2 |
460 |
continue; |
c2cba57e8 [XFS] This fix pr... |
461 |
} |
1da177e4c Linux-2.6.12-rc2 |
462 463 464 465 |
/* * Count used inodes as free so we can tell * when the chunk is used up. */ |
262750933 [XFS] Drop unneed... |
466 |
irbp->ir_freecount++; |
1da177e4c Linux-2.6.12-rc2 |
467 468 469 |
/* * Get the inode and fill in a single buffer. |
1da177e4c Linux-2.6.12-rc2 |
470 471 |
*/ ubused = statstruct_size; |
7b6259e7a xfs: remove block... |
472 |
error = formatter(mp, ino, ubufp, ubleft, |
7dce11dba xfs: always use i... |
473 |
&ubused, &fmterror); |
1da177e4c Linux-2.6.12-rc2 |
474 |
if (fmterror == BULKSTAT_RV_NOTHING) { |
cd57e594a [XFS] 971064 Vari... |
475 476 |
if (error && error != ENOENT && error != EINVAL) { |
e132f54ce [XFS] pv 955157, ... |
477 |
ubleft = 0; |
cd57e594a [XFS] 971064 Vari... |
478 479 480 481 |
rval = error; break; } lastino = ino; |
1da177e4c Linux-2.6.12-rc2 |
482 483 484 485 486 487 488 489 490 491 492 493 494 495 |
continue; } if (fmterror == BULKSTAT_RV_GIVEUP) { ubleft = 0; ASSERT(error); rval = error; break; } if (ubufp) ubufp += ubused; ubleft -= ubused; ubelem++; lastino = ino; } |
cd57e594a [XFS] 971064 Vari... |
496 497 |
cond_resched(); |
1da177e4c Linux-2.6.12-rc2 |
498 499 500 501 502 503 504 505 |
} if (bp) xfs_buf_relse(bp); /* * Set up for the next loop iteration. */ |
cd57e594a [XFS] 971064 Vari... |
506 |
if (XFS_BULKSTAT_UBLEFT(ubleft)) { |
1da177e4c Linux-2.6.12-rc2 |
507 508 509 |
if (end_of_ag) { agno++; agino = 0; |
cd57e594a [XFS] 971064 Vari... |
510 511 |
} else agino = XFS_INO_TO_AGINO(mp, lastino); |
1da177e4c Linux-2.6.12-rc2 |
512 513 514 515 516 517 |
} else break; } /* * Done, we're either out of filesystem or space to put the data. */ |
bdfb04301 xfs: replace KM_L... |
518 |
kmem_free_large(irbuf); |
1da177e4c Linux-2.6.12-rc2 |
519 |
*ubcountp = ubelem; |
cd57e594a [XFS] 971064 Vari... |
520 521 522 523 524 |
/* * Found some inodes, return them now and return the error next time. */ if (ubelem) rval = 0; |
1da177e4c Linux-2.6.12-rc2 |
525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 |
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); *done = 1; } else *lastinop = (xfs_ino_t)lastino; return rval; } /* * Return stat information in bulk (by-inode) for the filesystem. * Special case for non-sequential one inode bulkstat. */ int /* error status */ xfs_bulkstat_single( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t *lastinop, /* inode to return */ char __user *buffer, /* buffer with inode stats */ |
c41564b5a [XFS] We really s... |
548 |
int *done) /* 1 if there are more stats to get */ |
1da177e4c Linux-2.6.12-rc2 |
549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 |
{ int count; /* count value for bulkstat call */ int error; /* return value */ xfs_ino_t ino; /* filesystem inode number */ int res; /* result from bs1 */ /* * note that requesting valid inode numbers which are not allocated * to inodes will most likely cause xfs_itobp to generate warning * messages about bad magic numbers. This is ok. The fact that * the inode isn't actually an inode is handled by the * error check below. Done this way to make the usual case faster * at the expense of the error case. */ ino = (xfs_ino_t)*lastinop; |
7b6259e7a xfs: remove block... |
565 |
error = xfs_bulkstat_one(mp, ino, buffer, sizeof(xfs_bstat_t), 0, &res); |
1da177e4c Linux-2.6.12-rc2 |
566 567 568 569 570 571 572 573 |
if (error) { /* * Special case way failed, do it the "long" way * to see if that works. */ (*lastinop)--; count = 1; if (xfs_bulkstat(mp, lastinop, &count, xfs_bulkstat_one, |
7dce11dba xfs: always use i... |
574 |
sizeof(xfs_bstat_t), buffer, done)) |
1da177e4c Linux-2.6.12-rc2 |
575 576 577 578 579 580 581 582 583 584 |
return error; if (count == 0 || (xfs_ino_t)*lastinop != ino) return error == EFSCORRUPTED ? XFS_ERROR(EINVAL) : error; else return 0; } *done = 0; return 0; } |
faa63e958 [XFS] Fix XFS_IOC... |
585 586 587 588 589 590 591 592 593 594 595 596 |
int xfs_inumbers_fmt( void __user *ubuffer, /* buffer to write to */ const xfs_inogrp_t *buffer, /* buffer to read from */ long count, /* # of elements to read */ long *written) /* # of bytes written */ { if (copy_to_user(ubuffer, buffer, count * sizeof(*buffer))) return -EFAULT; *written = count * sizeof(*buffer); return 0; } |
1da177e4c Linux-2.6.12-rc2 |
597 598 599 600 601 602 603 604 |
/* * Return inode number table for the filesystem. */ int /* error status */ xfs_inumbers( xfs_mount_t *mp, /* mount point for filesystem */ xfs_ino_t *lastino, /* last inode returned */ int *count, /* size of buffer/count returned */ |
faa63e958 [XFS] Fix XFS_IOC... |
605 606 |
void __user *ubuffer,/* buffer with inode descriptions */ inumbers_fmt_pf formatter) |
1da177e4c Linux-2.6.12-rc2 |
607 608 609 610 611 612 613 614 615 |
{ xfs_buf_t *agbp; xfs_agino_t agino; xfs_agnumber_t agno; int bcount; xfs_inogrp_t *buffer; int bufidx; xfs_btree_cur_t *cur; int error; |
2e287a731 xfs: improve xfs_... |
616 |
xfs_inobt_rec_incore_t r; |
1da177e4c Linux-2.6.12-rc2 |
617 618 619 620 621 622 623 624 625 626 |
int i; xfs_ino_t ino; int left; int tmp; ino = (xfs_ino_t)*lastino; agno = XFS_INO_TO_AGNO(mp, ino); agino = XFS_INO_TO_AGINO(mp, ino); left = *count; *count = 0; |
e6a4b37f3 [XFS] Remove the ... |
627 |
bcount = MIN(left, (int)(PAGE_SIZE / sizeof(*buffer))); |
1da177e4c Linux-2.6.12-rc2 |
628 629 630 631 632 633 |
buffer = kmem_alloc(bcount * sizeof(*buffer), KM_SLEEP); error = bufidx = 0; cur = NULL; agbp = NULL; while (left > 0 && agno < mp->m_sb.sb_agcount) { if (agbp == NULL) { |
1da177e4c Linux-2.6.12-rc2 |
634 |
error = xfs_ialloc_read_agi(mp, NULL, agno, &agbp); |
1da177e4c Linux-2.6.12-rc2 |
635 636 637 638 639 640 641 642 643 644 645 |
if (error) { /* * If we can't read the AGI of this ag, * then just skip to the next one. */ ASSERT(cur == NULL); agbp = NULL; agno++; agino = 0; continue; } |
561f7d173 [XFS] split up xf... |
646 |
cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno); |
218755052 xfs: rationalize ... |
647 648 |
error = xfs_inobt_lookup(cur, agino, XFS_LOOKUP_GE, &tmp); |
1da177e4c Linux-2.6.12-rc2 |
649 650 651 652 653 654 |
if (error) { xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); cur = NULL; xfs_buf_relse(agbp); agbp = NULL; /* |
59c51591a Fix occurrences o... |
655 |
* Move up the last inode in the current |
1da177e4c Linux-2.6.12-rc2 |
656 657 658 659 660 661 662 |
* chunk. The lookup_ge will always get * us the first inode in the next chunk. */ agino += XFS_INODES_PER_CHUNK - 1; continue; } } |
2e287a731 xfs: improve xfs_... |
663 664 |
error = xfs_inobt_get_rec(cur, &r, &i); if (error || i == 0) { |
1da177e4c Linux-2.6.12-rc2 |
665 666 667 668 669 670 671 672 |
xfs_buf_relse(agbp); agbp = NULL; xfs_btree_del_cursor(cur, XFS_BTREE_NOERROR); cur = NULL; agno++; agino = 0; continue; } |
2e287a731 xfs: improve xfs_... |
673 674 675 676 677 678 |
agino = r.ir_startino + XFS_INODES_PER_CHUNK - 1; buffer[bufidx].xi_startino = XFS_AGINO_TO_INO(mp, agno, r.ir_startino); buffer[bufidx].xi_alloccount = XFS_INODES_PER_CHUNK - r.ir_freecount; buffer[bufidx].xi_allocmask = ~r.ir_free; |
1da177e4c Linux-2.6.12-rc2 |
679 680 681 |
bufidx++; left--; if (bufidx == bcount) { |
faa63e958 [XFS] Fix XFS_IOC... |
682 683 |
long written; if (formatter(ubuffer, buffer, bufidx, &written)) { |
1da177e4c Linux-2.6.12-rc2 |
684 685 686 |
error = XFS_ERROR(EFAULT); break; } |
faa63e958 [XFS] Fix XFS_IOC... |
687 |
ubuffer += written; |
1da177e4c Linux-2.6.12-rc2 |
688 689 690 691 |
*count += bufidx; bufidx = 0; } if (left) { |
637aa50f4 [XFS] implement g... |
692 |
error = xfs_btree_increment(cur, 0, &tmp); |
1da177e4c Linux-2.6.12-rc2 |
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 |
if (error) { xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); cur = NULL; xfs_buf_relse(agbp); agbp = NULL; /* * The agino value has already been bumped. * Just try to skip up to it. */ agino += XFS_INODES_PER_CHUNK; continue; } } } if (!error) { if (bufidx) { |
faa63e958 [XFS] Fix XFS_IOC... |
709 710 |
long written; if (formatter(ubuffer, buffer, bufidx, &written)) |
1da177e4c Linux-2.6.12-rc2 |
711 712 713 714 715 716 |
error = XFS_ERROR(EFAULT); else *count += bufidx; } *lastino = XFS_AGINO_TO_INO(mp, agno, agino); } |
f0e2d93c2 [XFS] Remove unus... |
717 |
kmem_free(buffer); |
1da177e4c Linux-2.6.12-rc2 |
718 719 720 721 722 723 724 |
if (cur) xfs_btree_del_cursor(cur, (error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR)); if (agbp) xfs_buf_relse(agbp); return error; } |