diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 587 |
1 files changed, 160 insertions, 427 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index a391b955df01..5a5e035e5d38 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -23,7 +23,6 @@ | |||
23 | #include "xfs_bit.h" | 23 | #include "xfs_bit.h" |
24 | #include "xfs_log.h" | 24 | #include "xfs_log.h" |
25 | #include "xfs_inum.h" | 25 | #include "xfs_inum.h" |
26 | #include "xfs_imap.h" | ||
27 | #include "xfs_trans.h" | 26 | #include "xfs_trans.h" |
28 | #include "xfs_trans_priv.h" | 27 | #include "xfs_trans_priv.h" |
29 | #include "xfs_sb.h" | 28 | #include "xfs_sb.h" |
@@ -41,6 +40,7 @@ | |||
41 | #include "xfs_buf_item.h" | 40 | #include "xfs_buf_item.h" |
42 | #include "xfs_inode_item.h" | 41 | #include "xfs_inode_item.h" |
43 | #include "xfs_btree.h" | 42 | #include "xfs_btree.h" |
43 | #include "xfs_btree_trace.h" | ||
44 | #include "xfs_alloc.h" | 44 | #include "xfs_alloc.h" |
45 | #include "xfs_ialloc.h" | 45 | #include "xfs_ialloc.h" |
46 | #include "xfs_bmap.h" | 46 | #include "xfs_bmap.h" |
@@ -133,10 +133,10 @@ STATIC int | |||
133 | xfs_imap_to_bp( | 133 | xfs_imap_to_bp( |
134 | xfs_mount_t *mp, | 134 | xfs_mount_t *mp, |
135 | xfs_trans_t *tp, | 135 | xfs_trans_t *tp, |
136 | xfs_imap_t *imap, | 136 | struct xfs_imap *imap, |
137 | xfs_buf_t **bpp, | 137 | xfs_buf_t **bpp, |
138 | uint buf_flags, | 138 | uint buf_flags, |
139 | uint imap_flags) | 139 | uint iget_flags) |
140 | { | 140 | { |
141 | int error; | 141 | int error; |
142 | int i; | 142 | int i; |
@@ -173,12 +173,12 @@ xfs_imap_to_bp( | |||
173 | 173 | ||
174 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, | 174 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, |
175 | (i << mp->m_sb.sb_inodelog)); | 175 | (i << mp->m_sb.sb_inodelog)); |
176 | di_ok = be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC && | 176 | di_ok = be16_to_cpu(dip->di_magic) == XFS_DINODE_MAGIC && |
177 | XFS_DINODE_GOOD_VERSION(dip->di_core.di_version); | 177 | XFS_DINODE_GOOD_VERSION(dip->di_version); |
178 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, | 178 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, |
179 | XFS_ERRTAG_ITOBP_INOTOBP, | 179 | XFS_ERRTAG_ITOBP_INOTOBP, |
180 | XFS_RANDOM_ITOBP_INOTOBP))) { | 180 | XFS_RANDOM_ITOBP_INOTOBP))) { |
181 | if (imap_flags & XFS_IMAP_BULKSTAT) { | 181 | if (iget_flags & XFS_IGET_BULKSTAT) { |
182 | xfs_trans_brelse(tp, bp); | 182 | xfs_trans_brelse(tp, bp); |
183 | return XFS_ERROR(EINVAL); | 183 | return XFS_ERROR(EINVAL); |
184 | } | 184 | } |
@@ -190,7 +190,7 @@ xfs_imap_to_bp( | |||
190 | "daddr %lld #%d (magic=%x)", | 190 | "daddr %lld #%d (magic=%x)", |
191 | XFS_BUFTARG_NAME(mp->m_ddev_targp), | 191 | XFS_BUFTARG_NAME(mp->m_ddev_targp), |
192 | (unsigned long long)imap->im_blkno, i, | 192 | (unsigned long long)imap->im_blkno, i, |
193 | be16_to_cpu(dip->di_core.di_magic)); | 193 | be16_to_cpu(dip->di_magic)); |
194 | #endif | 194 | #endif |
195 | xfs_trans_brelse(tp, bp); | 195 | xfs_trans_brelse(tp, bp); |
196 | return XFS_ERROR(EFSCORRUPTED); | 196 | return XFS_ERROR(EFSCORRUPTED); |
@@ -221,25 +221,26 @@ xfs_imap_to_bp( | |||
221 | * Use xfs_imap() to determine the size and location of the | 221 | * Use xfs_imap() to determine the size and location of the |
222 | * buffer to read from disk. | 222 | * buffer to read from disk. |
223 | */ | 223 | */ |
224 | STATIC int | 224 | int |
225 | xfs_inotobp( | 225 | xfs_inotobp( |
226 | xfs_mount_t *mp, | 226 | xfs_mount_t *mp, |
227 | xfs_trans_t *tp, | 227 | xfs_trans_t *tp, |
228 | xfs_ino_t ino, | 228 | xfs_ino_t ino, |
229 | xfs_dinode_t **dipp, | 229 | xfs_dinode_t **dipp, |
230 | xfs_buf_t **bpp, | 230 | xfs_buf_t **bpp, |
231 | int *offset) | 231 | int *offset, |
232 | uint imap_flags) | ||
232 | { | 233 | { |
233 | xfs_imap_t imap; | 234 | struct xfs_imap imap; |
234 | xfs_buf_t *bp; | 235 | xfs_buf_t *bp; |
235 | int error; | 236 | int error; |
236 | 237 | ||
237 | imap.im_blkno = 0; | 238 | imap.im_blkno = 0; |
238 | error = xfs_imap(mp, tp, ino, &imap, XFS_IMAP_LOOKUP); | 239 | error = xfs_imap(mp, tp, ino, &imap, imap_flags); |
239 | if (error) | 240 | if (error) |
240 | return error; | 241 | return error; |
241 | 242 | ||
242 | error = xfs_imap_to_bp(mp, tp, &imap, &bp, XFS_BUF_LOCK, 0); | 243 | error = xfs_imap_to_bp(mp, tp, &imap, &bp, XFS_BUF_LOCK, imap_flags); |
243 | if (error) | 244 | if (error) |
244 | return error; | 245 | return error; |
245 | 246 | ||
@@ -260,15 +261,11 @@ xfs_inotobp( | |||
260 | * If a non-zero error is returned, then the contents of bpp and | 261 | * If a non-zero error is returned, then the contents of bpp and |
261 | * dipp are undefined. | 262 | * dipp are undefined. |
262 | * | 263 | * |
263 | * If the inode is new and has not yet been initialized, use xfs_imap() | 264 | * The inode is expected to already been mapped to its buffer and read |
264 | * to determine the size and location of the buffer to read from disk. | 265 | * in once, thus we can use the mapping information stored in the inode |
265 | * If the inode has already been mapped to its buffer and read in once, | 266 | * rather than calling xfs_imap(). This allows us to avoid the overhead |
266 | * then use the mapping information stored in the inode rather than | 267 | * of looking at the inode btree for small block file systems |
267 | * calling xfs_imap(). This allows us to avoid the overhead of looking | 268 | * (see xfs_imap()). |
268 | * at the inode btree for small block file systems (see xfs_dilocate()). | ||
269 | * We can tell whether the inode has been mapped in before by comparing | ||
270 | * its disk block address to 0. Only uninitialized inodes will have | ||
271 | * 0 for the disk block address. | ||
272 | */ | 269 | */ |
273 | int | 270 | int |
274 | xfs_itobp( | 271 | xfs_itobp( |
@@ -277,40 +274,14 @@ xfs_itobp( | |||
277 | xfs_inode_t *ip, | 274 | xfs_inode_t *ip, |
278 | xfs_dinode_t **dipp, | 275 | xfs_dinode_t **dipp, |
279 | xfs_buf_t **bpp, | 276 | xfs_buf_t **bpp, |
280 | xfs_daddr_t bno, | ||
281 | uint imap_flags, | ||
282 | uint buf_flags) | 277 | uint buf_flags) |
283 | { | 278 | { |
284 | xfs_imap_t imap; | ||
285 | xfs_buf_t *bp; | 279 | xfs_buf_t *bp; |
286 | int error; | 280 | int error; |
287 | 281 | ||
288 | if (ip->i_blkno == (xfs_daddr_t)0) { | 282 | ASSERT(ip->i_imap.im_blkno != 0); |
289 | imap.im_blkno = bno; | ||
290 | error = xfs_imap(mp, tp, ip->i_ino, &imap, | ||
291 | XFS_IMAP_LOOKUP | imap_flags); | ||
292 | if (error) | ||
293 | return error; | ||
294 | 283 | ||
295 | /* | 284 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, buf_flags, 0); |
296 | * Fill in the fields in the inode that will be used to | ||
297 | * map the inode to its buffer from now on. | ||
298 | */ | ||
299 | ip->i_blkno = imap.im_blkno; | ||
300 | ip->i_len = imap.im_len; | ||
301 | ip->i_boffset = imap.im_boffset; | ||
302 | } else { | ||
303 | /* | ||
304 | * We've already mapped the inode once, so just use the | ||
305 | * mapping that we saved the first time. | ||
306 | */ | ||
307 | imap.im_blkno = ip->i_blkno; | ||
308 | imap.im_len = ip->i_len; | ||
309 | imap.im_boffset = ip->i_boffset; | ||
310 | } | ||
311 | ASSERT(bno == 0 || bno == imap.im_blkno); | ||
312 | |||
313 | error = xfs_imap_to_bp(mp, tp, &imap, &bp, buf_flags, imap_flags); | ||
314 | if (error) | 285 | if (error) |
315 | return error; | 286 | return error; |
316 | 287 | ||
@@ -321,7 +292,7 @@ xfs_itobp( | |||
321 | return EAGAIN; | 292 | return EAGAIN; |
322 | } | 293 | } |
323 | 294 | ||
324 | *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, imap.im_boffset); | 295 | *dipp = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); |
325 | *bpp = bp; | 296 | *bpp = bp; |
326 | return 0; | 297 | return 0; |
327 | } | 298 | } |
@@ -348,26 +319,26 @@ xfs_iformat( | |||
348 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | 319 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); |
349 | error = 0; | 320 | error = 0; |
350 | 321 | ||
351 | if (unlikely(be32_to_cpu(dip->di_core.di_nextents) + | 322 | if (unlikely(be32_to_cpu(dip->di_nextents) + |
352 | be16_to_cpu(dip->di_core.di_anextents) > | 323 | be16_to_cpu(dip->di_anextents) > |
353 | be64_to_cpu(dip->di_core.di_nblocks))) { | 324 | be64_to_cpu(dip->di_nblocks))) { |
354 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 325 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
355 | "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", | 326 | "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", |
356 | (unsigned long long)ip->i_ino, | 327 | (unsigned long long)ip->i_ino, |
357 | (int)(be32_to_cpu(dip->di_core.di_nextents) + | 328 | (int)(be32_to_cpu(dip->di_nextents) + |
358 | be16_to_cpu(dip->di_core.di_anextents)), | 329 | be16_to_cpu(dip->di_anextents)), |
359 | (unsigned long long) | 330 | (unsigned long long) |
360 | be64_to_cpu(dip->di_core.di_nblocks)); | 331 | be64_to_cpu(dip->di_nblocks)); |
361 | XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, | 332 | XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, |
362 | ip->i_mount, dip); | 333 | ip->i_mount, dip); |
363 | return XFS_ERROR(EFSCORRUPTED); | 334 | return XFS_ERROR(EFSCORRUPTED); |
364 | } | 335 | } |
365 | 336 | ||
366 | if (unlikely(dip->di_core.di_forkoff > ip->i_mount->m_sb.sb_inodesize)) { | 337 | if (unlikely(dip->di_forkoff > ip->i_mount->m_sb.sb_inodesize)) { |
367 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 338 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
368 | "corrupt dinode %Lu, forkoff = 0x%x.", | 339 | "corrupt dinode %Lu, forkoff = 0x%x.", |
369 | (unsigned long long)ip->i_ino, | 340 | (unsigned long long)ip->i_ino, |
370 | dip->di_core.di_forkoff); | 341 | dip->di_forkoff); |
371 | XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, | 342 | XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, |
372 | ip->i_mount, dip); | 343 | ip->i_mount, dip); |
373 | return XFS_ERROR(EFSCORRUPTED); | 344 | return XFS_ERROR(EFSCORRUPTED); |
@@ -378,25 +349,25 @@ xfs_iformat( | |||
378 | case S_IFCHR: | 349 | case S_IFCHR: |
379 | case S_IFBLK: | 350 | case S_IFBLK: |
380 | case S_IFSOCK: | 351 | case S_IFSOCK: |
381 | if (unlikely(dip->di_core.di_format != XFS_DINODE_FMT_DEV)) { | 352 | if (unlikely(dip->di_format != XFS_DINODE_FMT_DEV)) { |
382 | XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, | 353 | XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, |
383 | ip->i_mount, dip); | 354 | ip->i_mount, dip); |
384 | return XFS_ERROR(EFSCORRUPTED); | 355 | return XFS_ERROR(EFSCORRUPTED); |
385 | } | 356 | } |
386 | ip->i_d.di_size = 0; | 357 | ip->i_d.di_size = 0; |
387 | ip->i_size = 0; | 358 | ip->i_size = 0; |
388 | ip->i_df.if_u2.if_rdev = be32_to_cpu(dip->di_u.di_dev); | 359 | ip->i_df.if_u2.if_rdev = xfs_dinode_get_rdev(dip); |
389 | break; | 360 | break; |
390 | 361 | ||
391 | case S_IFREG: | 362 | case S_IFREG: |
392 | case S_IFLNK: | 363 | case S_IFLNK: |
393 | case S_IFDIR: | 364 | case S_IFDIR: |
394 | switch (dip->di_core.di_format) { | 365 | switch (dip->di_format) { |
395 | case XFS_DINODE_FMT_LOCAL: | 366 | case XFS_DINODE_FMT_LOCAL: |
396 | /* | 367 | /* |
397 | * no local regular files yet | 368 | * no local regular files yet |
398 | */ | 369 | */ |
399 | if (unlikely((be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFREG)) { | 370 | if (unlikely((be16_to_cpu(dip->di_mode) & S_IFMT) == S_IFREG)) { |
400 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 371 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
401 | "corrupt inode %Lu " | 372 | "corrupt inode %Lu " |
402 | "(local format for regular file).", | 373 | "(local format for regular file).", |
@@ -407,7 +378,7 @@ xfs_iformat( | |||
407 | return XFS_ERROR(EFSCORRUPTED); | 378 | return XFS_ERROR(EFSCORRUPTED); |
408 | } | 379 | } |
409 | 380 | ||
410 | di_size = be64_to_cpu(dip->di_core.di_size); | 381 | di_size = be64_to_cpu(dip->di_size); |
411 | if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { | 382 | if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { |
412 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 383 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
413 | "corrupt inode %Lu " | 384 | "corrupt inode %Lu " |
@@ -449,7 +420,7 @@ xfs_iformat( | |||
449 | ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); | 420 | ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); |
450 | ip->i_afp->if_ext_max = | 421 | ip->i_afp->if_ext_max = |
451 | XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | 422 | XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); |
452 | switch (dip->di_core.di_aformat) { | 423 | switch (dip->di_aformat) { |
453 | case XFS_DINODE_FMT_LOCAL: | 424 | case XFS_DINODE_FMT_LOCAL: |
454 | atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); | 425 | atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); |
455 | size = be16_to_cpu(atp->hdr.totsize); | 426 | size = be16_to_cpu(atp->hdr.totsize); |
@@ -621,7 +592,7 @@ xfs_iformat_btree( | |||
621 | ifp = XFS_IFORK_PTR(ip, whichfork); | 592 | ifp = XFS_IFORK_PTR(ip, whichfork); |
622 | dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); | 593 | dfp = (xfs_bmdr_block_t *)XFS_DFORK_PTR(dip, whichfork); |
623 | size = XFS_BMAP_BROOT_SPACE(dfp); | 594 | size = XFS_BMAP_BROOT_SPACE(dfp); |
624 | nrecs = XFS_BMAP_BROOT_NUMRECS(dfp); | 595 | nrecs = be16_to_cpu(dfp->bb_numrecs); |
625 | 596 | ||
626 | /* | 597 | /* |
627 | * blow out if -- fork has less extents than can fit in | 598 | * blow out if -- fork has less extents than can fit in |
@@ -649,8 +620,9 @@ xfs_iformat_btree( | |||
649 | * Copy and convert from the on-disk structure | 620 | * Copy and convert from the on-disk structure |
650 | * to the in-memory structure. | 621 | * to the in-memory structure. |
651 | */ | 622 | */ |
652 | xfs_bmdr_to_bmbt(dfp, XFS_DFORK_SIZE(dip, ip->i_mount, whichfork), | 623 | xfs_bmdr_to_bmbt(ip->i_mount, dfp, |
653 | ifp->if_broot, size); | 624 | XFS_DFORK_SIZE(dip, ip->i_mount, whichfork), |
625 | ifp->if_broot, size); | ||
654 | ifp->if_flags &= ~XFS_IFEXTENTS; | 626 | ifp->if_flags &= ~XFS_IFEXTENTS; |
655 | ifp->if_flags |= XFS_IFBROOT; | 627 | ifp->if_flags |= XFS_IFBROOT; |
656 | 628 | ||
@@ -660,7 +632,7 @@ xfs_iformat_btree( | |||
660 | void | 632 | void |
661 | xfs_dinode_from_disk( | 633 | xfs_dinode_from_disk( |
662 | xfs_icdinode_t *to, | 634 | xfs_icdinode_t *to, |
663 | xfs_dinode_core_t *from) | 635 | xfs_dinode_t *from) |
664 | { | 636 | { |
665 | to->di_magic = be16_to_cpu(from->di_magic); | 637 | to->di_magic = be16_to_cpu(from->di_magic); |
666 | to->di_mode = be16_to_cpu(from->di_mode); | 638 | to->di_mode = be16_to_cpu(from->di_mode); |
@@ -694,7 +666,7 @@ xfs_dinode_from_disk( | |||
694 | 666 | ||
695 | void | 667 | void |
696 | xfs_dinode_to_disk( | 668 | xfs_dinode_to_disk( |
697 | xfs_dinode_core_t *to, | 669 | xfs_dinode_t *to, |
698 | xfs_icdinode_t *from) | 670 | xfs_icdinode_t *from) |
699 | { | 671 | { |
700 | to->di_magic = cpu_to_be16(from->di_magic); | 672 | to->di_magic = cpu_to_be16(from->di_magic); |
@@ -781,93 +753,57 @@ uint | |||
781 | xfs_dic2xflags( | 753 | xfs_dic2xflags( |
782 | xfs_dinode_t *dip) | 754 | xfs_dinode_t *dip) |
783 | { | 755 | { |
784 | xfs_dinode_core_t *dic = &dip->di_core; | 756 | return _xfs_dic2xflags(be16_to_cpu(dip->di_flags)) | |
785 | |||
786 | return _xfs_dic2xflags(be16_to_cpu(dic->di_flags)) | | ||
787 | (XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0); | 757 | (XFS_DFORK_Q(dip) ? XFS_XFLAG_HASATTR : 0); |
788 | } | 758 | } |
789 | 759 | ||
790 | /* | 760 | /* |
791 | * Given a mount structure and an inode number, return a pointer | 761 | * Read the disk inode attributes into the in-core inode structure. |
792 | * to a newly allocated in-core inode corresponding to the given | ||
793 | * inode number. | ||
794 | * | ||
795 | * Initialize the inode's attributes and extent pointers if it | ||
796 | * already has them (it will not if the inode has no links). | ||
797 | */ | 762 | */ |
798 | int | 763 | int |
799 | xfs_iread( | 764 | xfs_iread( |
800 | xfs_mount_t *mp, | 765 | xfs_mount_t *mp, |
801 | xfs_trans_t *tp, | 766 | xfs_trans_t *tp, |
802 | xfs_ino_t ino, | 767 | xfs_inode_t *ip, |
803 | xfs_inode_t **ipp, | ||
804 | xfs_daddr_t bno, | 768 | xfs_daddr_t bno, |
805 | uint imap_flags) | 769 | uint iget_flags) |
806 | { | 770 | { |
807 | xfs_buf_t *bp; | 771 | xfs_buf_t *bp; |
808 | xfs_dinode_t *dip; | 772 | xfs_dinode_t *dip; |
809 | xfs_inode_t *ip; | ||
810 | int error; | 773 | int error; |
811 | 774 | ||
812 | ASSERT(xfs_inode_zone != NULL); | ||
813 | |||
814 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); | ||
815 | ip->i_ino = ino; | ||
816 | ip->i_mount = mp; | ||
817 | atomic_set(&ip->i_iocount, 0); | ||
818 | spin_lock_init(&ip->i_flags_lock); | ||
819 | |||
820 | /* | 775 | /* |
821 | * Get pointer's to the on-disk inode and the buffer containing it. | 776 | * Fill in the location information in the in-core inode. |
822 | * If the inode number refers to a block outside the file system | ||
823 | * then xfs_itobp() will return NULL. In this case we should | ||
824 | * return NULL as well. Set i_blkno to 0 so that xfs_itobp() will | ||
825 | * know that this is a new incore inode. | ||
826 | */ | 777 | */ |
827 | error = xfs_itobp(mp, tp, ip, &dip, &bp, bno, imap_flags, XFS_BUF_LOCK); | 778 | ip->i_imap.im_blkno = bno; |
828 | if (error) { | 779 | error = xfs_imap(mp, tp, ip->i_ino, &ip->i_imap, iget_flags); |
829 | kmem_zone_free(xfs_inode_zone, ip); | 780 | if (error) |
830 | return error; | 781 | return error; |
831 | } | 782 | ASSERT(bno == 0 || bno == ip->i_imap.im_blkno); |
832 | 783 | ||
833 | /* | 784 | /* |
834 | * Initialize inode's trace buffers. | 785 | * Get pointers to the on-disk inode and the buffer containing it. |
835 | * Do this before xfs_iformat in case it adds entries. | ||
836 | */ | 786 | */ |
837 | #ifdef XFS_INODE_TRACE | 787 | error = xfs_imap_to_bp(mp, tp, &ip->i_imap, &bp, |
838 | ip->i_trace = ktrace_alloc(INODE_TRACE_SIZE, KM_NOFS); | 788 | XFS_BUF_LOCK, iget_flags); |
839 | #endif | 789 | if (error) |
840 | #ifdef XFS_BMAP_TRACE | 790 | return error; |
841 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_NOFS); | 791 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); |
842 | #endif | ||
843 | #ifdef XFS_BMBT_TRACE | ||
844 | ip->i_btrace = ktrace_alloc(XFS_BMBT_KTRACE_SIZE, KM_NOFS); | ||
845 | #endif | ||
846 | #ifdef XFS_RW_TRACE | ||
847 | ip->i_rwtrace = ktrace_alloc(XFS_RW_KTRACE_SIZE, KM_NOFS); | ||
848 | #endif | ||
849 | #ifdef XFS_ILOCK_TRACE | ||
850 | ip->i_lock_trace = ktrace_alloc(XFS_ILOCK_KTRACE_SIZE, KM_NOFS); | ||
851 | #endif | ||
852 | #ifdef XFS_DIR2_TRACE | ||
853 | ip->i_dir_trace = ktrace_alloc(XFS_DIR2_KTRACE_SIZE, KM_NOFS); | ||
854 | #endif | ||
855 | 792 | ||
856 | /* | 793 | /* |
857 | * If we got something that isn't an inode it means someone | 794 | * If we got something that isn't an inode it means someone |
858 | * (nfs or dmi) has a stale handle. | 795 | * (nfs or dmi) has a stale handle. |
859 | */ | 796 | */ |
860 | if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) { | 797 | if (be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC) { |
861 | kmem_zone_free(xfs_inode_zone, ip); | ||
862 | xfs_trans_brelse(tp, bp); | ||
863 | #ifdef DEBUG | 798 | #ifdef DEBUG |
864 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " | 799 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " |
865 | "dip->di_core.di_magic (0x%x) != " | 800 | "dip->di_magic (0x%x) != " |
866 | "XFS_DINODE_MAGIC (0x%x)", | 801 | "XFS_DINODE_MAGIC (0x%x)", |
867 | be16_to_cpu(dip->di_core.di_magic), | 802 | be16_to_cpu(dip->di_magic), |
868 | XFS_DINODE_MAGIC); | 803 | XFS_DINODE_MAGIC); |
869 | #endif /* DEBUG */ | 804 | #endif /* DEBUG */ |
870 | return XFS_ERROR(EINVAL); | 805 | error = XFS_ERROR(EINVAL); |
806 | goto out_brelse; | ||
871 | } | 807 | } |
872 | 808 | ||
873 | /* | 809 | /* |
@@ -877,24 +813,22 @@ xfs_iread( | |||
877 | * specific information. | 813 | * specific information. |
878 | * Otherwise, just get the truly permanent information. | 814 | * Otherwise, just get the truly permanent information. |
879 | */ | 815 | */ |
880 | if (dip->di_core.di_mode) { | 816 | if (dip->di_mode) { |
881 | xfs_dinode_from_disk(&ip->i_d, &dip->di_core); | 817 | xfs_dinode_from_disk(&ip->i_d, dip); |
882 | error = xfs_iformat(ip, dip); | 818 | error = xfs_iformat(ip, dip); |
883 | if (error) { | 819 | if (error) { |
884 | kmem_zone_free(xfs_inode_zone, ip); | ||
885 | xfs_trans_brelse(tp, bp); | ||
886 | #ifdef DEBUG | 820 | #ifdef DEBUG |
887 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " | 821 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " |
888 | "xfs_iformat() returned error %d", | 822 | "xfs_iformat() returned error %d", |
889 | error); | 823 | error); |
890 | #endif /* DEBUG */ | 824 | #endif /* DEBUG */ |
891 | return error; | 825 | goto out_brelse; |
892 | } | 826 | } |
893 | } else { | 827 | } else { |
894 | ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic); | 828 | ip->i_d.di_magic = be16_to_cpu(dip->di_magic); |
895 | ip->i_d.di_version = dip->di_core.di_version; | 829 | ip->i_d.di_version = dip->di_version; |
896 | ip->i_d.di_gen = be32_to_cpu(dip->di_core.di_gen); | 830 | ip->i_d.di_gen = be32_to_cpu(dip->di_gen); |
897 | ip->i_d.di_flushiter = be16_to_cpu(dip->di_core.di_flushiter); | 831 | ip->i_d.di_flushiter = be16_to_cpu(dip->di_flushiter); |
898 | /* | 832 | /* |
899 | * Make sure to pull in the mode here as well in | 833 | * Make sure to pull in the mode here as well in |
900 | * case the inode is released without being used. | 834 | * case the inode is released without being used. |
@@ -911,8 +845,6 @@ xfs_iread( | |||
911 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | 845 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); |
912 | } | 846 | } |
913 | 847 | ||
914 | INIT_LIST_HEAD(&ip->i_reclaim); | ||
915 | |||
916 | /* | 848 | /* |
917 | * The inode format changed when we moved the link count and | 849 | * The inode format changed when we moved the link count and |
918 | * made it 32 bits long. If this is an old format inode, | 850 | * made it 32 bits long. If this is an old format inode, |
@@ -924,7 +856,7 @@ xfs_iread( | |||
924 | * the new format. We don't change the version number so that we | 856 | * the new format. We don't change the version number so that we |
925 | * can distinguish this from a real new format inode. | 857 | * can distinguish this from a real new format inode. |
926 | */ | 858 | */ |
927 | if (ip->i_d.di_version == XFS_DINODE_VERSION_1) { | 859 | if (ip->i_d.di_version == 1) { |
928 | ip->i_d.di_nlink = ip->i_d.di_onlink; | 860 | ip->i_d.di_nlink = ip->i_d.di_onlink; |
929 | ip->i_d.di_onlink = 0; | 861 | ip->i_d.di_onlink = 0; |
930 | ip->i_d.di_projid = 0; | 862 | ip->i_d.di_projid = 0; |
@@ -938,7 +870,7 @@ xfs_iread( | |||
938 | * around for a while. This helps to keep recently accessed | 870 | * around for a while. This helps to keep recently accessed |
939 | * meta-data in-core longer. | 871 | * meta-data in-core longer. |
940 | */ | 872 | */ |
941 | XFS_BUF_SET_REF(bp, XFS_INO_REF); | 873 | XFS_BUF_SET_REF(bp, XFS_INO_REF); |
942 | 874 | ||
943 | /* | 875 | /* |
944 | * Use xfs_trans_brelse() to release the buffer containing the | 876 | * Use xfs_trans_brelse() to release the buffer containing the |
@@ -953,9 +885,9 @@ xfs_iread( | |||
953 | * to worry about the inode being changed just because we released | 885 | * to worry about the inode being changed just because we released |
954 | * the buffer. | 886 | * the buffer. |
955 | */ | 887 | */ |
888 | out_brelse: | ||
956 | xfs_trans_brelse(tp, bp); | 889 | xfs_trans_brelse(tp, bp); |
957 | *ipp = ip; | 890 | return error; |
958 | return 0; | ||
959 | } | 891 | } |
960 | 892 | ||
961 | /* | 893 | /* |
@@ -1049,6 +981,7 @@ xfs_ialloc( | |||
1049 | uint flags; | 981 | uint flags; |
1050 | int error; | 982 | int error; |
1051 | timespec_t tv; | 983 | timespec_t tv; |
984 | int filestreams = 0; | ||
1052 | 985 | ||
1053 | /* | 986 | /* |
1054 | * Call the space management code to pick | 987 | * Call the space management code to pick |
@@ -1056,9 +989,8 @@ xfs_ialloc( | |||
1056 | */ | 989 | */ |
1057 | error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, | 990 | error = xfs_dialloc(tp, pip ? pip->i_ino : 0, mode, okalloc, |
1058 | ialloc_context, call_again, &ino); | 991 | ialloc_context, call_again, &ino); |
1059 | if (error != 0) { | 992 | if (error) |
1060 | return error; | 993 | return error; |
1061 | } | ||
1062 | if (*call_again || ino == NULLFSINO) { | 994 | if (*call_again || ino == NULLFSINO) { |
1063 | *ipp = NULL; | 995 | *ipp = NULL; |
1064 | return 0; | 996 | return 0; |
@@ -1072,9 +1004,8 @@ xfs_ialloc( | |||
1072 | */ | 1004 | */ |
1073 | error = xfs_trans_iget(tp->t_mountp, tp, ino, | 1005 | error = xfs_trans_iget(tp->t_mountp, tp, ino, |
1074 | XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip); | 1006 | XFS_IGET_CREATE, XFS_ILOCK_EXCL, &ip); |
1075 | if (error != 0) { | 1007 | if (error) |
1076 | return error; | 1008 | return error; |
1077 | } | ||
1078 | ASSERT(ip != NULL); | 1009 | ASSERT(ip != NULL); |
1079 | 1010 | ||
1080 | ip->i_d.di_mode = (__uint16_t)mode; | 1011 | ip->i_d.di_mode = (__uint16_t)mode; |
@@ -1093,8 +1024,8 @@ xfs_ialloc( | |||
1093 | * here rather than here and in the flush/logging code. | 1024 | * here rather than here and in the flush/logging code. |
1094 | */ | 1025 | */ |
1095 | if (xfs_sb_version_hasnlink(&tp->t_mountp->m_sb) && | 1026 | if (xfs_sb_version_hasnlink(&tp->t_mountp->m_sb) && |
1096 | ip->i_d.di_version == XFS_DINODE_VERSION_1) { | 1027 | ip->i_d.di_version == 1) { |
1097 | ip->i_d.di_version = XFS_DINODE_VERSION_2; | 1028 | ip->i_d.di_version = 2; |
1098 | /* | 1029 | /* |
1099 | * We've already zeroed the old link count, the projid field, | 1030 | * We've already zeroed the old link count, the projid field, |
1100 | * and the pad field. | 1031 | * and the pad field. |
@@ -1104,7 +1035,7 @@ xfs_ialloc( | |||
1104 | /* | 1035 | /* |
1105 | * Project ids won't be stored on disk if we are using a version 1 inode. | 1036 | * Project ids won't be stored on disk if we are using a version 1 inode. |
1106 | */ | 1037 | */ |
1107 | if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) | 1038 | if ((prid != 0) && (ip->i_d.di_version == 1)) |
1108 | xfs_bump_ino_vers2(tp, ip); | 1039 | xfs_bump_ino_vers2(tp, ip); |
1109 | 1040 | ||
1110 | if (pip && XFS_INHERIT_GID(pip)) { | 1041 | if (pip && XFS_INHERIT_GID(pip)) { |
@@ -1155,13 +1086,12 @@ xfs_ialloc( | |||
1155 | flags |= XFS_ILOG_DEV; | 1086 | flags |= XFS_ILOG_DEV; |
1156 | break; | 1087 | break; |
1157 | case S_IFREG: | 1088 | case S_IFREG: |
1158 | if (pip && xfs_inode_is_filestream(pip)) { | 1089 | /* |
1159 | error = xfs_filestream_associate(pip, ip); | 1090 | * we can't set up filestreams until after the VFS inode |
1160 | if (error < 0) | 1091 | * is set up properly. |
1161 | return -error; | 1092 | */ |
1162 | if (!error) | 1093 | if (pip && xfs_inode_is_filestream(pip)) |
1163 | xfs_iflags_set(ip, XFS_IFILESTREAM); | 1094 | filestreams = 1; |
1164 | } | ||
1165 | /* fall through */ | 1095 | /* fall through */ |
1166 | case S_IFDIR: | 1096 | case S_IFDIR: |
1167 | if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { | 1097 | if (pip && (pip->i_d.di_flags & XFS_DIFLAG_ANY)) { |
@@ -1227,6 +1157,15 @@ xfs_ialloc( | |||
1227 | /* now that we have an i_mode we can setup inode ops and unlock */ | 1157 | /* now that we have an i_mode we can setup inode ops and unlock */ |
1228 | xfs_setup_inode(ip); | 1158 | xfs_setup_inode(ip); |
1229 | 1159 | ||
1160 | /* now we have set up the vfs inode we can associate the filestream */ | ||
1161 | if (filestreams) { | ||
1162 | error = xfs_filestream_associate(pip, ip); | ||
1163 | if (error < 0) | ||
1164 | return -error; | ||
1165 | if (!error) | ||
1166 | xfs_iflags_set(ip, XFS_IFILESTREAM); | ||
1167 | } | ||
1168 | |||
1230 | *ipp = ip; | 1169 | *ipp = ip; |
1231 | return 0; | 1170 | return 0; |
1232 | } | 1171 | } |
@@ -1383,8 +1322,8 @@ xfs_itrunc_trace( | |||
1383 | * direct I/O with the truncate operation. Also, because we hold | 1322 | * direct I/O with the truncate operation. Also, because we hold |
1384 | * the IOLOCK in exclusive mode, we prevent new direct I/Os from being | 1323 | * the IOLOCK in exclusive mode, we prevent new direct I/Os from being |
1385 | * started until the truncate completes and drops the lock. Essentially, | 1324 | * started until the truncate completes and drops the lock. Essentially, |
1386 | * the vn_iowait() call forms an I/O barrier that provides strict ordering | 1325 | * the xfs_ioend_wait() call forms an I/O barrier that provides strict |
1387 | * between direct I/Os and the truncate operation. | 1326 | * ordering between direct I/Os and the truncate operation. |
1388 | * | 1327 | * |
1389 | * The flags parameter can have either the value XFS_ITRUNC_DEFINITE | 1328 | * The flags parameter can have either the value XFS_ITRUNC_DEFINITE |
1390 | * or XFS_ITRUNC_MAYBE. The XFS_ITRUNC_MAYBE value should be used | 1329 | * or XFS_ITRUNC_MAYBE. The XFS_ITRUNC_MAYBE value should be used |
@@ -1415,7 +1354,7 @@ xfs_itruncate_start( | |||
1415 | 1354 | ||
1416 | /* wait for the completion of any pending DIOs */ | 1355 | /* wait for the completion of any pending DIOs */ |
1417 | if (new_size == 0 || new_size < ip->i_size) | 1356 | if (new_size == 0 || new_size < ip->i_size) |
1418 | vn_iowait(ip); | 1357 | xfs_ioend_wait(ip); |
1419 | 1358 | ||
1420 | /* | 1359 | /* |
1421 | * Call toss_pages or flushinval_pages to get rid of pages | 1360 | * Call toss_pages or flushinval_pages to get rid of pages |
@@ -1726,8 +1665,14 @@ xfs_itruncate_finish( | |||
1726 | xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); | 1665 | xfs_trans_ijoin(ntp, ip, XFS_ILOCK_EXCL | XFS_IOLOCK_EXCL); |
1727 | xfs_trans_ihold(ntp, ip); | 1666 | xfs_trans_ihold(ntp, ip); |
1728 | 1667 | ||
1729 | if (!error) | 1668 | if (error) |
1730 | error = xfs_trans_reserve(ntp, 0, | 1669 | return error; |
1670 | /* | ||
1671 | * transaction commit worked ok so we can drop the extra ticket | ||
1672 | * reference that we gained in xfs_trans_dup() | ||
1673 | */ | ||
1674 | xfs_log_ticket_put(ntp->t_ticket); | ||
1675 | error = xfs_trans_reserve(ntp, 0, | ||
1731 | XFS_ITRUNCATE_LOG_RES(mp), 0, | 1676 | XFS_ITRUNCATE_LOG_RES(mp), 0, |
1732 | XFS_TRANS_PERM_LOG_RES, | 1677 | XFS_TRANS_PERM_LOG_RES, |
1733 | XFS_ITRUNCATE_LOG_COUNT); | 1678 | XFS_ITRUNCATE_LOG_COUNT); |
@@ -1781,13 +1726,10 @@ xfs_iunlink( | |||
1781 | xfs_dinode_t *dip; | 1726 | xfs_dinode_t *dip; |
1782 | xfs_buf_t *agibp; | 1727 | xfs_buf_t *agibp; |
1783 | xfs_buf_t *ibp; | 1728 | xfs_buf_t *ibp; |
1784 | xfs_agnumber_t agno; | ||
1785 | xfs_daddr_t agdaddr; | ||
1786 | xfs_agino_t agino; | 1729 | xfs_agino_t agino; |
1787 | short bucket_index; | 1730 | short bucket_index; |
1788 | int offset; | 1731 | int offset; |
1789 | int error; | 1732 | int error; |
1790 | int agi_ok; | ||
1791 | 1733 | ||
1792 | ASSERT(ip->i_d.di_nlink == 0); | 1734 | ASSERT(ip->i_d.di_nlink == 0); |
1793 | ASSERT(ip->i_d.di_mode != 0); | 1735 | ASSERT(ip->i_d.di_mode != 0); |
@@ -1795,31 +1737,15 @@ xfs_iunlink( | |||
1795 | 1737 | ||
1796 | mp = tp->t_mountp; | 1738 | mp = tp->t_mountp; |
1797 | 1739 | ||
1798 | agno = XFS_INO_TO_AGNO(mp, ip->i_ino); | ||
1799 | agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)); | ||
1800 | |||
1801 | /* | 1740 | /* |
1802 | * Get the agi buffer first. It ensures lock ordering | 1741 | * Get the agi buffer first. It ensures lock ordering |
1803 | * on the list. | 1742 | * on the list. |
1804 | */ | 1743 | */ |
1805 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr, | 1744 | error = xfs_read_agi(mp, tp, XFS_INO_TO_AGNO(mp, ip->i_ino), &agibp); |
1806 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); | ||
1807 | if (error) | 1745 | if (error) |
1808 | return error; | 1746 | return error; |
1809 | |||
1810 | /* | ||
1811 | * Validate the magic number of the agi block. | ||
1812 | */ | ||
1813 | agi = XFS_BUF_TO_AGI(agibp); | 1747 | agi = XFS_BUF_TO_AGI(agibp); |
1814 | agi_ok = | 1748 | |
1815 | be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && | ||
1816 | XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)); | ||
1817 | if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK, | ||
1818 | XFS_RANDOM_IUNLINK))) { | ||
1819 | XFS_CORRUPTION_ERROR("xfs_iunlink", XFS_ERRLEVEL_LOW, mp, agi); | ||
1820 | xfs_trans_brelse(tp, agibp); | ||
1821 | return XFS_ERROR(EFSCORRUPTED); | ||
1822 | } | ||
1823 | /* | 1749 | /* |
1824 | * Get the index into the agi hash table for the | 1750 | * Get the index into the agi hash table for the |
1825 | * list this inode will go on. | 1751 | * list this inode will go on. |
@@ -1837,14 +1763,14 @@ xfs_iunlink( | |||
1837 | * Here we put the head pointer into our next pointer, | 1763 | * Here we put the head pointer into our next pointer, |
1838 | * and then we fall through to point the head at us. | 1764 | * and then we fall through to point the head at us. |
1839 | */ | 1765 | */ |
1840 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK); | 1766 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, XFS_BUF_LOCK); |
1841 | if (error) | 1767 | if (error) |
1842 | return error; | 1768 | return error; |
1843 | 1769 | ||
1844 | ASSERT(be32_to_cpu(dip->di_next_unlinked) == NULLAGINO); | 1770 | ASSERT(be32_to_cpu(dip->di_next_unlinked) == NULLAGINO); |
1845 | /* both on-disk, don't endian flip twice */ | 1771 | /* both on-disk, don't endian flip twice */ |
1846 | dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; | 1772 | dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; |
1847 | offset = ip->i_boffset + | 1773 | offset = ip->i_imap.im_boffset + |
1848 | offsetof(xfs_dinode_t, di_next_unlinked); | 1774 | offsetof(xfs_dinode_t, di_next_unlinked); |
1849 | xfs_trans_inode_buf(tp, ibp); | 1775 | xfs_trans_inode_buf(tp, ibp); |
1850 | xfs_trans_log_buf(tp, ibp, offset, | 1776 | xfs_trans_log_buf(tp, ibp, offset, |
@@ -1879,7 +1805,6 @@ xfs_iunlink_remove( | |||
1879 | xfs_buf_t *agibp; | 1805 | xfs_buf_t *agibp; |
1880 | xfs_buf_t *ibp; | 1806 | xfs_buf_t *ibp; |
1881 | xfs_agnumber_t agno; | 1807 | xfs_agnumber_t agno; |
1882 | xfs_daddr_t agdaddr; | ||
1883 | xfs_agino_t agino; | 1808 | xfs_agino_t agino; |
1884 | xfs_agino_t next_agino; | 1809 | xfs_agino_t next_agino; |
1885 | xfs_buf_t *last_ibp; | 1810 | xfs_buf_t *last_ibp; |
@@ -1887,45 +1812,20 @@ xfs_iunlink_remove( | |||
1887 | short bucket_index; | 1812 | short bucket_index; |
1888 | int offset, last_offset = 0; | 1813 | int offset, last_offset = 0; |
1889 | int error; | 1814 | int error; |
1890 | int agi_ok; | ||
1891 | 1815 | ||
1892 | /* | ||
1893 | * First pull the on-disk inode from the AGI unlinked list. | ||
1894 | */ | ||
1895 | mp = tp->t_mountp; | 1816 | mp = tp->t_mountp; |
1896 | |||
1897 | agno = XFS_INO_TO_AGNO(mp, ip->i_ino); | 1817 | agno = XFS_INO_TO_AGNO(mp, ip->i_ino); |
1898 | agdaddr = XFS_AG_DADDR(mp, agno, XFS_AGI_DADDR(mp)); | ||
1899 | 1818 | ||
1900 | /* | 1819 | /* |
1901 | * Get the agi buffer first. It ensures lock ordering | 1820 | * Get the agi buffer first. It ensures lock ordering |
1902 | * on the list. | 1821 | * on the list. |
1903 | */ | 1822 | */ |
1904 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr, | 1823 | error = xfs_read_agi(mp, tp, agno, &agibp); |
1905 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); | 1824 | if (error) |
1906 | if (error) { | ||
1907 | cmn_err(CE_WARN, | ||
1908 | "xfs_iunlink_remove: xfs_trans_read_buf() returned an error %d on %s. Returning error.", | ||
1909 | error, mp->m_fsname); | ||
1910 | return error; | 1825 | return error; |
1911 | } | 1826 | |
1912 | /* | ||
1913 | * Validate the magic number of the agi block. | ||
1914 | */ | ||
1915 | agi = XFS_BUF_TO_AGI(agibp); | 1827 | agi = XFS_BUF_TO_AGI(agibp); |
1916 | agi_ok = | 1828 | |
1917 | be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && | ||
1918 | XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)); | ||
1919 | if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE, | ||
1920 | XFS_RANDOM_IUNLINK_REMOVE))) { | ||
1921 | XFS_CORRUPTION_ERROR("xfs_iunlink_remove", XFS_ERRLEVEL_LOW, | ||
1922 | mp, agi); | ||
1923 | xfs_trans_brelse(tp, agibp); | ||
1924 | cmn_err(CE_WARN, | ||
1925 | "xfs_iunlink_remove: XFS_TEST_ERROR() returned an error on %s. Returning EFSCORRUPTED.", | ||
1926 | mp->m_fsname); | ||
1927 | return XFS_ERROR(EFSCORRUPTED); | ||
1928 | } | ||
1929 | /* | 1829 | /* |
1930 | * Get the index into the agi hash table for the | 1830 | * Get the index into the agi hash table for the |
1931 | * list this inode will go on. | 1831 | * list this inode will go on. |
@@ -1945,7 +1845,7 @@ xfs_iunlink_remove( | |||
1945 | * of dealing with the buffer when there is no need to | 1845 | * of dealing with the buffer when there is no need to |
1946 | * change it. | 1846 | * change it. |
1947 | */ | 1847 | */ |
1948 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK); | 1848 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, XFS_BUF_LOCK); |
1949 | if (error) { | 1849 | if (error) { |
1950 | cmn_err(CE_WARN, | 1850 | cmn_err(CE_WARN, |
1951 | "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.", | 1851 | "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.", |
@@ -1956,7 +1856,7 @@ xfs_iunlink_remove( | |||
1956 | ASSERT(next_agino != 0); | 1856 | ASSERT(next_agino != 0); |
1957 | if (next_agino != NULLAGINO) { | 1857 | if (next_agino != NULLAGINO) { |
1958 | dip->di_next_unlinked = cpu_to_be32(NULLAGINO); | 1858 | dip->di_next_unlinked = cpu_to_be32(NULLAGINO); |
1959 | offset = ip->i_boffset + | 1859 | offset = ip->i_imap.im_boffset + |
1960 | offsetof(xfs_dinode_t, di_next_unlinked); | 1860 | offsetof(xfs_dinode_t, di_next_unlinked); |
1961 | xfs_trans_inode_buf(tp, ibp); | 1861 | xfs_trans_inode_buf(tp, ibp); |
1962 | xfs_trans_log_buf(tp, ibp, offset, | 1862 | xfs_trans_log_buf(tp, ibp, offset, |
@@ -1992,7 +1892,7 @@ xfs_iunlink_remove( | |||
1992 | } | 1892 | } |
1993 | next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino); | 1893 | next_ino = XFS_AGINO_TO_INO(mp, agno, next_agino); |
1994 | error = xfs_inotobp(mp, tp, next_ino, &last_dip, | 1894 | error = xfs_inotobp(mp, tp, next_ino, &last_dip, |
1995 | &last_ibp, &last_offset); | 1895 | &last_ibp, &last_offset, 0); |
1996 | if (error) { | 1896 | if (error) { |
1997 | cmn_err(CE_WARN, | 1897 | cmn_err(CE_WARN, |
1998 | "xfs_iunlink_remove: xfs_inotobp() returned an error %d on %s. Returning error.", | 1898 | "xfs_iunlink_remove: xfs_inotobp() returned an error %d on %s. Returning error.", |
@@ -2007,7 +1907,7 @@ xfs_iunlink_remove( | |||
2007 | * Now last_ibp points to the buffer previous to us on | 1907 | * Now last_ibp points to the buffer previous to us on |
2008 | * the unlinked list. Pull us from the list. | 1908 | * the unlinked list. Pull us from the list. |
2009 | */ | 1909 | */ |
2010 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK); | 1910 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, XFS_BUF_LOCK); |
2011 | if (error) { | 1911 | if (error) { |
2012 | cmn_err(CE_WARN, | 1912 | cmn_err(CE_WARN, |
2013 | "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.", | 1913 | "xfs_iunlink_remove: xfs_itobp() returned an error %d on %s. Returning error.", |
@@ -2019,7 +1919,7 @@ xfs_iunlink_remove( | |||
2019 | ASSERT(next_agino != agino); | 1919 | ASSERT(next_agino != agino); |
2020 | if (next_agino != NULLAGINO) { | 1920 | if (next_agino != NULLAGINO) { |
2021 | dip->di_next_unlinked = cpu_to_be32(NULLAGINO); | 1921 | dip->di_next_unlinked = cpu_to_be32(NULLAGINO); |
2022 | offset = ip->i_boffset + | 1922 | offset = ip->i_imap.im_boffset + |
2023 | offsetof(xfs_dinode_t, di_next_unlinked); | 1923 | offsetof(xfs_dinode_t, di_next_unlinked); |
2024 | xfs_trans_inode_buf(tp, ibp); | 1924 | xfs_trans_inode_buf(tp, ibp); |
2025 | xfs_trans_log_buf(tp, ibp, offset, | 1925 | xfs_trans_log_buf(tp, ibp, offset, |
@@ -2160,9 +2060,9 @@ xfs_ifree_cluster( | |||
2160 | iip = (xfs_inode_log_item_t *)lip; | 2060 | iip = (xfs_inode_log_item_t *)lip; |
2161 | ASSERT(iip->ili_logged == 1); | 2061 | ASSERT(iip->ili_logged == 1); |
2162 | lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done; | 2062 | lip->li_cb = (void(*)(xfs_buf_t*,xfs_log_item_t*)) xfs_istale_done; |
2163 | spin_lock(&mp->m_ail_lock); | 2063 | xfs_trans_ail_copy_lsn(mp->m_ail, |
2164 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | 2064 | &iip->ili_flush_lsn, |
2165 | spin_unlock(&mp->m_ail_lock); | 2065 | &iip->ili_item.li_lsn); |
2166 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); | 2066 | xfs_iflags_set(iip->ili_inode, XFS_ISTALE); |
2167 | pre_flushed++; | 2067 | pre_flushed++; |
2168 | } | 2068 | } |
@@ -2183,9 +2083,8 @@ xfs_ifree_cluster( | |||
2183 | iip->ili_last_fields = iip->ili_format.ilf_fields; | 2083 | iip->ili_last_fields = iip->ili_format.ilf_fields; |
2184 | iip->ili_format.ilf_fields = 0; | 2084 | iip->ili_format.ilf_fields = 0; |
2185 | iip->ili_logged = 1; | 2085 | iip->ili_logged = 1; |
2186 | spin_lock(&mp->m_ail_lock); | 2086 | xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, |
2187 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | 2087 | &iip->ili_item.li_lsn); |
2188 | spin_unlock(&mp->m_ail_lock); | ||
2189 | 2088 | ||
2190 | xfs_buf_attach_iodone(bp, | 2089 | xfs_buf_attach_iodone(bp, |
2191 | (void(*)(xfs_buf_t*,xfs_log_item_t*)) | 2090 | (void(*)(xfs_buf_t*,xfs_log_item_t*)) |
@@ -2263,7 +2162,7 @@ xfs_ifree( | |||
2263 | 2162 | ||
2264 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 2163 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
2265 | 2164 | ||
2266 | error = xfs_itobp(ip->i_mount, tp, ip, &dip, &ibp, 0, 0, XFS_BUF_LOCK); | 2165 | error = xfs_itobp(ip->i_mount, tp, ip, &dip, &ibp, XFS_BUF_LOCK); |
2267 | if (error) | 2166 | if (error) |
2268 | return error; | 2167 | return error; |
2269 | 2168 | ||
@@ -2279,7 +2178,7 @@ xfs_ifree( | |||
2279 | * This is a temporary hack that would require a proper fix | 2178 | * This is a temporary hack that would require a proper fix |
2280 | * in the future. | 2179 | * in the future. |
2281 | */ | 2180 | */ |
2282 | dip->di_core.di_mode = 0; | 2181 | dip->di_mode = 0; |
2283 | 2182 | ||
2284 | if (delete) { | 2183 | if (delete) { |
2285 | xfs_ifree_cluster(ip, tp, first_ino); | 2184 | xfs_ifree_cluster(ip, tp, first_ino); |
@@ -2312,9 +2211,10 @@ xfs_iroot_realloc( | |||
2312 | int rec_diff, | 2211 | int rec_diff, |
2313 | int whichfork) | 2212 | int whichfork) |
2314 | { | 2213 | { |
2214 | struct xfs_mount *mp = ip->i_mount; | ||
2315 | int cur_max; | 2215 | int cur_max; |
2316 | xfs_ifork_t *ifp; | 2216 | xfs_ifork_t *ifp; |
2317 | xfs_bmbt_block_t *new_broot; | 2217 | struct xfs_btree_block *new_broot; |
2318 | int new_max; | 2218 | int new_max; |
2319 | size_t new_size; | 2219 | size_t new_size; |
2320 | char *np; | 2220 | char *np; |
@@ -2335,8 +2235,7 @@ xfs_iroot_realloc( | |||
2335 | */ | 2235 | */ |
2336 | if (ifp->if_broot_bytes == 0) { | 2236 | if (ifp->if_broot_bytes == 0) { |
2337 | new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(rec_diff); | 2237 | new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(rec_diff); |
2338 | ifp->if_broot = (xfs_bmbt_block_t*)kmem_alloc(new_size, | 2238 | ifp->if_broot = kmem_alloc(new_size, KM_SLEEP); |
2339 | KM_SLEEP); | ||
2340 | ifp->if_broot_bytes = (int)new_size; | 2239 | ifp->if_broot_bytes = (int)new_size; |
2341 | return; | 2240 | return; |
2342 | } | 2241 | } |
@@ -2347,18 +2246,16 @@ xfs_iroot_realloc( | |||
2347 | * location. The records don't change location because | 2246 | * location. The records don't change location because |
2348 | * they are kept butted up against the btree block header. | 2247 | * they are kept butted up against the btree block header. |
2349 | */ | 2248 | */ |
2350 | cur_max = XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes); | 2249 | cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); |
2351 | new_max = cur_max + rec_diff; | 2250 | new_max = cur_max + rec_diff; |
2352 | new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max); | 2251 | new_size = (size_t)XFS_BMAP_BROOT_SPACE_CALC(new_max); |
2353 | ifp->if_broot = (xfs_bmbt_block_t *) | 2252 | ifp->if_broot = kmem_realloc(ifp->if_broot, new_size, |
2354 | kmem_realloc(ifp->if_broot, | ||
2355 | new_size, | ||
2356 | (size_t)XFS_BMAP_BROOT_SPACE_CALC(cur_max), /* old size */ | 2253 | (size_t)XFS_BMAP_BROOT_SPACE_CALC(cur_max), /* old size */ |
2357 | KM_SLEEP); | 2254 | KM_SLEEP); |
2358 | op = (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp->if_broot, 1, | 2255 | op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, |
2359 | ifp->if_broot_bytes); | 2256 | ifp->if_broot_bytes); |
2360 | np = (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp->if_broot, 1, | 2257 | np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, |
2361 | (int)new_size); | 2258 | (int)new_size); |
2362 | ifp->if_broot_bytes = (int)new_size; | 2259 | ifp->if_broot_bytes = (int)new_size; |
2363 | ASSERT(ifp->if_broot_bytes <= | 2260 | ASSERT(ifp->if_broot_bytes <= |
2364 | XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ); | 2261 | XFS_IFORK_SIZE(ip, whichfork) + XFS_BROOT_SIZE_ADJ); |
@@ -2372,7 +2269,7 @@ xfs_iroot_realloc( | |||
2372 | * records, just get rid of the root and clear the status bit. | 2269 | * records, just get rid of the root and clear the status bit. |
2373 | */ | 2270 | */ |
2374 | ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0)); | 2271 | ASSERT((ifp->if_broot != NULL) && (ifp->if_broot_bytes > 0)); |
2375 | cur_max = XFS_BMAP_BROOT_MAXRECS(ifp->if_broot_bytes); | 2272 | cur_max = xfs_bmbt_maxrecs(mp, ifp->if_broot_bytes, 0); |
2376 | new_max = cur_max + rec_diff; | 2273 | new_max = cur_max + rec_diff; |
2377 | ASSERT(new_max >= 0); | 2274 | ASSERT(new_max >= 0); |
2378 | if (new_max > 0) | 2275 | if (new_max > 0) |
@@ -2380,11 +2277,11 @@ xfs_iroot_realloc( | |||
2380 | else | 2277 | else |
2381 | new_size = 0; | 2278 | new_size = 0; |
2382 | if (new_size > 0) { | 2279 | if (new_size > 0) { |
2383 | new_broot = (xfs_bmbt_block_t *)kmem_alloc(new_size, KM_SLEEP); | 2280 | new_broot = kmem_alloc(new_size, KM_SLEEP); |
2384 | /* | 2281 | /* |
2385 | * First copy over the btree block header. | 2282 | * First copy over the btree block header. |
2386 | */ | 2283 | */ |
2387 | memcpy(new_broot, ifp->if_broot, sizeof(xfs_bmbt_block_t)); | 2284 | memcpy(new_broot, ifp->if_broot, XFS_BTREE_LBLOCK_LEN); |
2388 | } else { | 2285 | } else { |
2389 | new_broot = NULL; | 2286 | new_broot = NULL; |
2390 | ifp->if_flags &= ~XFS_IFBROOT; | 2287 | ifp->if_flags &= ~XFS_IFBROOT; |
@@ -2397,18 +2294,16 @@ xfs_iroot_realloc( | |||
2397 | /* | 2294 | /* |
2398 | * First copy the records. | 2295 | * First copy the records. |
2399 | */ | 2296 | */ |
2400 | op = (char *)XFS_BMAP_BROOT_REC_ADDR(ifp->if_broot, 1, | 2297 | op = (char *)XFS_BMBT_REC_ADDR(mp, ifp->if_broot, 1); |
2401 | ifp->if_broot_bytes); | 2298 | np = (char *)XFS_BMBT_REC_ADDR(mp, new_broot, 1); |
2402 | np = (char *)XFS_BMAP_BROOT_REC_ADDR(new_broot, 1, | ||
2403 | (int)new_size); | ||
2404 | memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); | 2299 | memcpy(np, op, new_max * (uint)sizeof(xfs_bmbt_rec_t)); |
2405 | 2300 | ||
2406 | /* | 2301 | /* |
2407 | * Then copy the pointers. | 2302 | * Then copy the pointers. |
2408 | */ | 2303 | */ |
2409 | op = (char *)XFS_BMAP_BROOT_PTR_ADDR(ifp->if_broot, 1, | 2304 | op = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, ifp->if_broot, 1, |
2410 | ifp->if_broot_bytes); | 2305 | ifp->if_broot_bytes); |
2411 | np = (char *)XFS_BMAP_BROOT_PTR_ADDR(new_broot, 1, | 2306 | np = (char *)XFS_BMAP_BROOT_PTR_ADDR(mp, new_broot, 1, |
2412 | (int)new_size); | 2307 | (int)new_size); |
2413 | memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); | 2308 | memcpy(np, op, new_max * (uint)sizeof(xfs_dfsbno_t)); |
2414 | } | 2309 | } |
@@ -2511,64 +2406,6 @@ xfs_idata_realloc( | |||
2511 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); | 2406 | ASSERT(ifp->if_bytes <= XFS_IFORK_SIZE(ip, whichfork)); |
2512 | } | 2407 | } |
2513 | 2408 | ||
2514 | |||
2515 | |||
2516 | |||
2517 | /* | ||
2518 | * Map inode to disk block and offset. | ||
2519 | * | ||
2520 | * mp -- the mount point structure for the current file system | ||
2521 | * tp -- the current transaction | ||
2522 | * ino -- the inode number of the inode to be located | ||
2523 | * imap -- this structure is filled in with the information necessary | ||
2524 | * to retrieve the given inode from disk | ||
2525 | * flags -- flags to pass to xfs_dilocate indicating whether or not | ||
2526 | * lookups in the inode btree were OK or not | ||
2527 | */ | ||
2528 | int | ||
2529 | xfs_imap( | ||
2530 | xfs_mount_t *mp, | ||
2531 | xfs_trans_t *tp, | ||
2532 | xfs_ino_t ino, | ||
2533 | xfs_imap_t *imap, | ||
2534 | uint flags) | ||
2535 | { | ||
2536 | xfs_fsblock_t fsbno; | ||
2537 | int len; | ||
2538 | int off; | ||
2539 | int error; | ||
2540 | |||
2541 | fsbno = imap->im_blkno ? | ||
2542 | XFS_DADDR_TO_FSB(mp, imap->im_blkno) : NULLFSBLOCK; | ||
2543 | error = xfs_dilocate(mp, tp, ino, &fsbno, &len, &off, flags); | ||
2544 | if (error) | ||
2545 | return error; | ||
2546 | |||
2547 | imap->im_blkno = XFS_FSB_TO_DADDR(mp, fsbno); | ||
2548 | imap->im_len = XFS_FSB_TO_BB(mp, len); | ||
2549 | imap->im_agblkno = XFS_FSB_TO_AGBNO(mp, fsbno); | ||
2550 | imap->im_ioffset = (ushort)off; | ||
2551 | imap->im_boffset = (ushort)(off << mp->m_sb.sb_inodelog); | ||
2552 | |||
2553 | /* | ||
2554 | * If the inode number maps to a block outside the bounds | ||
2555 | * of the file system then return NULL rather than calling | ||
2556 | * read_buf and panicing when we get an error from the | ||
2557 | * driver. | ||
2558 | */ | ||
2559 | if ((imap->im_blkno + imap->im_len) > | ||
2560 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) { | ||
2561 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_imap: " | ||
2562 | "(imap->im_blkno (0x%llx) + imap->im_len (0x%llx)) > " | ||
2563 | " XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks) (0x%llx)", | ||
2564 | (unsigned long long) imap->im_blkno, | ||
2565 | (unsigned long long) imap->im_len, | ||
2566 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)); | ||
2567 | return EINVAL; | ||
2568 | } | ||
2569 | return 0; | ||
2570 | } | ||
2571 | |||
2572 | void | 2409 | void |
2573 | xfs_idestroy_fork( | 2410 | xfs_idestroy_fork( |
2574 | xfs_inode_t *ip, | 2411 | xfs_inode_t *ip, |
@@ -2613,70 +2450,6 @@ xfs_idestroy_fork( | |||
2613 | } | 2450 | } |
2614 | 2451 | ||
2615 | /* | 2452 | /* |
2616 | * This is called free all the memory associated with an inode. | ||
2617 | * It must free the inode itself and any buffers allocated for | ||
2618 | * if_extents/if_data and if_broot. It must also free the lock | ||
2619 | * associated with the inode. | ||
2620 | */ | ||
2621 | void | ||
2622 | xfs_idestroy( | ||
2623 | xfs_inode_t *ip) | ||
2624 | { | ||
2625 | switch (ip->i_d.di_mode & S_IFMT) { | ||
2626 | case S_IFREG: | ||
2627 | case S_IFDIR: | ||
2628 | case S_IFLNK: | ||
2629 | xfs_idestroy_fork(ip, XFS_DATA_FORK); | ||
2630 | break; | ||
2631 | } | ||
2632 | if (ip->i_afp) | ||
2633 | xfs_idestroy_fork(ip, XFS_ATTR_FORK); | ||
2634 | mrfree(&ip->i_lock); | ||
2635 | mrfree(&ip->i_iolock); | ||
2636 | |||
2637 | #ifdef XFS_INODE_TRACE | ||
2638 | ktrace_free(ip->i_trace); | ||
2639 | #endif | ||
2640 | #ifdef XFS_BMAP_TRACE | ||
2641 | ktrace_free(ip->i_xtrace); | ||
2642 | #endif | ||
2643 | #ifdef XFS_BMBT_TRACE | ||
2644 | ktrace_free(ip->i_btrace); | ||
2645 | #endif | ||
2646 | #ifdef XFS_RW_TRACE | ||
2647 | ktrace_free(ip->i_rwtrace); | ||
2648 | #endif | ||
2649 | #ifdef XFS_ILOCK_TRACE | ||
2650 | ktrace_free(ip->i_lock_trace); | ||
2651 | #endif | ||
2652 | #ifdef XFS_DIR2_TRACE | ||
2653 | ktrace_free(ip->i_dir_trace); | ||
2654 | #endif | ||
2655 | if (ip->i_itemp) { | ||
2656 | /* | ||
2657 | * Only if we are shutting down the fs will we see an | ||
2658 | * inode still in the AIL. If it is there, we should remove | ||
2659 | * it to prevent a use-after-free from occurring. | ||
2660 | */ | ||
2661 | xfs_mount_t *mp = ip->i_mount; | ||
2662 | xfs_log_item_t *lip = &ip->i_itemp->ili_item; | ||
2663 | |||
2664 | ASSERT(((lip->li_flags & XFS_LI_IN_AIL) == 0) || | ||
2665 | XFS_FORCED_SHUTDOWN(ip->i_mount)); | ||
2666 | if (lip->li_flags & XFS_LI_IN_AIL) { | ||
2667 | spin_lock(&mp->m_ail_lock); | ||
2668 | if (lip->li_flags & XFS_LI_IN_AIL) | ||
2669 | xfs_trans_delete_ail(mp, lip); | ||
2670 | else | ||
2671 | spin_unlock(&mp->m_ail_lock); | ||
2672 | } | ||
2673 | xfs_inode_item_destroy(ip); | ||
2674 | } | ||
2675 | kmem_zone_free(xfs_inode_zone, ip); | ||
2676 | } | ||
2677 | |||
2678 | |||
2679 | /* | ||
2680 | * Increment the pin count of the given buffer. | 2453 | * Increment the pin count of the given buffer. |
2681 | * This value is protected by ipinlock spinlock in the mount structure. | 2454 | * This value is protected by ipinlock spinlock in the mount structure. |
2682 | */ | 2455 | */ |
@@ -2880,7 +2653,7 @@ xfs_iflush_fork( | |||
2880 | ASSERT(ifp->if_broot_bytes <= | 2653 | ASSERT(ifp->if_broot_bytes <= |
2881 | (XFS_IFORK_SIZE(ip, whichfork) + | 2654 | (XFS_IFORK_SIZE(ip, whichfork) + |
2882 | XFS_BROOT_SIZE_ADJ)); | 2655 | XFS_BROOT_SIZE_ADJ)); |
2883 | xfs_bmbt_to_bmdr(ifp->if_broot, ifp->if_broot_bytes, | 2656 | xfs_bmbt_to_bmdr(mp, ifp->if_broot, ifp->if_broot_bytes, |
2884 | (xfs_bmdr_block_t *)cp, | 2657 | (xfs_bmdr_block_t *)cp, |
2885 | XFS_DFORK_SIZE(dip, mp, whichfork)); | 2658 | XFS_DFORK_SIZE(dip, mp, whichfork)); |
2886 | } | 2659 | } |
@@ -2889,15 +2662,16 @@ xfs_iflush_fork( | |||
2889 | case XFS_DINODE_FMT_DEV: | 2662 | case XFS_DINODE_FMT_DEV: |
2890 | if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { | 2663 | if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { |
2891 | ASSERT(whichfork == XFS_DATA_FORK); | 2664 | ASSERT(whichfork == XFS_DATA_FORK); |
2892 | dip->di_u.di_dev = cpu_to_be32(ip->i_df.if_u2.if_rdev); | 2665 | xfs_dinode_put_rdev(dip, ip->i_df.if_u2.if_rdev); |
2893 | } | 2666 | } |
2894 | break; | 2667 | break; |
2895 | 2668 | ||
2896 | case XFS_DINODE_FMT_UUID: | 2669 | case XFS_DINODE_FMT_UUID: |
2897 | if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) { | 2670 | if (iip->ili_format.ilf_fields & XFS_ILOG_UUID) { |
2898 | ASSERT(whichfork == XFS_DATA_FORK); | 2671 | ASSERT(whichfork == XFS_DATA_FORK); |
2899 | memcpy(&dip->di_u.di_muuid, &ip->i_df.if_u2.if_uuid, | 2672 | memcpy(XFS_DFORK_DPTR(dip), |
2900 | sizeof(uuid_t)); | 2673 | &ip->i_df.if_u2.if_uuid, |
2674 | sizeof(uuid_t)); | ||
2901 | } | 2675 | } |
2902 | break; | 2676 | break; |
2903 | 2677 | ||
@@ -3030,7 +2804,6 @@ cluster_corrupt_out: | |||
3030 | XFS_BUF_CLR_BDSTRAT_FUNC(bp); | 2804 | XFS_BUF_CLR_BDSTRAT_FUNC(bp); |
3031 | XFS_BUF_UNDONE(bp); | 2805 | XFS_BUF_UNDONE(bp); |
3032 | XFS_BUF_STALE(bp); | 2806 | XFS_BUF_STALE(bp); |
3033 | XFS_BUF_SHUT(bp); | ||
3034 | XFS_BUF_ERROR(bp,EIO); | 2807 | XFS_BUF_ERROR(bp,EIO); |
3035 | xfs_biodone(bp); | 2808 | xfs_biodone(bp); |
3036 | } else { | 2809 | } else { |
@@ -3172,7 +2945,7 @@ xfs_iflush( | |||
3172 | /* | 2945 | /* |
3173 | * Get the buffer containing the on-disk inode. | 2946 | * Get the buffer containing the on-disk inode. |
3174 | */ | 2947 | */ |
3175 | error = xfs_itobp(mp, NULL, ip, &dip, &bp, 0, 0, | 2948 | error = xfs_itobp(mp, NULL, ip, &dip, &bp, |
3176 | noblock ? XFS_BUF_TRYLOCK : XFS_BUF_LOCK); | 2949 | noblock ? XFS_BUF_TRYLOCK : XFS_BUF_LOCK); |
3177 | if (error || !bp) { | 2950 | if (error || !bp) { |
3178 | xfs_ifunlock(ip); | 2951 | xfs_ifunlock(ip); |
@@ -3253,7 +3026,7 @@ xfs_iflush_int( | |||
3253 | } | 3026 | } |
3254 | 3027 | ||
3255 | /* set *dip = inode's place in the buffer */ | 3028 | /* set *dip = inode's place in the buffer */ |
3256 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_boffset); | 3029 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, ip->i_imap.im_boffset); |
3257 | 3030 | ||
3258 | /* | 3031 | /* |
3259 | * Clear i_update_core before copying out the data. | 3032 | * Clear i_update_core before copying out the data. |
@@ -3275,11 +3048,11 @@ xfs_iflush_int( | |||
3275 | */ | 3048 | */ |
3276 | xfs_synchronize_atime(ip); | 3049 | xfs_synchronize_atime(ip); |
3277 | 3050 | ||
3278 | if (XFS_TEST_ERROR(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC, | 3051 | if (XFS_TEST_ERROR(be16_to_cpu(dip->di_magic) != XFS_DINODE_MAGIC, |
3279 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { | 3052 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { |
3280 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, | 3053 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, |
3281 | "xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p", | 3054 | "xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p", |
3282 | ip->i_ino, be16_to_cpu(dip->di_core.di_magic), dip); | 3055 | ip->i_ino, be16_to_cpu(dip->di_magic), dip); |
3283 | goto corrupt_out; | 3056 | goto corrupt_out; |
3284 | } | 3057 | } |
3285 | if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, | 3058 | if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, |
@@ -3342,7 +3115,7 @@ xfs_iflush_int( | |||
3342 | * because if the inode is dirty at all the core must | 3115 | * because if the inode is dirty at all the core must |
3343 | * be. | 3116 | * be. |
3344 | */ | 3117 | */ |
3345 | xfs_dinode_to_disk(&dip->di_core, &ip->i_d); | 3118 | xfs_dinode_to_disk(dip, &ip->i_d); |
3346 | 3119 | ||
3347 | /* Wrap, we never let the log put out DI_MAX_FLUSH */ | 3120 | /* Wrap, we never let the log put out DI_MAX_FLUSH */ |
3348 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) | 3121 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) |
@@ -3354,28 +3127,27 @@ xfs_iflush_int( | |||
3354 | * convert back to the old inode format. If the superblock version | 3127 | * convert back to the old inode format. If the superblock version |
3355 | * has been updated, then make the conversion permanent. | 3128 | * has been updated, then make the conversion permanent. |
3356 | */ | 3129 | */ |
3357 | ASSERT(ip->i_d.di_version == XFS_DINODE_VERSION_1 || | 3130 | ASSERT(ip->i_d.di_version == 1 || xfs_sb_version_hasnlink(&mp->m_sb)); |
3358 | xfs_sb_version_hasnlink(&mp->m_sb)); | 3131 | if (ip->i_d.di_version == 1) { |
3359 | if (ip->i_d.di_version == XFS_DINODE_VERSION_1) { | ||
3360 | if (!xfs_sb_version_hasnlink(&mp->m_sb)) { | 3132 | if (!xfs_sb_version_hasnlink(&mp->m_sb)) { |
3361 | /* | 3133 | /* |
3362 | * Convert it back. | 3134 | * Convert it back. |
3363 | */ | 3135 | */ |
3364 | ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); | 3136 | ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); |
3365 | dip->di_core.di_onlink = cpu_to_be16(ip->i_d.di_nlink); | 3137 | dip->di_onlink = cpu_to_be16(ip->i_d.di_nlink); |
3366 | } else { | 3138 | } else { |
3367 | /* | 3139 | /* |
3368 | * The superblock version has already been bumped, | 3140 | * The superblock version has already been bumped, |
3369 | * so just make the conversion to the new inode | 3141 | * so just make the conversion to the new inode |
3370 | * format permanent. | 3142 | * format permanent. |
3371 | */ | 3143 | */ |
3372 | ip->i_d.di_version = XFS_DINODE_VERSION_2; | 3144 | ip->i_d.di_version = 2; |
3373 | dip->di_core.di_version = XFS_DINODE_VERSION_2; | 3145 | dip->di_version = 2; |
3374 | ip->i_d.di_onlink = 0; | 3146 | ip->i_d.di_onlink = 0; |
3375 | dip->di_core.di_onlink = 0; | 3147 | dip->di_onlink = 0; |
3376 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | 3148 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); |
3377 | memset(&(dip->di_core.di_pad[0]), 0, | 3149 | memset(&(dip->di_pad[0]), 0, |
3378 | sizeof(dip->di_core.di_pad)); | 3150 | sizeof(dip->di_pad)); |
3379 | ASSERT(ip->i_d.di_projid == 0); | 3151 | ASSERT(ip->i_d.di_projid == 0); |
3380 | } | 3152 | } |
3381 | } | 3153 | } |
@@ -3418,10 +3190,8 @@ xfs_iflush_int( | |||
3418 | iip->ili_format.ilf_fields = 0; | 3190 | iip->ili_format.ilf_fields = 0; |
3419 | iip->ili_logged = 1; | 3191 | iip->ili_logged = 1; |
3420 | 3192 | ||
3421 | ASSERT(sizeof(xfs_lsn_t) == 8); /* don't lock if it shrinks */ | 3193 | xfs_trans_ail_copy_lsn(mp->m_ail, &iip->ili_flush_lsn, |
3422 | spin_lock(&mp->m_ail_lock); | 3194 | &iip->ili_item.li_lsn); |
3423 | iip->ili_flush_lsn = iip->ili_item.li_lsn; | ||
3424 | spin_unlock(&mp->m_ail_lock); | ||
3425 | 3195 | ||
3426 | /* | 3196 | /* |
3427 | * Attach the function xfs_iflush_done to the inode's | 3197 | * Attach the function xfs_iflush_done to the inode's |
@@ -3459,45 +3229,8 @@ corrupt_out: | |||
3459 | } | 3229 | } |
3460 | 3230 | ||
3461 | 3231 | ||
3462 | /* | ||
3463 | * Flush all inactive inodes in mp. | ||
3464 | */ | ||
3465 | void | ||
3466 | xfs_iflush_all( | ||
3467 | xfs_mount_t *mp) | ||
3468 | { | ||
3469 | xfs_inode_t *ip; | ||
3470 | |||
3471 | again: | ||
3472 | XFS_MOUNT_ILOCK(mp); | ||
3473 | ip = mp->m_inodes; | ||
3474 | if (ip == NULL) | ||
3475 | goto out; | ||
3476 | |||
3477 | do { | ||
3478 | /* Make sure we skip markers inserted by sync */ | ||
3479 | if (ip->i_mount == NULL) { | ||
3480 | ip = ip->i_mnext; | ||
3481 | continue; | ||
3482 | } | ||
3483 | |||
3484 | if (!VFS_I(ip)) { | ||
3485 | XFS_MOUNT_IUNLOCK(mp); | ||
3486 | xfs_finish_reclaim(ip, 0, XFS_IFLUSH_ASYNC); | ||
3487 | goto again; | ||
3488 | } | ||
3489 | |||
3490 | ASSERT(vn_count(VFS_I(ip)) == 0); | ||
3491 | |||
3492 | ip = ip->i_mnext; | ||
3493 | } while (ip != mp->m_inodes); | ||
3494 | out: | ||
3495 | XFS_MOUNT_IUNLOCK(mp); | ||
3496 | } | ||
3497 | 3232 | ||
3498 | #ifdef XFS_ILOCK_TRACE | 3233 | #ifdef XFS_ILOCK_TRACE |
3499 | ktrace_t *xfs_ilock_trace_buf; | ||
3500 | |||
3501 | void | 3234 | void |
3502 | xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra) | 3235 | xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra) |
3503 | { | 3236 | { |