diff options
Diffstat (limited to 'fs/xfs/xfs_itable.c')
-rw-r--r-- | fs/xfs/xfs_itable.c | 102 |
1 files changed, 54 insertions, 48 deletions
diff --git a/fs/xfs/xfs_itable.c b/fs/xfs/xfs_itable.c index cf6754a3c5b3..e19d0a8d5618 100644 --- a/fs/xfs/xfs_itable.c +++ b/fs/xfs/xfs_itable.c | |||
@@ -69,7 +69,7 @@ xfs_bulkstat_one_iget( | |||
69 | } | 69 | } |
70 | 70 | ||
71 | ASSERT(ip != NULL); | 71 | ASSERT(ip != NULL); |
72 | ASSERT(ip->i_blkno != (xfs_daddr_t)0); | 72 | ASSERT(ip->i_imap.im_blkno != 0); |
73 | 73 | ||
74 | dic = &ip->i_d; | 74 | dic = &ip->i_d; |
75 | 75 | ||
@@ -125,13 +125,9 @@ STATIC void | |||
125 | xfs_bulkstat_one_dinode( | 125 | xfs_bulkstat_one_dinode( |
126 | xfs_mount_t *mp, /* mount point for filesystem */ | 126 | xfs_mount_t *mp, /* mount point for filesystem */ |
127 | xfs_ino_t ino, /* inode number to get data for */ | 127 | xfs_ino_t ino, /* inode number to get data for */ |
128 | xfs_dinode_t *dip, /* dinode inode pointer */ | 128 | xfs_dinode_t *dic, /* dinode inode pointer */ |
129 | xfs_bstat_t *buf) /* return buffer */ | 129 | xfs_bstat_t *buf) /* return buffer */ |
130 | { | 130 | { |
131 | xfs_dinode_core_t *dic; /* dinode core info pointer */ | ||
132 | |||
133 | dic = &dip->di_core; | ||
134 | |||
135 | /* | 131 | /* |
136 | * The inode format changed when we moved the link count and | 132 | * The inode format changed when we moved the link count and |
137 | * made it 32 bits long. If this is an old format inode, | 133 | * made it 32 bits long. If this is an old format inode, |
@@ -143,7 +139,7 @@ xfs_bulkstat_one_dinode( | |||
143 | * the new format. We don't change the version number so that we | 139 | * the new format. We don't change the version number so that we |
144 | * can distinguish this from a real new format inode. | 140 | * can distinguish this from a real new format inode. |
145 | */ | 141 | */ |
146 | if (dic->di_version == XFS_DINODE_VERSION_1) { | 142 | if (dic->di_version == 1) { |
147 | buf->bs_nlink = be16_to_cpu(dic->di_onlink); | 143 | buf->bs_nlink = be16_to_cpu(dic->di_onlink); |
148 | buf->bs_projid = 0; | 144 | buf->bs_projid = 0; |
149 | } else { | 145 | } else { |
@@ -162,7 +158,7 @@ xfs_bulkstat_one_dinode( | |||
162 | buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec); | 158 | buf->bs_mtime.tv_nsec = be32_to_cpu(dic->di_mtime.t_nsec); |
163 | buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec); | 159 | buf->bs_ctime.tv_sec = be32_to_cpu(dic->di_ctime.t_sec); |
164 | buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec); | 160 | buf->bs_ctime.tv_nsec = be32_to_cpu(dic->di_ctime.t_nsec); |
165 | buf->bs_xflags = xfs_dic2xflags(dip); | 161 | buf->bs_xflags = xfs_dic2xflags(dic); |
166 | buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog; | 162 | buf->bs_extsize = be32_to_cpu(dic->di_extsize) << mp->m_sb.sb_blocklog; |
167 | buf->bs_extents = be32_to_cpu(dic->di_nextents); | 163 | buf->bs_extents = be32_to_cpu(dic->di_nextents); |
168 | buf->bs_gen = be32_to_cpu(dic->di_gen); | 164 | buf->bs_gen = be32_to_cpu(dic->di_gen); |
@@ -173,7 +169,7 @@ xfs_bulkstat_one_dinode( | |||
173 | 169 | ||
174 | switch (dic->di_format) { | 170 | switch (dic->di_format) { |
175 | case XFS_DINODE_FMT_DEV: | 171 | case XFS_DINODE_FMT_DEV: |
176 | buf->bs_rdev = be32_to_cpu(dip->di_u.di_dev); | 172 | buf->bs_rdev = xfs_dinode_get_rdev(dic); |
177 | buf->bs_blksize = BLKDEV_IOSIZE; | 173 | buf->bs_blksize = BLKDEV_IOSIZE; |
178 | buf->bs_blocks = 0; | 174 | buf->bs_blocks = 0; |
179 | break; | 175 | break; |
@@ -192,27 +188,34 @@ xfs_bulkstat_one_dinode( | |||
192 | } | 188 | } |
193 | } | 189 | } |
194 | 190 | ||
191 | /* Return 0 on success or positive error */ | ||
195 | STATIC int | 192 | STATIC int |
196 | xfs_bulkstat_one_fmt( | 193 | xfs_bulkstat_one_fmt( |
197 | void __user *ubuffer, | 194 | void __user *ubuffer, |
195 | int ubsize, | ||
196 | int *ubused, | ||
198 | const xfs_bstat_t *buffer) | 197 | const xfs_bstat_t *buffer) |
199 | { | 198 | { |
199 | if (ubsize < sizeof(*buffer)) | ||
200 | return XFS_ERROR(ENOMEM); | ||
200 | if (copy_to_user(ubuffer, buffer, sizeof(*buffer))) | 201 | if (copy_to_user(ubuffer, buffer, sizeof(*buffer))) |
201 | return -EFAULT; | 202 | return XFS_ERROR(EFAULT); |
202 | return sizeof(*buffer); | 203 | if (ubused) |
204 | *ubused = sizeof(*buffer); | ||
205 | return 0; | ||
203 | } | 206 | } |
204 | 207 | ||
205 | /* | 208 | /* |
206 | * Return stat information for one inode. | 209 | * Return stat information for one inode. |
207 | * Return 0 if ok, else errno. | 210 | * Return 0 if ok, else errno. |
208 | */ | 211 | */ |
209 | int /* error status */ | 212 | int /* error status */ |
210 | xfs_bulkstat_one( | 213 | xfs_bulkstat_one_int( |
211 | xfs_mount_t *mp, /* mount point for filesystem */ | 214 | xfs_mount_t *mp, /* mount point for filesystem */ |
212 | xfs_ino_t ino, /* inode number to get data for */ | 215 | xfs_ino_t ino, /* inode number to get data for */ |
213 | void __user *buffer, /* buffer to place output in */ | 216 | void __user *buffer, /* buffer to place output in */ |
214 | int ubsize, /* size of buffer */ | 217 | int ubsize, /* size of buffer */ |
215 | void *private_data, /* my private data */ | 218 | bulkstat_one_fmt_pf formatter, /* formatter, copy to user */ |
216 | xfs_daddr_t bno, /* starting bno of inode cluster */ | 219 | xfs_daddr_t bno, /* starting bno of inode cluster */ |
217 | int *ubused, /* bytes used by me */ | 220 | int *ubused, /* bytes used by me */ |
218 | void *dibuff, /* on-disk inode buffer */ | 221 | void *dibuff, /* on-disk inode buffer */ |
@@ -221,15 +224,12 @@ xfs_bulkstat_one( | |||
221 | xfs_bstat_t *buf; /* return buffer */ | 224 | xfs_bstat_t *buf; /* return buffer */ |
222 | int error = 0; /* error value */ | 225 | int error = 0; /* error value */ |
223 | xfs_dinode_t *dip; /* dinode inode pointer */ | 226 | xfs_dinode_t *dip; /* dinode inode pointer */ |
224 | bulkstat_one_fmt_pf formatter = private_data ? : xfs_bulkstat_one_fmt; | ||
225 | 227 | ||
226 | dip = (xfs_dinode_t *)dibuff; | 228 | dip = (xfs_dinode_t *)dibuff; |
227 | *stat = BULKSTAT_RV_NOTHING; | 229 | *stat = BULKSTAT_RV_NOTHING; |
228 | 230 | ||
229 | if (!buffer || xfs_internal_inum(mp, ino)) | 231 | if (!buffer || xfs_internal_inum(mp, ino)) |
230 | return XFS_ERROR(EINVAL); | 232 | return XFS_ERROR(EINVAL); |
231 | if (ubsize < sizeof(*buf)) | ||
232 | return XFS_ERROR(ENOMEM); | ||
233 | 233 | ||
234 | buf = kmem_alloc(sizeof(*buf), KM_SLEEP); | 234 | buf = kmem_alloc(sizeof(*buf), KM_SLEEP); |
235 | 235 | ||
@@ -244,21 +244,34 @@ xfs_bulkstat_one( | |||
244 | xfs_bulkstat_one_dinode(mp, ino, dip, buf); | 244 | xfs_bulkstat_one_dinode(mp, ino, dip, buf); |
245 | } | 245 | } |
246 | 246 | ||
247 | error = formatter(buffer, buf); | 247 | error = formatter(buffer, ubsize, ubused, buf); |
248 | if (error < 0) { | 248 | if (error) |
249 | error = EFAULT; | ||
250 | goto out_free; | 249 | goto out_free; |
251 | } | ||
252 | 250 | ||
253 | *stat = BULKSTAT_RV_DIDONE; | 251 | *stat = BULKSTAT_RV_DIDONE; |
254 | if (ubused) | ||
255 | *ubused = error; | ||
256 | 252 | ||
257 | out_free: | 253 | out_free: |
258 | kmem_free(buf); | 254 | kmem_free(buf); |
259 | return error; | 255 | return error; |
260 | } | 256 | } |
261 | 257 | ||
258 | int | ||
259 | xfs_bulkstat_one( | ||
260 | xfs_mount_t *mp, /* mount point for filesystem */ | ||
261 | xfs_ino_t ino, /* inode number to get data for */ | ||
262 | void __user *buffer, /* buffer to place output in */ | ||
263 | int ubsize, /* size of buffer */ | ||
264 | void *private_data, /* my private data */ | ||
265 | xfs_daddr_t bno, /* starting bno of inode cluster */ | ||
266 | int *ubused, /* bytes used by me */ | ||
267 | void *dibuff, /* on-disk inode buffer */ | ||
268 | int *stat) /* BULKSTAT_RV_... */ | ||
269 | { | ||
270 | return xfs_bulkstat_one_int(mp, ino, buffer, ubsize, | ||
271 | xfs_bulkstat_one_fmt, bno, | ||
272 | ubused, dibuff, stat); | ||
273 | } | ||
274 | |||
262 | /* | 275 | /* |
263 | * Test to see whether we can use the ondisk inode directly, based | 276 | * Test to see whether we can use the ondisk inode directly, based |
264 | * on the given bulkstat flags, filling in dipp accordingly. | 277 | * on the given bulkstat flags, filling in dipp accordingly. |
@@ -287,19 +300,19 @@ xfs_bulkstat_use_dinode( | |||
287 | * to disk yet. This is a temporary hack that would require a proper | 300 | * to disk yet. This is a temporary hack that would require a proper |
288 | * fix in the future. | 301 | * fix in the future. |
289 | */ | 302 | */ |
290 | if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC || | 303 | if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC || |
291 | !XFS_DINODE_GOOD_VERSION(dip->di_core.di_version) || | 304 | !XFS_DINODE_GOOD_VERSION(dip->di_version) || |
292 | !dip->di_core.di_mode) | 305 | !dip->di_mode) |
293 | return 0; | 306 | return 0; |
294 | if (flags & BULKSTAT_FG_QUICK) { | 307 | if (flags & BULKSTAT_FG_QUICK) { |
295 | *dipp = dip; | 308 | *dipp = dip; |
296 | return 1; | 309 | return 1; |
297 | } | 310 | } |
298 | /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ | 311 | /* BULKSTAT_FG_INLINE: if attr fork is local, or not there, use it */ |
299 | aformat = dip->di_core.di_aformat; | 312 | aformat = dip->di_aformat; |
300 | if ((XFS_DFORK_Q(dip) == 0) || | 313 | if ((XFS_DFORK_Q(dip) == 0) || |
301 | (aformat == XFS_DINODE_FMT_LOCAL) || | 314 | (aformat == XFS_DINODE_FMT_LOCAL) || |
302 | (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_core.di_anextents)) { | 315 | (aformat == XFS_DINODE_FMT_EXTENTS && !dip->di_anextents)) { |
303 | *dipp = dip; | 316 | *dipp = dip; |
304 | return 1; | 317 | return 1; |
305 | } | 318 | } |
@@ -359,7 +372,6 @@ xfs_bulkstat( | |||
359 | int ubused; /* bytes used by formatter */ | 372 | int ubused; /* bytes used by formatter */ |
360 | xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */ | 373 | xfs_buf_t *bp; /* ptr to on-disk inode cluster buf */ |
361 | xfs_dinode_t *dip; /* ptr into bp for specific inode */ | 374 | xfs_dinode_t *dip; /* ptr into bp for specific inode */ |
362 | xfs_inode_t *ip; /* ptr to in-core inode struct */ | ||
363 | 375 | ||
364 | /* | 376 | /* |
365 | * Get the last inode value, see if there's nothing to do. | 377 | * Get the last inode value, see if there's nothing to do. |
@@ -416,8 +428,7 @@ xfs_bulkstat( | |||
416 | /* | 428 | /* |
417 | * Allocate and initialize a btree cursor for ialloc btree. | 429 | * Allocate and initialize a btree cursor for ialloc btree. |
418 | */ | 430 | */ |
419 | cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, XFS_BTNUM_INO, | 431 | cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno); |
420 | (xfs_inode_t *)0, 0); | ||
421 | irbp = irbuf; | 432 | irbp = irbuf; |
422 | irbufend = irbuf + nirbuf; | 433 | irbufend = irbuf + nirbuf; |
423 | end_of_ag = 0; | 434 | end_of_ag = 0; |
@@ -472,7 +483,7 @@ xfs_bulkstat( | |||
472 | * In any case, increment to the next record. | 483 | * In any case, increment to the next record. |
473 | */ | 484 | */ |
474 | if (!error) | 485 | if (!error) |
475 | error = xfs_inobt_increment(cur, 0, &tmp); | 486 | error = xfs_btree_increment(cur, 0, &tmp); |
476 | } else { | 487 | } else { |
477 | /* | 488 | /* |
478 | * Start of ag. Lookup the first inode chunk. | 489 | * Start of ag. Lookup the first inode chunk. |
@@ -539,7 +550,7 @@ xfs_bulkstat( | |||
539 | * Set agino to after this chunk and bump the cursor. | 550 | * Set agino to after this chunk and bump the cursor. |
540 | */ | 551 | */ |
541 | agino = gino + XFS_INODES_PER_CHUNK; | 552 | agino = gino + XFS_INODES_PER_CHUNK; |
542 | error = xfs_inobt_increment(cur, 0, &tmp); | 553 | error = xfs_btree_increment(cur, 0, &tmp); |
543 | cond_resched(); | 554 | cond_resched(); |
544 | } | 555 | } |
545 | /* | 556 | /* |
@@ -586,6 +597,8 @@ xfs_bulkstat( | |||
586 | 597 | ||
587 | if (flags & (BULKSTAT_FG_QUICK | | 598 | if (flags & (BULKSTAT_FG_QUICK | |
588 | BULKSTAT_FG_INLINE)) { | 599 | BULKSTAT_FG_INLINE)) { |
600 | int offset; | ||
601 | |||
589 | ino = XFS_AGINO_TO_INO(mp, agno, | 602 | ino = XFS_AGINO_TO_INO(mp, agno, |
590 | agino); | 603 | agino); |
591 | bno = XFS_AGB_TO_DADDR(mp, agno, | 604 | bno = XFS_AGB_TO_DADDR(mp, agno, |
@@ -594,21 +607,15 @@ xfs_bulkstat( | |||
594 | /* | 607 | /* |
595 | * Get the inode cluster buffer | 608 | * Get the inode cluster buffer |
596 | */ | 609 | */ |
597 | ASSERT(xfs_inode_zone != NULL); | ||
598 | ip = kmem_zone_zalloc(xfs_inode_zone, | ||
599 | KM_SLEEP); | ||
600 | ip->i_ino = ino; | ||
601 | ip->i_mount = mp; | ||
602 | spin_lock_init(&ip->i_flags_lock); | ||
603 | if (bp) | 610 | if (bp) |
604 | xfs_buf_relse(bp); | 611 | xfs_buf_relse(bp); |
605 | error = xfs_itobp(mp, NULL, ip, | 612 | |
606 | &dip, &bp, bno, | 613 | error = xfs_inotobp(mp, NULL, ino, &dip, |
607 | XFS_IMAP_BULKSTAT, | 614 | &bp, &offset, |
608 | XFS_BUF_LOCK); | 615 | XFS_IGET_BULKSTAT); |
616 | |||
609 | if (!error) | 617 | if (!error) |
610 | clustidx = ip->i_boffset / mp->m_sb.sb_inodesize; | 618 | clustidx = offset / mp->m_sb.sb_inodesize; |
611 | kmem_zone_free(xfs_inode_zone, ip); | ||
612 | if (XFS_TEST_ERROR(error != 0, | 619 | if (XFS_TEST_ERROR(error != 0, |
613 | mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK, | 620 | mp, XFS_ERRTAG_BULKSTAT_READ_CHUNK, |
614 | XFS_RANDOM_BULKSTAT_READ_CHUNK)) { | 621 | XFS_RANDOM_BULKSTAT_READ_CHUNK)) { |
@@ -842,8 +849,7 @@ xfs_inumbers( | |||
842 | agino = 0; | 849 | agino = 0; |
843 | continue; | 850 | continue; |
844 | } | 851 | } |
845 | cur = xfs_btree_init_cursor(mp, NULL, agbp, agno, | 852 | cur = xfs_inobt_init_cursor(mp, NULL, agbp, agno); |
846 | XFS_BTNUM_INO, (xfs_inode_t *)0, 0); | ||
847 | error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp); | 853 | error = xfs_inobt_lookup_ge(cur, agino, 0, 0, &tmp); |
848 | if (error) { | 854 | if (error) { |
849 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | 855 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |
@@ -887,7 +893,7 @@ xfs_inumbers( | |||
887 | bufidx = 0; | 893 | bufidx = 0; |
888 | } | 894 | } |
889 | if (left) { | 895 | if (left) { |
890 | error = xfs_inobt_increment(cur, 0, &tmp); | 896 | error = xfs_btree_increment(cur, 0, &tmp); |
891 | if (error) { | 897 | if (error) { |
892 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); | 898 | xfs_btree_del_cursor(cur, XFS_BTREE_ERROR); |
893 | cur = NULL; | 899 | cur = NULL; |