aboutsummaryrefslogtreecommitdiffstats
path: root/fs/xfs/xfs_inode.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r--fs/xfs/xfs_inode.c383
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
55kmem_zone_t *xfs_ifork_zone; 54kmem_zone_t *xfs_ifork_zone;
56kmem_zone_t *xfs_inode_zone; 55kmem_zone_t *xfs_inode_zone;
57kmem_zone_t *xfs_chashlist_zone; 56kmem_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);
67STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int); 66STATIC int xfs_iformat_extents(xfs_inode_t *, xfs_dinode_t *, int);
68STATIC int xfs_iformat_btree(xfs_inode_t *, xfs_dinode_t *, int); 67STATIC 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
77xfs_validate_extents( 75xfs_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 */
731void 712void
732xfs_xlate_dinode_core( 713xfs_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, 747void
768 dir, arch); 748xfs_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
788STATIC uint 782STATIC uint
@@ -829,7 +823,7 @@ uint
829xfs_ip2xflags( 823xfs_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
839xfs_dic2xflags( 833xfs_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(
2887int 2900int
2888xfs_iextents_copy( 2901xfs_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 */
3714xfs_bmbt_rec_t * 3721xfs_bmbt_rec_host_t *
3715xfs_iext_get_ext( 3722xfs_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
4310xfs_iext_indirect_to_direct( 4313xfs_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 */
4365xfs_bmbt_rec_t * /* pointer to found extent record */ 4368xfs_bmbt_rec_host_t * /* pointer to found extent record */
4366xfs_iext_bno_to_ext( 4369xfs_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
4727xfs_iext_irec_compact_full( 4728xfs_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 */