diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 383 |
1 files changed, 192 insertions, 191 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index cdc4c28926d0..abf509a88915 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -49,12 +49,11 @@ | |||
49 | #include "xfs_quota.h" | 49 | #include "xfs_quota.h" |
50 | #include "xfs_acl.h" | 50 | #include "xfs_acl.h" |
51 | #include "xfs_filestream.h" | 51 | #include "xfs_filestream.h" |
52 | 52 | #include "xfs_vnodeops.h" | |
53 | #include <linux/log2.h> | ||
54 | 53 | ||
55 | kmem_zone_t *xfs_ifork_zone; | 54 | kmem_zone_t *xfs_ifork_zone; |
56 | kmem_zone_t *xfs_inode_zone; | 55 | kmem_zone_t *xfs_inode_zone; |
57 | kmem_zone_t *xfs_chashlist_zone; | 56 | kmem_zone_t *xfs_icluster_zone; |
58 | 57 | ||
59 | /* | 58 | /* |
60 | * Used in xfs_itruncate(). This is the maximum number of extents | 59 | * Used in xfs_itruncate(). This is the maximum number of extents |
@@ -67,7 +66,6 @@ STATIC int xfs_iformat_local(xfs_inode_t *, xfs_dinode_t *, int, int); | |||
67 | STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); | 66 | STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); |
68 | STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); | 67 | STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); |
69 | 68 | ||
70 | |||
71 | #ifdef DEBUG | 69 | #ifdef DEBUG |
72 | /* | 70 | /* |
73 | * Make sure that the extents in the given memory buffer | 71 | * Make sure that the extents in the given memory buffer |
@@ -77,28 +75,23 @@ STATIC void | |||
77 | xfs_validate_extents( | 75 | xfs_validate_extents( |
78 | xfs_ifork_t *ifp, | 76 | xfs_ifork_t *ifp, |
79 | int nrecs, | 77 | int nrecs, |
80 | int disk, | ||
81 | xfs_exntfmt_t fmt) | 78 | xfs_exntfmt_t fmt) |
82 | { | 79 | { |
83 | xfs_bmbt_rec_t *ep; | ||
84 | xfs_bmbt_irec_t irec; | 80 | xfs_bmbt_irec_t irec; |
85 | xfs_bmbt_rec_t rec; | 81 | xfs_bmbt_rec_host_t rec; |
86 | int i; | 82 | int i; |
87 | 83 | ||
88 | for (i = 0; i < nrecs; i++) { | 84 | for (i = 0; i < nrecs; i++) { |
89 | ep = xfs_iext_get_ext(ifp, i); | 85 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); |
90 | rec.l0 = get_unaligned((__uint64_t*)&ep->l0); | 86 | rec.l0 = get_unaligned(&ep->l0); |
91 | rec.l1 = get_unaligned((__uint64_t*)&ep->l1); | 87 | rec.l1 = get_unaligned(&ep->l1); |
92 | if (disk) | 88 | xfs_bmbt_get_all(&rec, &irec); |
93 | xfs_bmbt_disk_get_all(&rec, &irec); | ||
94 | else | ||
95 | xfs_bmbt_get_all(&rec, &irec); | ||
96 | if (fmt == XFS_EXTFMT_NOSTATE) | 89 | if (fmt == XFS_EXTFMT_NOSTATE) |
97 | ASSERT(irec.br_state == XFS_EXT_NORM); | 90 | ASSERT(irec.br_state == XFS_EXT_NORM); |
98 | } | 91 | } |
99 | } | 92 | } |
100 | #else /* DEBUG */ | 93 | #else /* DEBUG */ |
101 | #define xfs_validate_extents(ifp, nrecs, disk, fmt) | 94 | #define xfs_validate_extents(ifp, nrecs, fmt) |
102 | #endif /* DEBUG */ | 95 | #endif /* DEBUG */ |
103 | 96 | ||
104 | /* | 97 | /* |
@@ -201,8 +194,8 @@ xfs_inotobp( | |||
201 | } | 194 | } |
202 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, 0); | 195 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, 0); |
203 | di_ok = | 196 | di_ok = |
204 | INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && | 197 | be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC && |
205 | XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); | 198 | XFS_DINODE_GOOD_VERSION(dip->di_core.di_version); |
206 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, | 199 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, XFS_ERRTAG_ITOBP_INOTOBP, |
207 | XFS_RANDOM_ITOBP_INOTOBP))) { | 200 | XFS_RANDOM_ITOBP_INOTOBP))) { |
208 | XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip); | 201 | XFS_CORRUPTION_ERROR("xfs_inotobp", XFS_ERRLEVEL_LOW, mp, dip); |
@@ -346,8 +339,8 @@ xfs_itobp( | |||
346 | 339 | ||
347 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, | 340 | dip = (xfs_dinode_t *)xfs_buf_offset(bp, |
348 | (i << mp->m_sb.sb_inodelog)); | 341 | (i << mp->m_sb.sb_inodelog)); |
349 | di_ok = INT_GET(dip->di_core.di_magic, ARCH_CONVERT) == XFS_DINODE_MAGIC && | 342 | di_ok = be16_to_cpu(dip->di_core.di_magic) == XFS_DINODE_MAGIC && |
350 | XFS_DINODE_GOOD_VERSION(INT_GET(dip->di_core.di_version, ARCH_CONVERT)); | 343 | XFS_DINODE_GOOD_VERSION(dip->di_core.di_version); |
351 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, | 344 | if (unlikely(XFS_TEST_ERROR(!di_ok, mp, |
352 | XFS_ERRTAG_ITOBP_INOTOBP, | 345 | XFS_ERRTAG_ITOBP_INOTOBP, |
353 | XFS_RANDOM_ITOBP_INOTOBP))) { | 346 | XFS_RANDOM_ITOBP_INOTOBP))) { |
@@ -361,7 +354,7 @@ xfs_itobp( | |||
361 | "daddr %lld #%d (magic=%x)", | 354 | "daddr %lld #%d (magic=%x)", |
362 | XFS_BUFTARG_NAME(mp->m_ddev_targp), | 355 | XFS_BUFTARG_NAME(mp->m_ddev_targp), |
363 | (unsigned long long)imap.im_blkno, i, | 356 | (unsigned long long)imap.im_blkno, i, |
364 | INT_GET(dip->di_core.di_magic, ARCH_CONVERT)); | 357 | be16_to_cpu(dip->di_core.di_magic)); |
365 | #endif | 358 | #endif |
366 | XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH, | 359 | XFS_CORRUPTION_ERROR("xfs_itobp", XFS_ERRLEVEL_HIGH, |
367 | mp, dip); | 360 | mp, dip); |
@@ -407,27 +400,26 @@ xfs_iformat( | |||
407 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | 400 | XFS_IFORK_DSIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); |
408 | error = 0; | 401 | error = 0; |
409 | 402 | ||
410 | if (unlikely( | 403 | if (unlikely(be32_to_cpu(dip->di_core.di_nextents) + |
411 | INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) + | 404 | be16_to_cpu(dip->di_core.di_anextents) > |
412 | INT_GET(dip->di_core.di_anextents, ARCH_CONVERT) > | 405 | be64_to_cpu(dip->di_core.di_nblocks))) { |
413 | INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT))) { | ||
414 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 406 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
415 | "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", | 407 | "corrupt dinode %Lu, extent total = %d, nblocks = %Lu.", |
416 | (unsigned long long)ip->i_ino, | 408 | (unsigned long long)ip->i_ino, |
417 | (int)(INT_GET(dip->di_core.di_nextents, ARCH_CONVERT) | 409 | (int)(be32_to_cpu(dip->di_core.di_nextents) + |
418 | + INT_GET(dip->di_core.di_anextents, ARCH_CONVERT)), | 410 | be16_to_cpu(dip->di_core.di_anextents)), |
419 | (unsigned long long) | 411 | (unsigned long long) |
420 | INT_GET(dip->di_core.di_nblocks, ARCH_CONVERT)); | 412 | be64_to_cpu(dip->di_core.di_nblocks)); |
421 | XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, | 413 | XFS_CORRUPTION_ERROR("xfs_iformat(1)", XFS_ERRLEVEL_LOW, |
422 | ip->i_mount, dip); | 414 | ip->i_mount, dip); |
423 | return XFS_ERROR(EFSCORRUPTED); | 415 | return XFS_ERROR(EFSCORRUPTED); |
424 | } | 416 | } |
425 | 417 | ||
426 | if (unlikely(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT) > ip->i_mount->m_sb.sb_inodesize)) { | 418 | if (unlikely(dip->di_core.di_forkoff > ip->i_mount->m_sb.sb_inodesize)) { |
427 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 419 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
428 | "corrupt dinode %Lu, forkoff = 0x%x.", | 420 | "corrupt dinode %Lu, forkoff = 0x%x.", |
429 | (unsigned long long)ip->i_ino, | 421 | (unsigned long long)ip->i_ino, |
430 | (int)(INT_GET(dip->di_core.di_forkoff, ARCH_CONVERT))); | 422 | dip->di_core.di_forkoff); |
431 | XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, | 423 | XFS_CORRUPTION_ERROR("xfs_iformat(2)", XFS_ERRLEVEL_LOW, |
432 | ip->i_mount, dip); | 424 | ip->i_mount, dip); |
433 | return XFS_ERROR(EFSCORRUPTED); | 425 | return XFS_ERROR(EFSCORRUPTED); |
@@ -438,25 +430,25 @@ xfs_iformat( | |||
438 | case S_IFCHR: | 430 | case S_IFCHR: |
439 | case S_IFBLK: | 431 | case S_IFBLK: |
440 | case S_IFSOCK: | 432 | case S_IFSOCK: |
441 | if (unlikely(INT_GET(dip->di_core.di_format, ARCH_CONVERT) != XFS_DINODE_FMT_DEV)) { | 433 | if (unlikely(dip->di_core.di_format != XFS_DINODE_FMT_DEV)) { |
442 | XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, | 434 | XFS_CORRUPTION_ERROR("xfs_iformat(3)", XFS_ERRLEVEL_LOW, |
443 | ip->i_mount, dip); | 435 | ip->i_mount, dip); |
444 | return XFS_ERROR(EFSCORRUPTED); | 436 | return XFS_ERROR(EFSCORRUPTED); |
445 | } | 437 | } |
446 | ip->i_d.di_size = 0; | 438 | ip->i_d.di_size = 0; |
447 | ip->i_size = 0; | 439 | ip->i_size = 0; |
448 | ip->i_df.if_u2.if_rdev = INT_GET(dip->di_u.di_dev, ARCH_CONVERT); | 440 | ip->i_df.if_u2.if_rdev = be32_to_cpu(dip->di_u.di_dev); |
449 | break; | 441 | break; |
450 | 442 | ||
451 | case S_IFREG: | 443 | case S_IFREG: |
452 | case S_IFLNK: | 444 | case S_IFLNK: |
453 | case S_IFDIR: | 445 | case S_IFDIR: |
454 | switch (INT_GET(dip->di_core.di_format, ARCH_CONVERT)) { | 446 | switch (dip->di_core.di_format) { |
455 | case XFS_DINODE_FMT_LOCAL: | 447 | case XFS_DINODE_FMT_LOCAL: |
456 | /* | 448 | /* |
457 | * no local regular files yet | 449 | * no local regular files yet |
458 | */ | 450 | */ |
459 | if (unlikely((INT_GET(dip->di_core.di_mode, ARCH_CONVERT) & S_IFMT) == S_IFREG)) { | 451 | if (unlikely((be16_to_cpu(dip->di_core.di_mode) & S_IFMT) == S_IFREG)) { |
460 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 452 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
461 | "corrupt inode %Lu " | 453 | "corrupt inode %Lu " |
462 | "(local format for regular file).", | 454 | "(local format for regular file).", |
@@ -467,7 +459,7 @@ xfs_iformat( | |||
467 | return XFS_ERROR(EFSCORRUPTED); | 459 | return XFS_ERROR(EFSCORRUPTED); |
468 | } | 460 | } |
469 | 461 | ||
470 | di_size = INT_GET(dip->di_core.di_size, ARCH_CONVERT); | 462 | di_size = be64_to_cpu(dip->di_core.di_size); |
471 | if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { | 463 | if (unlikely(di_size > XFS_DFORK_DSIZE(dip, ip->i_mount))) { |
472 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, | 464 | xfs_fs_repair_cmn_err(CE_WARN, ip->i_mount, |
473 | "corrupt inode %Lu " | 465 | "corrupt inode %Lu " |
@@ -509,7 +501,7 @@ xfs_iformat( | |||
509 | ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); | 501 | ip->i_afp = kmem_zone_zalloc(xfs_ifork_zone, KM_SLEEP); |
510 | ip->i_afp->if_ext_max = | 502 | ip->i_afp->if_ext_max = |
511 | XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); | 503 | XFS_IFORK_ASIZE(ip) / (uint)sizeof(xfs_bmbt_rec_t); |
512 | switch (INT_GET(dip->di_core.di_aformat, ARCH_CONVERT)) { | 504 | switch (dip->di_core.di_aformat) { |
513 | case XFS_DINODE_FMT_LOCAL: | 505 | case XFS_DINODE_FMT_LOCAL: |
514 | atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); | 506 | atp = (xfs_attr_shortform_t *)XFS_DFORK_APTR(dip); |
515 | size = be16_to_cpu(atp->hdr.totsize); | 507 | size = be16_to_cpu(atp->hdr.totsize); |
@@ -602,7 +594,7 @@ xfs_iformat_extents( | |||
602 | xfs_dinode_t *dip, | 594 | xfs_dinode_t *dip, |
603 | int whichfork) | 595 | int whichfork) |
604 | { | 596 | { |
605 | xfs_bmbt_rec_t *ep, *dp; | 597 | xfs_bmbt_rec_t *dp; |
606 | xfs_ifork_t *ifp; | 598 | xfs_ifork_t *ifp; |
607 | int nex; | 599 | int nex; |
608 | int size; | 600 | int size; |
@@ -637,13 +629,11 @@ xfs_iformat_extents( | |||
637 | ifp->if_bytes = size; | 629 | ifp->if_bytes = size; |
638 | if (size) { | 630 | if (size) { |
639 | dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); | 631 | dp = (xfs_bmbt_rec_t *) XFS_DFORK_PTR(dip, whichfork); |
640 | xfs_validate_extents(ifp, nex, 1, XFS_EXTFMT_INODE(ip)); | 632 | xfs_validate_extents(ifp, nex, XFS_EXTFMT_INODE(ip)); |
641 | for (i = 0; i < nex; i++, dp++) { | 633 | for (i = 0; i < nex; i++, dp++) { |
642 | ep = xfs_iext_get_ext(ifp, i); | 634 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); |
643 | ep->l0 = INT_GET(get_unaligned((__uint64_t*)&dp->l0), | 635 | ep->l0 = be64_to_cpu(get_unaligned(&dp->l0)); |
644 | ARCH_CONVERT); | 636 | ep->l1 = be64_to_cpu(get_unaligned(&dp->l1)); |
645 | ep->l1 = INT_GET(get_unaligned((__uint64_t*)&dp->l1), | ||
646 | ARCH_CONVERT); | ||
647 | } | 637 | } |
648 | XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); | 638 | XFS_BMAP_TRACE_EXLIST(ip, nex, whichfork); |
649 | if (whichfork != XFS_DATA_FORK || | 639 | if (whichfork != XFS_DATA_FORK || |
@@ -719,70 +709,74 @@ xfs_iformat_btree( | |||
719 | return 0; | 709 | return 0; |
720 | } | 710 | } |
721 | 711 | ||
722 | /* | ||
723 | * xfs_xlate_dinode_core - translate an xfs_inode_core_t between ondisk | ||
724 | * and native format | ||
725 | * | ||
726 | * buf = on-disk representation | ||
727 | * dip = native representation | ||
728 | * dir = direction - +ve -> disk to native | ||
729 | * -ve -> native to disk | ||
730 | */ | ||
731 | void | 712 | void |
732 | xfs_xlate_dinode_core( | 713 | xfs_dinode_from_disk( |
733 | xfs_caddr_t buf, | 714 | xfs_icdinode_t *to, |
734 | xfs_dinode_core_t *dip, | 715 | xfs_dinode_core_t *from) |
735 | int dir) | ||
736 | { | 716 | { |
737 | xfs_dinode_core_t *buf_core = (xfs_dinode_core_t *)buf; | 717 | to->di_magic = be16_to_cpu(from->di_magic); |
738 | xfs_dinode_core_t *mem_core = (xfs_dinode_core_t *)dip; | 718 | to->di_mode = be16_to_cpu(from->di_mode); |
739 | xfs_arch_t arch = ARCH_CONVERT; | 719 | to->di_version = from ->di_version; |
740 | 720 | to->di_format = from->di_format; | |
741 | ASSERT(dir); | 721 | to->di_onlink = be16_to_cpu(from->di_onlink); |
742 | 722 | to->di_uid = be32_to_cpu(from->di_uid); | |
743 | INT_XLATE(buf_core->di_magic, mem_core->di_magic, dir, arch); | 723 | to->di_gid = be32_to_cpu(from->di_gid); |
744 | INT_XLATE(buf_core->di_mode, mem_core->di_mode, dir, arch); | 724 | to->di_nlink = be32_to_cpu(from->di_nlink); |
745 | INT_XLATE(buf_core->di_version, mem_core->di_version, dir, arch); | 725 | to->di_projid = be16_to_cpu(from->di_projid); |
746 | INT_XLATE(buf_core->di_format, mem_core->di_format, dir, arch); | 726 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); |
747 | INT_XLATE(buf_core->di_onlink, mem_core->di_onlink, dir, arch); | 727 | to->di_flushiter = be16_to_cpu(from->di_flushiter); |
748 | INT_XLATE(buf_core->di_uid, mem_core->di_uid, dir, arch); | 728 | to->di_atime.t_sec = be32_to_cpu(from->di_atime.t_sec); |
749 | INT_XLATE(buf_core->di_gid, mem_core->di_gid, dir, arch); | 729 | to->di_atime.t_nsec = be32_to_cpu(from->di_atime.t_nsec); |
750 | INT_XLATE(buf_core->di_nlink, mem_core->di_nlink, dir, arch); | 730 | to->di_mtime.t_sec = be32_to_cpu(from->di_mtime.t_sec); |
751 | INT_XLATE(buf_core->di_projid, mem_core->di_projid, dir, arch); | 731 | to->di_mtime.t_nsec = be32_to_cpu(from->di_mtime.t_nsec); |
752 | 732 | to->di_ctime.t_sec = be32_to_cpu(from->di_ctime.t_sec); | |
753 | if (dir > 0) { | 733 | to->di_ctime.t_nsec = be32_to_cpu(from->di_ctime.t_nsec); |
754 | memcpy(mem_core->di_pad, buf_core->di_pad, | 734 | to->di_size = be64_to_cpu(from->di_size); |
755 | sizeof(buf_core->di_pad)); | 735 | to->di_nblocks = be64_to_cpu(from->di_nblocks); |
756 | } else { | 736 | to->di_extsize = be32_to_cpu(from->di_extsize); |
757 | memcpy(buf_core->di_pad, mem_core->di_pad, | 737 | to->di_nextents = be32_to_cpu(from->di_nextents); |
758 | sizeof(buf_core->di_pad)); | 738 | to->di_anextents = be16_to_cpu(from->di_anextents); |
759 | } | 739 | to->di_forkoff = from->di_forkoff; |
760 | 740 | to->di_aformat = from->di_aformat; | |
761 | INT_XLATE(buf_core->di_flushiter, mem_core->di_flushiter, dir, arch); | 741 | to->di_dmevmask = be32_to_cpu(from->di_dmevmask); |
762 | 742 | to->di_dmstate = be16_to_cpu(from->di_dmstate); | |
763 | INT_XLATE(buf_core->di_atime.t_sec, mem_core->di_atime.t_sec, | 743 | to->di_flags = be16_to_cpu(from->di_flags); |
764 | dir, arch); | 744 | to->di_gen = be32_to_cpu(from->di_gen); |
765 | INT_XLATE(buf_core->di_atime.t_nsec, mem_core->di_atime.t_nsec, | 745 | } |
766 | dir, arch); | 746 | |
767 | INT_XLATE(buf_core->di_mtime.t_sec, mem_core->di_mtime.t_sec, | 747 | void |
768 | dir, arch); | 748 | xfs_dinode_to_disk( |
769 | INT_XLATE(buf_core->di_mtime.t_nsec, mem_core->di_mtime.t_nsec, | 749 | xfs_dinode_core_t *to, |
770 | dir, arch); | 750 | xfs_icdinode_t *from) |
771 | INT_XLATE(buf_core->di_ctime.t_sec, mem_core->di_ctime.t_sec, | 751 | { |
772 | dir, arch); | 752 | to->di_magic = cpu_to_be16(from->di_magic); |
773 | INT_XLATE(buf_core->di_ctime.t_nsec, mem_core->di_ctime.t_nsec, | 753 | to->di_mode = cpu_to_be16(from->di_mode); |
774 | dir, arch); | 754 | to->di_version = from ->di_version; |
775 | INT_XLATE(buf_core->di_size, mem_core->di_size, dir, arch); | 755 | to->di_format = from->di_format; |
776 | INT_XLATE(buf_core->di_nblocks, mem_core->di_nblocks, dir, arch); | 756 | to->di_onlink = cpu_to_be16(from->di_onlink); |
777 | INT_XLATE(buf_core->di_extsize, mem_core->di_extsize, dir, arch); | 757 | to->di_uid = cpu_to_be32(from->di_uid); |
778 | INT_XLATE(buf_core->di_nextents, mem_core->di_nextents, dir, arch); | 758 | to->di_gid = cpu_to_be32(from->di_gid); |
779 | INT_XLATE(buf_core->di_anextents, mem_core->di_anextents, dir, arch); | 759 | to->di_nlink = cpu_to_be32(from->di_nlink); |
780 | INT_XLATE(buf_core->di_forkoff, mem_core->di_forkoff, dir, arch); | 760 | to->di_projid = cpu_to_be16(from->di_projid); |
781 | INT_XLATE(buf_core->di_aformat, mem_core->di_aformat, dir, arch); | 761 | memcpy(to->di_pad, from->di_pad, sizeof(to->di_pad)); |
782 | INT_XLATE(buf_core->di_dmevmask, mem_core->di_dmevmask, dir, arch); | 762 | to->di_flushiter = cpu_to_be16(from->di_flushiter); |
783 | INT_XLATE(buf_core->di_dmstate, mem_core->di_dmstate, dir, arch); | 763 | to->di_atime.t_sec = cpu_to_be32(from->di_atime.t_sec); |
784 | INT_XLATE(buf_core->di_flags, mem_core->di_flags, dir, arch); | 764 | to->di_atime.t_nsec = cpu_to_be32(from->di_atime.t_nsec); |
785 | INT_XLATE(buf_core->di_gen, mem_core->di_gen, dir, arch); | 765 | to->di_mtime.t_sec = cpu_to_be32(from->di_mtime.t_sec); |
766 | to->di_mtime.t_nsec = cpu_to_be32(from->di_mtime.t_nsec); | ||
767 | to->di_ctime.t_sec = cpu_to_be32(from->di_ctime.t_sec); | ||
768 | to->di_ctime.t_nsec = cpu_to_be32(from->di_ctime.t_nsec); | ||
769 | to->di_size = cpu_to_be64(from->di_size); | ||
770 | to->di_nblocks = cpu_to_be64(from->di_nblocks); | ||
771 | to->di_extsize = cpu_to_be32(from->di_extsize); | ||
772 | to->di_nextents = cpu_to_be32(from->di_nextents); | ||
773 | to->di_anextents = cpu_to_be16(from->di_anextents); | ||
774 | to->di_forkoff = from->di_forkoff; | ||
775 | to->di_aformat = from->di_aformat; | ||
776 | to->di_dmevmask = cpu_to_be32(from->di_dmevmask); | ||
777 | to->di_dmstate = cpu_to_be16(from->di_dmstate); | ||
778 | to->di_flags = cpu_to_be16(from->di_flags); | ||
779 | to->di_gen = cpu_to_be32(from->di_gen); | ||
786 | } | 780 | } |
787 | 781 | ||
788 | STATIC uint | 782 | STATIC uint |
@@ -829,7 +823,7 @@ uint | |||
829 | xfs_ip2xflags( | 823 | xfs_ip2xflags( |
830 | xfs_inode_t *ip) | 824 | xfs_inode_t *ip) |
831 | { | 825 | { |
832 | xfs_dinode_core_t *dic = &ip->i_d; | 826 | xfs_icdinode_t *dic = &ip->i_d; |
833 | 827 | ||
834 | return _xfs_dic2xflags(dic->di_flags) | | 828 | return _xfs_dic2xflags(dic->di_flags) | |
835 | (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); | 829 | (XFS_CFORK_Q(dic) ? XFS_XFLAG_HASATTR : 0); |
@@ -839,7 +833,7 @@ uint | |||
839 | xfs_dic2xflags( | 833 | xfs_dic2xflags( |
840 | xfs_dinode_core_t *dic) | 834 | xfs_dinode_core_t *dic) |
841 | { | 835 | { |
842 | return _xfs_dic2xflags(INT_GET(dic->di_flags, ARCH_CONVERT)) | | 836 | return _xfs_dic2xflags(be16_to_cpu(dic->di_flags)) | |
843 | (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); | 837 | (XFS_CFORK_Q_DISK(dic) ? XFS_XFLAG_HASATTR : 0); |
844 | } | 838 | } |
845 | 839 | ||
@@ -870,6 +864,7 @@ xfs_iread( | |||
870 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); | 864 | ip = kmem_zone_zalloc(xfs_inode_zone, KM_SLEEP); |
871 | ip->i_ino = ino; | 865 | ip->i_ino = ino; |
872 | ip->i_mount = mp; | 866 | ip->i_mount = mp; |
867 | atomic_set(&ip->i_iocount, 0); | ||
873 | spin_lock_init(&ip->i_flags_lock); | 868 | spin_lock_init(&ip->i_flags_lock); |
874 | 869 | ||
875 | /* | 870 | /* |
@@ -889,6 +884,9 @@ xfs_iread( | |||
889 | * Initialize inode's trace buffers. | 884 | * Initialize inode's trace buffers. |
890 | * Do this before xfs_iformat in case it adds entries. | 885 | * Do this before xfs_iformat in case it adds entries. |
891 | */ | 886 | */ |
887 | #ifdef XFS_VNODE_TRACE | ||
888 | ip->i_trace = ktrace_alloc(VNODE_TRACE_SIZE, KM_SLEEP); | ||
889 | #endif | ||
892 | #ifdef XFS_BMAP_TRACE | 890 | #ifdef XFS_BMAP_TRACE |
893 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP); | 891 | ip->i_xtrace = ktrace_alloc(XFS_BMAP_KTRACE_SIZE, KM_SLEEP); |
894 | #endif | 892 | #endif |
@@ -909,14 +907,14 @@ xfs_iread( | |||
909 | * If we got something that isn't an inode it means someone | 907 | * If we got something that isn't an inode it means someone |
910 | * (nfs or dmi) has a stale handle. | 908 | * (nfs or dmi) has a stale handle. |
911 | */ | 909 | */ |
912 | if (INT_GET(dip->di_core.di_magic, ARCH_CONVERT) != XFS_DINODE_MAGIC) { | 910 | if (be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC) { |
913 | kmem_zone_free(xfs_inode_zone, ip); | 911 | kmem_zone_free(xfs_inode_zone, ip); |
914 | xfs_trans_brelse(tp, bp); | 912 | xfs_trans_brelse(tp, bp); |
915 | #ifdef DEBUG | 913 | #ifdef DEBUG |
916 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " | 914 | xfs_fs_cmn_err(CE_ALERT, mp, "xfs_iread: " |
917 | "dip->di_core.di_magic (0x%x) != " | 915 | "dip->di_core.di_magic (0x%x) != " |
918 | "XFS_DINODE_MAGIC (0x%x)", | 916 | "XFS_DINODE_MAGIC (0x%x)", |
919 | INT_GET(dip->di_core.di_magic, ARCH_CONVERT), | 917 | be16_to_cpu(dip->di_core.di_magic), |
920 | XFS_DINODE_MAGIC); | 918 | XFS_DINODE_MAGIC); |
921 | #endif /* DEBUG */ | 919 | #endif /* DEBUG */ |
922 | return XFS_ERROR(EINVAL); | 920 | return XFS_ERROR(EINVAL); |
@@ -930,8 +928,7 @@ xfs_iread( | |||
930 | * Otherwise, just get the truly permanent information. | 928 | * Otherwise, just get the truly permanent information. |
931 | */ | 929 | */ |
932 | if (dip->di_core.di_mode) { | 930 | if (dip->di_core.di_mode) { |
933 | xfs_xlate_dinode_core((xfs_caddr_t)&dip->di_core, | 931 | xfs_dinode_from_disk(&ip->i_d, &dip->di_core); |
934 | &(ip->i_d), 1); | ||
935 | error = xfs_iformat(ip, dip); | 932 | error = xfs_iformat(ip, dip); |
936 | if (error) { | 933 | if (error) { |
937 | kmem_zone_free(xfs_inode_zone, ip); | 934 | kmem_zone_free(xfs_inode_zone, ip); |
@@ -944,10 +941,10 @@ xfs_iread( | |||
944 | return error; | 941 | return error; |
945 | } | 942 | } |
946 | } else { | 943 | } else { |
947 | ip->i_d.di_magic = INT_GET(dip->di_core.di_magic, ARCH_CONVERT); | 944 | ip->i_d.di_magic = be16_to_cpu(dip->di_core.di_magic); |
948 | ip->i_d.di_version = INT_GET(dip->di_core.di_version, ARCH_CONVERT); | 945 | ip->i_d.di_version = dip->di_core.di_version; |
949 | ip->i_d.di_gen = INT_GET(dip->di_core.di_gen, ARCH_CONVERT); | 946 | ip->i_d.di_gen = be32_to_cpu(dip->di_core.di_gen); |
950 | ip->i_d.di_flushiter = INT_GET(dip->di_core.di_flushiter, ARCH_CONVERT); | 947 | ip->i_d.di_flushiter = be16_to_cpu(dip->di_core.di_flushiter); |
951 | /* | 948 | /* |
952 | * Make sure to pull in the mode here as well in | 949 | * Make sure to pull in the mode here as well in |
953 | * case the inode is released without being used. | 950 | * case the inode is released without being used. |
@@ -1048,7 +1045,7 @@ xfs_iread_extents( | |||
1048 | ifp->if_flags &= ~XFS_IFEXTENTS; | 1045 | ifp->if_flags &= ~XFS_IFEXTENTS; |
1049 | return error; | 1046 | return error; |
1050 | } | 1047 | } |
1051 | xfs_validate_extents(ifp, nextents, 0, XFS_EXTFMT_INODE(ip)); | 1048 | xfs_validate_extents(ifp, nextents, XFS_EXTFMT_INODE(ip)); |
1052 | return 0; | 1049 | return 0; |
1053 | } | 1050 | } |
1054 | 1051 | ||
@@ -1161,7 +1158,7 @@ xfs_ialloc( | |||
1161 | if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) | 1158 | if ((prid != 0) && (ip->i_d.di_version == XFS_DINODE_VERSION_1)) |
1162 | xfs_bump_ino_vers2(tp, ip); | 1159 | xfs_bump_ino_vers2(tp, ip); |
1163 | 1160 | ||
1164 | if (pip && XFS_INHERIT_GID(pip, vp->v_vfsp)) { | 1161 | if (pip && XFS_INHERIT_GID(pip)) { |
1165 | ip->i_d.di_gid = pip->i_d.di_gid; | 1162 | ip->i_d.di_gid = pip->i_d.di_gid; |
1166 | if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { | 1163 | if ((pip->i_d.di_mode & S_ISGID) && (mode & S_IFMT) == S_IFDIR) { |
1167 | ip->i_d.di_mode |= S_ISGID; | 1164 | ip->i_d.di_mode |= S_ISGID; |
@@ -1275,7 +1272,7 @@ xfs_ialloc( | |||
1275 | xfs_trans_log_inode(tp, ip, flags); | 1272 | xfs_trans_log_inode(tp, ip, flags); |
1276 | 1273 | ||
1277 | /* now that we have an i_mode we can setup inode ops and unlock */ | 1274 | /* now that we have an i_mode we can setup inode ops and unlock */ |
1278 | bhv_vfs_init_vnode(XFS_MTOVFS(tp->t_mountp), vp, XFS_ITOBHV(ip), 1); | 1275 | xfs_initialize_vnode(tp->t_mountp, vp, ip); |
1279 | 1276 | ||
1280 | *ipp = ip; | 1277 | *ipp = ip; |
1281 | return 0; | 1278 | return 0; |
@@ -1462,7 +1459,7 @@ xfs_itruncate_start( | |||
1462 | mp = ip->i_mount; | 1459 | mp = ip->i_mount; |
1463 | vp = XFS_ITOV(ip); | 1460 | vp = XFS_ITOV(ip); |
1464 | 1461 | ||
1465 | vn_iowait(vp); /* wait for the completion of any pending DIOs */ | 1462 | vn_iowait(ip); /* wait for the completion of any pending DIOs */ |
1466 | 1463 | ||
1467 | /* | 1464 | /* |
1468 | * Call toss_pages or flushinval_pages to get rid of pages | 1465 | * Call toss_pages or flushinval_pages to get rid of pages |
@@ -1497,9 +1494,11 @@ xfs_itruncate_start( | |||
1497 | last_byte); | 1494 | last_byte); |
1498 | if (last_byte > toss_start) { | 1495 | if (last_byte > toss_start) { |
1499 | if (flags & XFS_ITRUNC_DEFINITE) { | 1496 | if (flags & XFS_ITRUNC_DEFINITE) { |
1500 | bhv_vop_toss_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); | 1497 | xfs_tosspages(ip, toss_start, |
1498 | -1, FI_REMAPF_LOCKED); | ||
1501 | } else { | 1499 | } else { |
1502 | error = bhv_vop_flushinval_pages(vp, toss_start, -1, FI_REMAPF_LOCKED); | 1500 | error = xfs_flushinval_pages(ip, toss_start, |
1501 | -1, FI_REMAPF_LOCKED); | ||
1503 | } | 1502 | } |
1504 | } | 1503 | } |
1505 | 1504 | ||
@@ -1932,9 +1931,9 @@ xfs_iunlink( | |||
1932 | */ | 1931 | */ |
1933 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr, | 1932 | error = xfs_trans_read_buf(mp, tp, mp->m_ddev_targp, agdaddr, |
1934 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); | 1933 | XFS_FSS_TO_BB(mp, 1), 0, &agibp); |
1935 | if (error) { | 1934 | if (error) |
1936 | return error; | 1935 | return error; |
1937 | } | 1936 | |
1938 | /* | 1937 | /* |
1939 | * Validate the magic number of the agi block. | 1938 | * Validate the magic number of the agi block. |
1940 | */ | 1939 | */ |
@@ -1958,6 +1957,24 @@ xfs_iunlink( | |||
1958 | ASSERT(agi->agi_unlinked[bucket_index]); | 1957 | ASSERT(agi->agi_unlinked[bucket_index]); |
1959 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); | 1958 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); |
1960 | 1959 | ||
1960 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0); | ||
1961 | if (error) | ||
1962 | return error; | ||
1963 | |||
1964 | /* | ||
1965 | * Clear the on-disk di_nlink. This is to prevent xfs_bulkstat | ||
1966 | * from picking up this inode when it is reclaimed (its incore state | ||
1967 | * initialzed but not flushed to disk yet). The in-core di_nlink is | ||
1968 | * already cleared in xfs_droplink() and a corresponding transaction | ||
1969 | * logged. The hack here just synchronizes the in-core to on-disk | ||
1970 | * di_nlink value in advance before the actual inode sync to disk. | ||
1971 | * This is OK because the inode is already unlinked and would never | ||
1972 | * change its di_nlink again for this inode generation. | ||
1973 | * This is a temporary hack that would require a proper fix | ||
1974 | * in the future. | ||
1975 | */ | ||
1976 | dip->di_core.di_nlink = 0; | ||
1977 | |||
1961 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) { | 1978 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) { |
1962 | /* | 1979 | /* |
1963 | * There is already another inode in the bucket we need | 1980 | * There is already another inode in the bucket we need |
@@ -1965,12 +1982,7 @@ xfs_iunlink( | |||
1965 | * Here we put the head pointer into our next pointer, | 1982 | * Here we put the head pointer into our next pointer, |
1966 | * and then we fall through to point the head at us. | 1983 | * and then we fall through to point the head at us. |
1967 | */ | 1984 | */ |
1968 | error = xfs_itobp(mp, tp, ip, &dip, &ibp, 0, 0); | 1985 | ASSERT(be32_to_cpu(dip->di_next_unlinked) == NULLAGINO); |
1969 | if (error) { | ||
1970 | return error; | ||
1971 | } | ||
1972 | ASSERT(INT_GET(dip->di_next_unlinked, ARCH_CONVERT) == NULLAGINO); | ||
1973 | ASSERT(dip->di_next_unlinked); | ||
1974 | /* both on-disk, don't endian flip twice */ | 1986 | /* both on-disk, don't endian flip twice */ |
1975 | dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; | 1987 | dip->di_next_unlinked = agi->agi_unlinked[bucket_index]; |
1976 | offset = ip->i_boffset + | 1988 | offset = ip->i_boffset + |
@@ -2081,10 +2093,10 @@ xfs_iunlink_remove( | |||
2081 | error, mp->m_fsname); | 2093 | error, mp->m_fsname); |
2082 | return error; | 2094 | return error; |
2083 | } | 2095 | } |
2084 | next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT); | 2096 | next_agino = be32_to_cpu(dip->di_next_unlinked); |
2085 | ASSERT(next_agino != 0); | 2097 | ASSERT(next_agino != 0); |
2086 | if (next_agino != NULLAGINO) { | 2098 | if (next_agino != NULLAGINO) { |
2087 | INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO); | 2099 | dip->di_next_unlinked = cpu_to_be32(NULLAGINO); |
2088 | offset = ip->i_boffset + | 2100 | offset = ip->i_boffset + |
2089 | offsetof(xfs_dinode_t, di_next_unlinked); | 2101 | offsetof(xfs_dinode_t, di_next_unlinked); |
2090 | xfs_trans_inode_buf(tp, ibp); | 2102 | xfs_trans_inode_buf(tp, ibp); |
@@ -2128,7 +2140,7 @@ xfs_iunlink_remove( | |||
2128 | error, mp->m_fsname); | 2140 | error, mp->m_fsname); |
2129 | return error; | 2141 | return error; |
2130 | } | 2142 | } |
2131 | next_agino = INT_GET(last_dip->di_next_unlinked, ARCH_CONVERT); | 2143 | next_agino = be32_to_cpu(last_dip->di_next_unlinked); |
2132 | ASSERT(next_agino != NULLAGINO); | 2144 | ASSERT(next_agino != NULLAGINO); |
2133 | ASSERT(next_agino != 0); | 2145 | ASSERT(next_agino != 0); |
2134 | } | 2146 | } |
@@ -2143,11 +2155,11 @@ xfs_iunlink_remove( | |||
2143 | error, mp->m_fsname); | 2155 | error, mp->m_fsname); |
2144 | return error; | 2156 | return error; |
2145 | } | 2157 | } |
2146 | next_agino = INT_GET(dip->di_next_unlinked, ARCH_CONVERT); | 2158 | next_agino = be32_to_cpu(dip->di_next_unlinked); |
2147 | ASSERT(next_agino != 0); | 2159 | ASSERT(next_agino != 0); |
2148 | ASSERT(next_agino != agino); | 2160 | ASSERT(next_agino != agino); |
2149 | if (next_agino != NULLAGINO) { | 2161 | if (next_agino != NULLAGINO) { |
2150 | INT_SET(dip->di_next_unlinked, ARCH_CONVERT, NULLAGINO); | 2162 | dip->di_next_unlinked = cpu_to_be32(NULLAGINO); |
2151 | offset = ip->i_boffset + | 2163 | offset = ip->i_boffset + |
2152 | offsetof(xfs_dinode_t, di_next_unlinked); | 2164 | offsetof(xfs_dinode_t, di_next_unlinked); |
2153 | xfs_trans_inode_buf(tp, ibp); | 2165 | xfs_trans_inode_buf(tp, ibp); |
@@ -2160,7 +2172,7 @@ xfs_iunlink_remove( | |||
2160 | /* | 2172 | /* |
2161 | * Point the previous inode on the list to the next inode. | 2173 | * Point the previous inode on the list to the next inode. |
2162 | */ | 2174 | */ |
2163 | INT_SET(last_dip->di_next_unlinked, ARCH_CONVERT, next_agino); | 2175 | last_dip->di_next_unlinked = cpu_to_be32(next_agino); |
2164 | ASSERT(next_agino != 0); | 2176 | ASSERT(next_agino != 0); |
2165 | offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked); | 2177 | offset = last_offset + offsetof(xfs_dinode_t, di_next_unlinked); |
2166 | xfs_trans_inode_buf(tp, last_ibp); | 2178 | xfs_trans_inode_buf(tp, last_ibp); |
@@ -2191,10 +2203,10 @@ xfs_ifree_cluster( | |||
2191 | int i, j, found, pre_flushed; | 2203 | int i, j, found, pre_flushed; |
2192 | xfs_daddr_t blkno; | 2204 | xfs_daddr_t blkno; |
2193 | xfs_buf_t *bp; | 2205 | xfs_buf_t *bp; |
2194 | xfs_ihash_t *ih; | ||
2195 | xfs_inode_t *ip, **ip_found; | 2206 | xfs_inode_t *ip, **ip_found; |
2196 | xfs_inode_log_item_t *iip; | 2207 | xfs_inode_log_item_t *iip; |
2197 | xfs_log_item_t *lip; | 2208 | xfs_log_item_t *lip; |
2209 | xfs_perag_t *pag = xfs_get_perag(mp, inum); | ||
2198 | SPLDECL(s); | 2210 | SPLDECL(s); |
2199 | 2211 | ||
2200 | if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { | 2212 | if (mp->m_sb.sb_blocksize >= XFS_INODE_CLUSTER_SIZE(mp)) { |
@@ -2229,23 +2241,20 @@ xfs_ifree_cluster( | |||
2229 | */ | 2241 | */ |
2230 | found = 0; | 2242 | found = 0; |
2231 | for (i = 0; i < ninodes; i++) { | 2243 | for (i = 0; i < ninodes; i++) { |
2232 | ih = XFS_IHASH(mp, inum + i); | 2244 | read_lock(&pag->pag_ici_lock); |
2233 | read_lock(&ih->ih_lock); | 2245 | ip = radix_tree_lookup(&pag->pag_ici_root, |
2234 | for (ip = ih->ih_next; ip != NULL; ip = ip->i_next) { | 2246 | XFS_INO_TO_AGINO(mp, (inum + i))); |
2235 | if (ip->i_ino == inum + i) | ||
2236 | break; | ||
2237 | } | ||
2238 | 2247 | ||
2239 | /* Inode not in memory or we found it already, | 2248 | /* Inode not in memory or we found it already, |
2240 | * nothing to do | 2249 | * nothing to do |
2241 | */ | 2250 | */ |
2242 | if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { | 2251 | if (!ip || xfs_iflags_test(ip, XFS_ISTALE)) { |
2243 | read_unlock(&ih->ih_lock); | 2252 | read_unlock(&pag->pag_ici_lock); |
2244 | continue; | 2253 | continue; |
2245 | } | 2254 | } |
2246 | 2255 | ||
2247 | if (xfs_inode_clean(ip)) { | 2256 | if (xfs_inode_clean(ip)) { |
2248 | read_unlock(&ih->ih_lock); | 2257 | read_unlock(&pag->pag_ici_lock); |
2249 | continue; | 2258 | continue; |
2250 | } | 2259 | } |
2251 | 2260 | ||
@@ -2268,7 +2277,7 @@ xfs_ifree_cluster( | |||
2268 | ip_found[found++] = ip; | 2277 | ip_found[found++] = ip; |
2269 | } | 2278 | } |
2270 | } | 2279 | } |
2271 | read_unlock(&ih->ih_lock); | 2280 | read_unlock(&pag->pag_ici_lock); |
2272 | continue; | 2281 | continue; |
2273 | } | 2282 | } |
2274 | 2283 | ||
@@ -2286,8 +2295,7 @@ xfs_ifree_cluster( | |||
2286 | xfs_iunlock(ip, XFS_ILOCK_EXCL); | 2295 | xfs_iunlock(ip, XFS_ILOCK_EXCL); |
2287 | } | 2296 | } |
2288 | } | 2297 | } |
2289 | 2298 | read_unlock(&pag->pag_ici_lock); | |
2290 | read_unlock(&ih->ih_lock); | ||
2291 | } | 2299 | } |
2292 | 2300 | ||
2293 | bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, | 2301 | bp = xfs_trans_get_buf(tp, mp->m_ddev_targp, blkno, |
@@ -2342,6 +2350,7 @@ xfs_ifree_cluster( | |||
2342 | } | 2350 | } |
2343 | 2351 | ||
2344 | kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *)); | 2352 | kmem_free(ip_found, ninodes * sizeof(xfs_inode_t *)); |
2353 | xfs_put_perag(mp, pag); | ||
2345 | } | 2354 | } |
2346 | 2355 | ||
2347 | /* | 2356 | /* |
@@ -2737,6 +2746,10 @@ xfs_idestroy( | |||
2737 | mrfree(&ip->i_lock); | 2746 | mrfree(&ip->i_lock); |
2738 | mrfree(&ip->i_iolock); | 2747 | mrfree(&ip->i_iolock); |
2739 | freesema(&ip->i_flock); | 2748 | freesema(&ip->i_flock); |
2749 | |||
2750 | #ifdef XFS_VNODE_TRACE | ||
2751 | ktrace_free(ip->i_trace); | ||
2752 | #endif | ||
2740 | #ifdef XFS_BMAP_TRACE | 2753 | #ifdef XFS_BMAP_TRACE |
2741 | ktrace_free(ip->i_xtrace); | 2754 | ktrace_free(ip->i_xtrace); |
2742 | #endif | 2755 | #endif |
@@ -2887,12 +2900,10 @@ xfs_iunpin_wait( | |||
2887 | int | 2900 | int |
2888 | xfs_iextents_copy( | 2901 | xfs_iextents_copy( |
2889 | xfs_inode_t *ip, | 2902 | xfs_inode_t *ip, |
2890 | xfs_bmbt_rec_t *buffer, | 2903 | xfs_bmbt_rec_t *dp, |
2891 | int whichfork) | 2904 | int whichfork) |
2892 | { | 2905 | { |
2893 | int copied; | 2906 | int copied; |
2894 | xfs_bmbt_rec_t *dest_ep; | ||
2895 | xfs_bmbt_rec_t *ep; | ||
2896 | int i; | 2907 | int i; |
2897 | xfs_ifork_t *ifp; | 2908 | xfs_ifork_t *ifp; |
2898 | int nrecs; | 2909 | int nrecs; |
@@ -2912,10 +2923,9 @@ xfs_iextents_copy( | |||
2912 | * the delayed ones. There must be at least one | 2923 | * the delayed ones. There must be at least one |
2913 | * non-delayed extent. | 2924 | * non-delayed extent. |
2914 | */ | 2925 | */ |
2915 | dest_ep = buffer; | ||
2916 | copied = 0; | 2926 | copied = 0; |
2917 | for (i = 0; i < nrecs; i++) { | 2927 | for (i = 0; i < nrecs; i++) { |
2918 | ep = xfs_iext_get_ext(ifp, i); | 2928 | xfs_bmbt_rec_host_t *ep = xfs_iext_get_ext(ifp, i); |
2919 | start_block = xfs_bmbt_get_startblock(ep); | 2929 | start_block = xfs_bmbt_get_startblock(ep); |
2920 | if (ISNULLSTARTBLOCK(start_block)) { | 2930 | if (ISNULLSTARTBLOCK(start_block)) { |
2921 | /* | 2931 | /* |
@@ -2925,15 +2935,13 @@ xfs_iextents_copy( | |||
2925 | } | 2935 | } |
2926 | 2936 | ||
2927 | /* Translate to on disk format */ | 2937 | /* Translate to on disk format */ |
2928 | put_unaligned(INT_GET(ep->l0, ARCH_CONVERT), | 2938 | put_unaligned(cpu_to_be64(ep->l0), &dp->l0); |
2929 | (__uint64_t*)&dest_ep->l0); | 2939 | put_unaligned(cpu_to_be64(ep->l1), &dp->l1); |
2930 | put_unaligned(INT_GET(ep->l1, ARCH_CONVERT), | 2940 | dp++; |
2931 | (__uint64_t*)&dest_ep->l1); | ||
2932 | dest_ep++; | ||
2933 | copied++; | 2941 | copied++; |
2934 | } | 2942 | } |
2935 | ASSERT(copied != 0); | 2943 | ASSERT(copied != 0); |
2936 | xfs_validate_extents(ifp, copied, 1, XFS_EXTFMT_INODE(ip)); | 2944 | xfs_validate_extents(ifp, copied, XFS_EXTFMT_INODE(ip)); |
2937 | 2945 | ||
2938 | return (copied * (uint)sizeof(xfs_bmbt_rec_t)); | 2946 | return (copied * (uint)sizeof(xfs_bmbt_rec_t)); |
2939 | } | 2947 | } |
@@ -3024,7 +3032,7 @@ xfs_iflush_fork( | |||
3024 | case XFS_DINODE_FMT_DEV: | 3032 | case XFS_DINODE_FMT_DEV: |
3025 | if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { | 3033 | if (iip->ili_format.ilf_fields & XFS_ILOG_DEV) { |
3026 | ASSERT(whichfork == XFS_DATA_FORK); | 3034 | ASSERT(whichfork == XFS_DATA_FORK); |
3027 | INT_SET(dip->di_u.di_dev, ARCH_CONVERT, ip->i_df.if_u2.if_rdev); | 3035 | dip->di_u.di_dev = cpu_to_be32(ip->i_df.if_u2.if_rdev); |
3028 | } | 3036 | } |
3029 | break; | 3037 | break; |
3030 | 3038 | ||
@@ -3064,12 +3072,11 @@ xfs_iflush( | |||
3064 | xfs_mount_t *mp; | 3072 | xfs_mount_t *mp; |
3065 | int error; | 3073 | int error; |
3066 | /* REFERENCED */ | 3074 | /* REFERENCED */ |
3067 | xfs_chash_t *ch; | ||
3068 | xfs_inode_t *iq; | 3075 | xfs_inode_t *iq; |
3069 | int clcount; /* count of inodes clustered */ | 3076 | int clcount; /* count of inodes clustered */ |
3070 | int bufwasdelwri; | 3077 | int bufwasdelwri; |
3078 | struct hlist_node *entry; | ||
3071 | enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) }; | 3079 | enum { INT_DELWRI = (1 << 0), INT_ASYNC = (1 << 1) }; |
3072 | SPLDECL(s); | ||
3073 | 3080 | ||
3074 | XFS_STATS_INC(xs_iflush_count); | 3081 | XFS_STATS_INC(xs_iflush_count); |
3075 | 3082 | ||
@@ -3183,14 +3190,14 @@ xfs_iflush( | |||
3183 | * inode clustering: | 3190 | * inode clustering: |
3184 | * see if other inodes can be gathered into this write | 3191 | * see if other inodes can be gathered into this write |
3185 | */ | 3192 | */ |
3186 | 3193 | spin_lock(&ip->i_cluster->icl_lock); | |
3187 | ip->i_chash->chl_buf = bp; | 3194 | ip->i_cluster->icl_buf = bp; |
3188 | |||
3189 | ch = XFS_CHASH(mp, ip->i_blkno); | ||
3190 | s = mutex_spinlock(&ch->ch_lock); | ||
3191 | 3195 | ||
3192 | clcount = 0; | 3196 | clcount = 0; |
3193 | for (iq = ip->i_cnext; iq != ip; iq = iq->i_cnext) { | 3197 | hlist_for_each_entry(iq, entry, &ip->i_cluster->icl_inodes, i_cnode) { |
3198 | if (iq == ip) | ||
3199 | continue; | ||
3200 | |||
3194 | /* | 3201 | /* |
3195 | * Do an un-protected check to see if the inode is dirty and | 3202 | * Do an un-protected check to see if the inode is dirty and |
3196 | * is a candidate for flushing. These checks will be repeated | 3203 | * is a candidate for flushing. These checks will be repeated |
@@ -3241,7 +3248,7 @@ xfs_iflush( | |||
3241 | xfs_iunlock(iq, XFS_ILOCK_SHARED); | 3248 | xfs_iunlock(iq, XFS_ILOCK_SHARED); |
3242 | } | 3249 | } |
3243 | } | 3250 | } |
3244 | mutex_spinunlock(&ch->ch_lock, s); | 3251 | spin_unlock(&ip->i_cluster->icl_lock); |
3245 | 3252 | ||
3246 | if (clcount) { | 3253 | if (clcount) { |
3247 | XFS_STATS_INC(xs_icluster_flushcnt); | 3254 | XFS_STATS_INC(xs_icluster_flushcnt); |
@@ -3278,7 +3285,7 @@ cluster_corrupt_out: | |||
3278 | /* Corruption detected in the clustering loop. Invalidate the | 3285 | /* Corruption detected in the clustering loop. Invalidate the |
3279 | * inode buffer and shut down the filesystem. | 3286 | * inode buffer and shut down the filesystem. |
3280 | */ | 3287 | */ |
3281 | mutex_spinunlock(&ch->ch_lock, s); | 3288 | spin_unlock(&ip->i_cluster->icl_lock); |
3282 | 3289 | ||
3283 | /* | 3290 | /* |
3284 | * Clean up the buffer. If it was B_DELWRI, just release it -- | 3291 | * Clean up the buffer. If it was B_DELWRI, just release it -- |
@@ -3373,11 +3380,11 @@ xfs_iflush_int( | |||
3373 | */ | 3380 | */ |
3374 | xfs_synchronize_atime(ip); | 3381 | xfs_synchronize_atime(ip); |
3375 | 3382 | ||
3376 | if (XFS_TEST_ERROR(INT_GET(dip->di_core.di_magic,ARCH_CONVERT) != XFS_DINODE_MAGIC, | 3383 | if (XFS_TEST_ERROR(be16_to_cpu(dip->di_core.di_magic) != XFS_DINODE_MAGIC, |
3377 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { | 3384 | mp, XFS_ERRTAG_IFLUSH_1, XFS_RANDOM_IFLUSH_1)) { |
3378 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, | 3385 | xfs_cmn_err(XFS_PTAG_IFLUSH, CE_ALERT, mp, |
3379 | "xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p", | 3386 | "xfs_iflush: Bad inode %Lu magic number 0x%x, ptr 0x%p", |
3380 | ip->i_ino, (int) INT_GET(dip->di_core.di_magic, ARCH_CONVERT), dip); | 3387 | ip->i_ino, be16_to_cpu(dip->di_core.di_magic), dip); |
3381 | goto corrupt_out; | 3388 | goto corrupt_out; |
3382 | } | 3389 | } |
3383 | if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, | 3390 | if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, |
@@ -3440,7 +3447,7 @@ xfs_iflush_int( | |||
3440 | * because if the inode is dirty at all the core must | 3447 | * because if the inode is dirty at all the core must |
3441 | * be. | 3448 | * be. |
3442 | */ | 3449 | */ |
3443 | xfs_xlate_dinode_core((xfs_caddr_t)&(dip->di_core), &(ip->i_d), -1); | 3450 | xfs_dinode_to_disk(&dip->di_core, &ip->i_d); |
3444 | 3451 | ||
3445 | /* Wrap, we never let the log put out DI_MAX_FLUSH */ | 3452 | /* Wrap, we never let the log put out DI_MAX_FLUSH */ |
3446 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) | 3453 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) |
@@ -3460,7 +3467,7 @@ xfs_iflush_int( | |||
3460 | * Convert it back. | 3467 | * Convert it back. |
3461 | */ | 3468 | */ |
3462 | ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); | 3469 | ASSERT(ip->i_d.di_nlink <= XFS_MAXLINK_1); |
3463 | INT_SET(dip->di_core.di_onlink, ARCH_CONVERT, ip->i_d.di_nlink); | 3470 | dip->di_core.di_onlink = cpu_to_be16(ip->i_d.di_nlink); |
3464 | } else { | 3471 | } else { |
3465 | /* | 3472 | /* |
3466 | * The superblock version has already been bumped, | 3473 | * The superblock version has already been bumped, |
@@ -3468,7 +3475,7 @@ xfs_iflush_int( | |||
3468 | * format permanent. | 3475 | * format permanent. |
3469 | */ | 3476 | */ |
3470 | ip->i_d.di_version = XFS_DINODE_VERSION_2; | 3477 | ip->i_d.di_version = XFS_DINODE_VERSION_2; |
3471 | INT_SET(dip->di_core.di_version, ARCH_CONVERT, XFS_DINODE_VERSION_2); | 3478 | dip->di_core.di_version = XFS_DINODE_VERSION_2; |
3472 | ip->i_d.di_onlink = 0; | 3479 | ip->i_d.di_onlink = 0; |
3473 | dip->di_core.di_onlink = 0; | 3480 | dip->di_core.di_onlink = 0; |
3474 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | 3481 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); |
@@ -3711,7 +3718,7 @@ xfs_ilock_trace(xfs_inode_t *ip, int lock, unsigned int lockflags, inst_t *ra) | |||
3711 | /* | 3718 | /* |
3712 | * Return a pointer to the extent record at file index idx. | 3719 | * Return a pointer to the extent record at file index idx. |
3713 | */ | 3720 | */ |
3714 | xfs_bmbt_rec_t * | 3721 | xfs_bmbt_rec_host_t * |
3715 | xfs_iext_get_ext( | 3722 | xfs_iext_get_ext( |
3716 | xfs_ifork_t *ifp, /* inode fork pointer */ | 3723 | xfs_ifork_t *ifp, /* inode fork pointer */ |
3717 | xfs_extnum_t idx) /* index of target extent */ | 3724 | xfs_extnum_t idx) /* index of target extent */ |
@@ -3744,15 +3751,12 @@ xfs_iext_insert( | |||
3744 | xfs_extnum_t count, /* number of inserted items */ | 3751 | xfs_extnum_t count, /* number of inserted items */ |
3745 | xfs_bmbt_irec_t *new) /* items to insert */ | 3752 | xfs_bmbt_irec_t *new) /* items to insert */ |
3746 | { | 3753 | { |
3747 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | ||
3748 | xfs_extnum_t i; /* extent record index */ | 3754 | xfs_extnum_t i; /* extent record index */ |
3749 | 3755 | ||
3750 | ASSERT(ifp->if_flags & XFS_IFEXTENTS); | 3756 | ASSERT(ifp->if_flags & XFS_IFEXTENTS); |
3751 | xfs_iext_add(ifp, idx, count); | 3757 | xfs_iext_add(ifp, idx, count); |
3752 | for (i = idx; i < idx + count; i++, new++) { | 3758 | for (i = idx; i < idx + count; i++, new++) |
3753 | ep = xfs_iext_get_ext(ifp, i); | 3759 | xfs_bmbt_set_all(xfs_iext_get_ext(ifp, i), new); |
3754 | xfs_bmbt_set_all(ep, new); | ||
3755 | } | ||
3756 | } | 3760 | } |
3757 | 3761 | ||
3758 | /* | 3762 | /* |
@@ -4203,7 +4207,7 @@ xfs_iext_realloc_direct( | |||
4203 | rnew_size = xfs_iroundup(new_size); | 4207 | rnew_size = xfs_iroundup(new_size); |
4204 | } | 4208 | } |
4205 | if (rnew_size != ifp->if_real_bytes) { | 4209 | if (rnew_size != ifp->if_real_bytes) { |
4206 | ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) | 4210 | ifp->if_u1.if_extents = |
4207 | kmem_realloc(ifp->if_u1.if_extents, | 4211 | kmem_realloc(ifp->if_u1.if_extents, |
4208 | rnew_size, | 4212 | rnew_size, |
4209 | ifp->if_real_bytes, | 4213 | ifp->if_real_bytes, |
@@ -4266,8 +4270,7 @@ xfs_iext_inline_to_direct( | |||
4266 | xfs_ifork_t *ifp, /* inode fork pointer */ | 4270 | xfs_ifork_t *ifp, /* inode fork pointer */ |
4267 | int new_size) /* number of extents in file */ | 4271 | int new_size) /* number of extents in file */ |
4268 | { | 4272 | { |
4269 | ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) | 4273 | ifp->if_u1.if_extents = kmem_alloc(new_size, KM_SLEEP); |
4270 | kmem_alloc(new_size, KM_SLEEP); | ||
4271 | memset(ifp->if_u1.if_extents, 0, new_size); | 4274 | memset(ifp->if_u1.if_extents, 0, new_size); |
4272 | if (ifp->if_bytes) { | 4275 | if (ifp->if_bytes) { |
4273 | memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, | 4276 | memcpy(ifp->if_u1.if_extents, ifp->if_u2.if_inline_ext, |
@@ -4310,7 +4313,7 @@ void | |||
4310 | xfs_iext_indirect_to_direct( | 4313 | xfs_iext_indirect_to_direct( |
4311 | xfs_ifork_t *ifp) /* inode fork pointer */ | 4314 | xfs_ifork_t *ifp) /* inode fork pointer */ |
4312 | { | 4315 | { |
4313 | xfs_bmbt_rec_t *ep; /* extent record pointer */ | 4316 | xfs_bmbt_rec_host_t *ep; /* extent record pointer */ |
4314 | xfs_extnum_t nextents; /* number of extents in file */ | 4317 | xfs_extnum_t nextents; /* number of extents in file */ |
4315 | int size; /* size of file extents */ | 4318 | int size; /* size of file extents */ |
4316 | 4319 | ||
@@ -4362,15 +4365,15 @@ xfs_iext_destroy( | |||
4362 | /* | 4365 | /* |
4363 | * Return a pointer to the extent record for file system block bno. | 4366 | * Return a pointer to the extent record for file system block bno. |
4364 | */ | 4367 | */ |
4365 | xfs_bmbt_rec_t * /* pointer to found extent record */ | 4368 | xfs_bmbt_rec_host_t * /* pointer to found extent record */ |
4366 | xfs_iext_bno_to_ext( | 4369 | xfs_iext_bno_to_ext( |
4367 | xfs_ifork_t *ifp, /* inode fork pointer */ | 4370 | xfs_ifork_t *ifp, /* inode fork pointer */ |
4368 | xfs_fileoff_t bno, /* block number to search for */ | 4371 | xfs_fileoff_t bno, /* block number to search for */ |
4369 | xfs_extnum_t *idxp) /* index of target extent */ | 4372 | xfs_extnum_t *idxp) /* index of target extent */ |
4370 | { | 4373 | { |
4371 | xfs_bmbt_rec_t *base; /* pointer to first extent */ | 4374 | xfs_bmbt_rec_host_t *base; /* pointer to first extent */ |
4372 | xfs_filblks_t blockcount = 0; /* number of blocks in extent */ | 4375 | xfs_filblks_t blockcount = 0; /* number of blocks in extent */ |
4373 | xfs_bmbt_rec_t *ep = NULL; /* pointer to target extent */ | 4376 | xfs_bmbt_rec_host_t *ep = NULL; /* pointer to target extent */ |
4374 | xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ | 4377 | xfs_ext_irec_t *erp = NULL; /* indirection array pointer */ |
4375 | int high; /* upper boundary in search */ | 4378 | int high; /* upper boundary in search */ |
4376 | xfs_extnum_t idx = 0; /* index of target extent */ | 4379 | xfs_extnum_t idx = 0; /* index of target extent */ |
@@ -4545,8 +4548,7 @@ xfs_iext_irec_init( | |||
4545 | kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP); | 4548 | kmem_alloc(sizeof(xfs_ext_irec_t), KM_SLEEP); |
4546 | 4549 | ||
4547 | if (nextents == 0) { | 4550 | if (nextents == 0) { |
4548 | ifp->if_u1.if_extents = (xfs_bmbt_rec_t *) | 4551 | ifp->if_u1.if_extents = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); |
4549 | kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); | ||
4550 | } else if (!ifp->if_real_bytes) { | 4552 | } else if (!ifp->if_real_bytes) { |
4551 | xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); | 4553 | xfs_iext_inline_to_direct(ifp, XFS_IEXT_BUFSZ); |
4552 | } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { | 4554 | } else if (ifp->if_real_bytes < XFS_IEXT_BUFSZ) { |
@@ -4594,8 +4596,7 @@ xfs_iext_irec_new( | |||
4594 | 4596 | ||
4595 | /* Initialize new extent record */ | 4597 | /* Initialize new extent record */ |
4596 | erp = ifp->if_u1.if_ext_irec; | 4598 | erp = ifp->if_u1.if_ext_irec; |
4597 | erp[erp_idx].er_extbuf = (xfs_bmbt_rec_t *) | 4599 | erp[erp_idx].er_extbuf = kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); |
4598 | kmem_alloc(XFS_IEXT_BUFSZ, KM_SLEEP); | ||
4599 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; | 4600 | ifp->if_real_bytes = nlists * XFS_IEXT_BUFSZ; |
4600 | memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); | 4601 | memset(erp[erp_idx].er_extbuf, 0, XFS_IEXT_BUFSZ); |
4601 | erp[erp_idx].er_extcount = 0; | 4602 | erp[erp_idx].er_extcount = 0; |
@@ -4727,7 +4728,7 @@ void | |||
4727 | xfs_iext_irec_compact_full( | 4728 | xfs_iext_irec_compact_full( |
4728 | xfs_ifork_t *ifp) /* inode fork pointer */ | 4729 | xfs_ifork_t *ifp) /* inode fork pointer */ |
4729 | { | 4730 | { |
4730 | xfs_bmbt_rec_t *ep, *ep_next; /* extent record pointers */ | 4731 | xfs_bmbt_rec_host_t *ep, *ep_next; /* extent record pointers */ |
4731 | xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */ | 4732 | xfs_ext_irec_t *erp, *erp_next; /* extent irec pointers */ |
4732 | int erp_idx = 0; /* extent irec index */ | 4733 | int erp_idx = 0; /* extent irec index */ |
4733 | int ext_avail; /* empty entries in ex list */ | 4734 | int ext_avail; /* empty entries in ex list */ |