diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 174 |
1 files changed, 71 insertions, 103 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index ceba1a83cacc..96f606deee31 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -57,9 +57,9 @@ kmem_zone_t *xfs_inode_zone; | |||
57 | */ | 57 | */ |
58 | #define XFS_ITRUNC_MAX_EXTENTS 2 | 58 | #define XFS_ITRUNC_MAX_EXTENTS 2 |
59 | 59 | ||
60 | STATIC int xfs_iflush_int(xfs_inode_t *, xfs_buf_t *); | 60 | STATIC int xfs_iflush_int(struct xfs_inode *, struct xfs_buf *); |
61 | 61 | STATIC int xfs_iunlink(struct xfs_trans *, struct xfs_inode *); | |
62 | STATIC int xfs_iunlink_remove(xfs_trans_t *, xfs_inode_t *); | 62 | STATIC int xfs_iunlink_remove(struct xfs_trans *, struct xfs_inode *); |
63 | 63 | ||
64 | /* | 64 | /* |
65 | * helper function to extract extent size hint from inode | 65 | * helper function to extract extent size hint from inode |
@@ -766,6 +766,7 @@ xfs_ialloc( | |||
766 | uint flags; | 766 | uint flags; |
767 | int error; | 767 | int error; |
768 | struct timespec tv; | 768 | struct timespec tv; |
769 | struct inode *inode; | ||
769 | 770 | ||
770 | /* | 771 | /* |
771 | * Call the space management code to pick | 772 | * Call the space management code to pick |
@@ -791,6 +792,7 @@ xfs_ialloc( | |||
791 | if (error) | 792 | if (error) |
792 | return error; | 793 | return error; |
793 | ASSERT(ip != NULL); | 794 | ASSERT(ip != NULL); |
795 | inode = VFS_I(ip); | ||
794 | 796 | ||
795 | /* | 797 | /* |
796 | * We always convert v1 inodes to v2 now - we only support filesystems | 798 | * We always convert v1 inodes to v2 now - we only support filesystems |
@@ -800,20 +802,16 @@ xfs_ialloc( | |||
800 | if (ip->i_d.di_version == 1) | 802 | if (ip->i_d.di_version == 1) |
801 | ip->i_d.di_version = 2; | 803 | ip->i_d.di_version = 2; |
802 | 804 | ||
803 | ip->i_d.di_mode = mode; | 805 | inode->i_mode = mode; |
804 | ip->i_d.di_onlink = 0; | 806 | set_nlink(inode, nlink); |
805 | ip->i_d.di_nlink = nlink; | ||
806 | ASSERT(ip->i_d.di_nlink == nlink); | ||
807 | ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid()); | 807 | ip->i_d.di_uid = xfs_kuid_to_uid(current_fsuid()); |
808 | ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid()); | 808 | ip->i_d.di_gid = xfs_kgid_to_gid(current_fsgid()); |
809 | xfs_set_projid(ip, prid); | 809 | xfs_set_projid(ip, prid); |
810 | memset(&(ip->i_d.di_pad[0]), 0, sizeof(ip->i_d.di_pad)); | ||
811 | 810 | ||
812 | if (pip && XFS_INHERIT_GID(pip)) { | 811 | if (pip && XFS_INHERIT_GID(pip)) { |
813 | ip->i_d.di_gid = pip->i_d.di_gid; | 812 | ip->i_d.di_gid = pip->i_d.di_gid; |
814 | if ((pip->i_d.di_mode & S_ISGID) && S_ISDIR(mode)) { | 813 | if ((VFS_I(pip)->i_mode & S_ISGID) && S_ISDIR(mode)) |
815 | ip->i_d.di_mode |= S_ISGID; | 814 | inode->i_mode |= S_ISGID; |
816 | } | ||
817 | } | 815 | } |
818 | 816 | ||
819 | /* | 817 | /* |
@@ -822,38 +820,29 @@ xfs_ialloc( | |||
822 | * (and only if the irix_sgid_inherit compatibility variable is set). | 820 | * (and only if the irix_sgid_inherit compatibility variable is set). |
823 | */ | 821 | */ |
824 | if ((irix_sgid_inherit) && | 822 | if ((irix_sgid_inherit) && |
825 | (ip->i_d.di_mode & S_ISGID) && | 823 | (inode->i_mode & S_ISGID) && |
826 | (!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid)))) { | 824 | (!in_group_p(xfs_gid_to_kgid(ip->i_d.di_gid)))) |
827 | ip->i_d.di_mode &= ~S_ISGID; | 825 | inode->i_mode &= ~S_ISGID; |
828 | } | ||
829 | 826 | ||
830 | ip->i_d.di_size = 0; | 827 | ip->i_d.di_size = 0; |
831 | ip->i_d.di_nextents = 0; | 828 | ip->i_d.di_nextents = 0; |
832 | ASSERT(ip->i_d.di_nblocks == 0); | 829 | ASSERT(ip->i_d.di_nblocks == 0); |
833 | 830 | ||
834 | tv = current_fs_time(mp->m_super); | 831 | tv = current_fs_time(mp->m_super); |
835 | ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; | 832 | inode->i_mtime = tv; |
836 | ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; | 833 | inode->i_atime = tv; |
837 | ip->i_d.di_atime = ip->i_d.di_mtime; | 834 | inode->i_ctime = tv; |
838 | ip->i_d.di_ctime = ip->i_d.di_mtime; | ||
839 | 835 | ||
840 | /* | ||
841 | * di_gen will have been taken care of in xfs_iread. | ||
842 | */ | ||
843 | ip->i_d.di_extsize = 0; | 836 | ip->i_d.di_extsize = 0; |
844 | ip->i_d.di_dmevmask = 0; | 837 | ip->i_d.di_dmevmask = 0; |
845 | ip->i_d.di_dmstate = 0; | 838 | ip->i_d.di_dmstate = 0; |
846 | ip->i_d.di_flags = 0; | 839 | ip->i_d.di_flags = 0; |
847 | 840 | ||
848 | if (ip->i_d.di_version == 3) { | 841 | if (ip->i_d.di_version == 3) { |
849 | ASSERT(ip->i_d.di_ino == ino); | 842 | inode->i_version = 1; |
850 | ASSERT(uuid_equal(&ip->i_d.di_uuid, &mp->m_sb.sb_meta_uuid)); | ||
851 | ip->i_d.di_crc = 0; | ||
852 | ip->i_d.di_changecount = 1; | ||
853 | ip->i_d.di_lsn = 0; | ||
854 | ip->i_d.di_flags2 = 0; | 843 | ip->i_d.di_flags2 = 0; |
855 | memset(&(ip->i_d.di_pad2[0]), 0, sizeof(ip->i_d.di_pad2)); | 844 | ip->i_d.di_crtime.t_sec = (__int32_t)tv.tv_sec; |
856 | ip->i_d.di_crtime = ip->i_d.di_mtime; | 845 | ip->i_d.di_crtime.t_nsec = (__int32_t)tv.tv_nsec; |
857 | } | 846 | } |
858 | 847 | ||
859 | 848 | ||
@@ -1092,35 +1081,24 @@ xfs_dir_ialloc( | |||
1092 | } | 1081 | } |
1093 | 1082 | ||
1094 | /* | 1083 | /* |
1095 | * Decrement the link count on an inode & log the change. | 1084 | * Decrement the link count on an inode & log the change. If this causes the |
1096 | * If this causes the link count to go to zero, initiate the | 1085 | * link count to go to zero, move the inode to AGI unlinked list so that it can |
1097 | * logging activity required to truncate a file. | 1086 | * be freed when the last active reference goes away via xfs_inactive(). |
1098 | */ | 1087 | */ |
1099 | int /* error */ | 1088 | int /* error */ |
1100 | xfs_droplink( | 1089 | xfs_droplink( |
1101 | xfs_trans_t *tp, | 1090 | xfs_trans_t *tp, |
1102 | xfs_inode_t *ip) | 1091 | xfs_inode_t *ip) |
1103 | { | 1092 | { |
1104 | int error; | ||
1105 | |||
1106 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); | 1093 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); |
1107 | 1094 | ||
1108 | ASSERT (ip->i_d.di_nlink > 0); | ||
1109 | ip->i_d.di_nlink--; | ||
1110 | drop_nlink(VFS_I(ip)); | 1095 | drop_nlink(VFS_I(ip)); |
1111 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 1096 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
1112 | 1097 | ||
1113 | error = 0; | 1098 | if (VFS_I(ip)->i_nlink) |
1114 | if (ip->i_d.di_nlink == 0) { | 1099 | return 0; |
1115 | /* | 1100 | |
1116 | * We're dropping the last link to this file. | 1101 | return xfs_iunlink(tp, ip); |
1117 | * Move the on-disk inode to the AGI unlinked list. | ||
1118 | * From xfs_inactive() we will pull the inode from | ||
1119 | * the list and free it. | ||
1120 | */ | ||
1121 | error = xfs_iunlink(tp, ip); | ||
1122 | } | ||
1123 | return error; | ||
1124 | } | 1102 | } |
1125 | 1103 | ||
1126 | /* | 1104 | /* |
@@ -1134,8 +1112,6 @@ xfs_bumplink( | |||
1134 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); | 1112 | xfs_trans_ichgtime(tp, ip, XFS_ICHGTIME_CHG); |
1135 | 1113 | ||
1136 | ASSERT(ip->i_d.di_version > 1); | 1114 | ASSERT(ip->i_d.di_version > 1); |
1137 | ASSERT(ip->i_d.di_nlink > 0 || (VFS_I(ip)->i_state & I_LINKABLE)); | ||
1138 | ip->i_d.di_nlink++; | ||
1139 | inc_nlink(VFS_I(ip)); | 1115 | inc_nlink(VFS_I(ip)); |
1140 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 1116 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
1141 | return 0; | 1117 | return 0; |
@@ -1393,7 +1369,6 @@ xfs_create_tmpfile( | |||
1393 | */ | 1369 | */ |
1394 | xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); | 1370 | xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp); |
1395 | 1371 | ||
1396 | ip->i_d.di_nlink--; | ||
1397 | error = xfs_iunlink(tp, ip); | 1372 | error = xfs_iunlink(tp, ip); |
1398 | if (error) | 1373 | if (error) |
1399 | goto out_trans_cancel; | 1374 | goto out_trans_cancel; |
@@ -1444,7 +1419,7 @@ xfs_link( | |||
1444 | 1419 | ||
1445 | trace_xfs_link(tdp, target_name); | 1420 | trace_xfs_link(tdp, target_name); |
1446 | 1421 | ||
1447 | ASSERT(!S_ISDIR(sip->i_d.di_mode)); | 1422 | ASSERT(!S_ISDIR(VFS_I(sip)->i_mode)); |
1448 | 1423 | ||
1449 | if (XFS_FORCED_SHUTDOWN(mp)) | 1424 | if (XFS_FORCED_SHUTDOWN(mp)) |
1450 | return -EIO; | 1425 | return -EIO; |
@@ -1492,7 +1467,10 @@ xfs_link( | |||
1492 | 1467 | ||
1493 | xfs_bmap_init(&free_list, &first_block); | 1468 | xfs_bmap_init(&free_list, &first_block); |
1494 | 1469 | ||
1495 | if (sip->i_d.di_nlink == 0) { | 1470 | /* |
1471 | * Handle initial link state of O_TMPFILE inode | ||
1472 | */ | ||
1473 | if (VFS_I(sip)->i_nlink == 0) { | ||
1496 | error = xfs_iunlink_remove(tp, sip); | 1474 | error = xfs_iunlink_remove(tp, sip); |
1497 | if (error) | 1475 | if (error) |
1498 | goto error_return; | 1476 | goto error_return; |
@@ -1648,7 +1626,7 @@ xfs_release( | |||
1648 | xfs_mount_t *mp = ip->i_mount; | 1626 | xfs_mount_t *mp = ip->i_mount; |
1649 | int error; | 1627 | int error; |
1650 | 1628 | ||
1651 | if (!S_ISREG(ip->i_d.di_mode) || (ip->i_d.di_mode == 0)) | 1629 | if (!S_ISREG(VFS_I(ip)->i_mode) || (VFS_I(ip)->i_mode == 0)) |
1652 | return 0; | 1630 | return 0; |
1653 | 1631 | ||
1654 | /* If this is a read-only mount, don't do this (would generate I/O) */ | 1632 | /* If this is a read-only mount, don't do this (would generate I/O) */ |
@@ -1679,7 +1657,7 @@ xfs_release( | |||
1679 | } | 1657 | } |
1680 | } | 1658 | } |
1681 | 1659 | ||
1682 | if (ip->i_d.di_nlink == 0) | 1660 | if (VFS_I(ip)->i_nlink == 0) |
1683 | return 0; | 1661 | return 0; |
1684 | 1662 | ||
1685 | if (xfs_can_free_eofblocks(ip, false)) { | 1663 | if (xfs_can_free_eofblocks(ip, false)) { |
@@ -1883,7 +1861,7 @@ xfs_inactive( | |||
1883 | * If the inode is already free, then there can be nothing | 1861 | * If the inode is already free, then there can be nothing |
1884 | * to clean up here. | 1862 | * to clean up here. |
1885 | */ | 1863 | */ |
1886 | if (ip->i_d.di_mode == 0) { | 1864 | if (VFS_I(ip)->i_mode == 0) { |
1887 | ASSERT(ip->i_df.if_real_bytes == 0); | 1865 | ASSERT(ip->i_df.if_real_bytes == 0); |
1888 | ASSERT(ip->i_df.if_broot_bytes == 0); | 1866 | ASSERT(ip->i_df.if_broot_bytes == 0); |
1889 | return; | 1867 | return; |
@@ -1895,7 +1873,7 @@ xfs_inactive( | |||
1895 | if (mp->m_flags & XFS_MOUNT_RDONLY) | 1873 | if (mp->m_flags & XFS_MOUNT_RDONLY) |
1896 | return; | 1874 | return; |
1897 | 1875 | ||
1898 | if (ip->i_d.di_nlink != 0) { | 1876 | if (VFS_I(ip)->i_nlink != 0) { |
1899 | /* | 1877 | /* |
1900 | * force is true because we are evicting an inode from the | 1878 | * force is true because we are evicting an inode from the |
1901 | * cache. Post-eof blocks must be freed, lest we end up with | 1879 | * cache. Post-eof blocks must be freed, lest we end up with |
@@ -1907,7 +1885,7 @@ xfs_inactive( | |||
1907 | return; | 1885 | return; |
1908 | } | 1886 | } |
1909 | 1887 | ||
1910 | if (S_ISREG(ip->i_d.di_mode) && | 1888 | if (S_ISREG(VFS_I(ip)->i_mode) && |
1911 | (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || | 1889 | (ip->i_d.di_size != 0 || XFS_ISIZE(ip) != 0 || |
1912 | ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) | 1890 | ip->i_d.di_nextents > 0 || ip->i_delayed_blks > 0)) |
1913 | truncate = 1; | 1891 | truncate = 1; |
@@ -1916,7 +1894,7 @@ xfs_inactive( | |||
1916 | if (error) | 1894 | if (error) |
1917 | return; | 1895 | return; |
1918 | 1896 | ||
1919 | if (S_ISLNK(ip->i_d.di_mode)) | 1897 | if (S_ISLNK(VFS_I(ip)->i_mode)) |
1920 | error = xfs_inactive_symlink(ip); | 1898 | error = xfs_inactive_symlink(ip); |
1921 | else if (truncate) | 1899 | else if (truncate) |
1922 | error = xfs_inactive_truncate(ip); | 1900 | error = xfs_inactive_truncate(ip); |
@@ -1952,16 +1930,21 @@ xfs_inactive( | |||
1952 | } | 1930 | } |
1953 | 1931 | ||
1954 | /* | 1932 | /* |
1955 | * This is called when the inode's link count goes to 0. | 1933 | * This is called when the inode's link count goes to 0 or we are creating a |
1956 | * We place the on-disk inode on a list in the AGI. It | 1934 | * tmpfile via O_TMPFILE. In the case of a tmpfile, @ignore_linkcount will be |
1957 | * will be pulled from this list when the inode is freed. | 1935 | * set to true as the link count is dropped to zero by the VFS after we've |
1936 | * created the file successfully, so we have to add it to the unlinked list | ||
1937 | * while the link count is non-zero. | ||
1938 | * | ||
1939 | * We place the on-disk inode on a list in the AGI. It will be pulled from this | ||
1940 | * list when the inode is freed. | ||
1958 | */ | 1941 | */ |
1959 | int | 1942 | STATIC int |
1960 | xfs_iunlink( | 1943 | xfs_iunlink( |
1961 | xfs_trans_t *tp, | 1944 | struct xfs_trans *tp, |
1962 | xfs_inode_t *ip) | 1945 | struct xfs_inode *ip) |
1963 | { | 1946 | { |
1964 | xfs_mount_t *mp; | 1947 | xfs_mount_t *mp = tp->t_mountp; |
1965 | xfs_agi_t *agi; | 1948 | xfs_agi_t *agi; |
1966 | xfs_dinode_t *dip; | 1949 | xfs_dinode_t *dip; |
1967 | xfs_buf_t *agibp; | 1950 | xfs_buf_t *agibp; |
@@ -1971,10 +1954,7 @@ xfs_iunlink( | |||
1971 | int offset; | 1954 | int offset; |
1972 | int error; | 1955 | int error; |
1973 | 1956 | ||
1974 | ASSERT(ip->i_d.di_nlink == 0); | 1957 | ASSERT(VFS_I(ip)->i_mode != 0); |
1975 | ASSERT(ip->i_d.di_mode != 0); | ||
1976 | |||
1977 | mp = tp->t_mountp; | ||
1978 | 1958 | ||
1979 | /* | 1959 | /* |
1980 | * Get the agi buffer first. It ensures lock ordering | 1960 | * Get the agi buffer first. It ensures lock ordering |
@@ -2412,10 +2392,10 @@ xfs_ifree( | |||
2412 | struct xfs_icluster xic = { 0 }; | 2392 | struct xfs_icluster xic = { 0 }; |
2413 | 2393 | ||
2414 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); | 2394 | ASSERT(xfs_isilocked(ip, XFS_ILOCK_EXCL)); |
2415 | ASSERT(ip->i_d.di_nlink == 0); | 2395 | ASSERT(VFS_I(ip)->i_nlink == 0); |
2416 | ASSERT(ip->i_d.di_nextents == 0); | 2396 | ASSERT(ip->i_d.di_nextents == 0); |
2417 | ASSERT(ip->i_d.di_anextents == 0); | 2397 | ASSERT(ip->i_d.di_anextents == 0); |
2418 | ASSERT(ip->i_d.di_size == 0 || !S_ISREG(ip->i_d.di_mode)); | 2398 | ASSERT(ip->i_d.di_size == 0 || !S_ISREG(VFS_I(ip)->i_mode)); |
2419 | ASSERT(ip->i_d.di_nblocks == 0); | 2399 | ASSERT(ip->i_d.di_nblocks == 0); |
2420 | 2400 | ||
2421 | /* | 2401 | /* |
@@ -2429,7 +2409,7 @@ xfs_ifree( | |||
2429 | if (error) | 2409 | if (error) |
2430 | return error; | 2410 | return error; |
2431 | 2411 | ||
2432 | ip->i_d.di_mode = 0; /* mark incore inode as free */ | 2412 | VFS_I(ip)->i_mode = 0; /* mark incore inode as free */ |
2433 | ip->i_d.di_flags = 0; | 2413 | ip->i_d.di_flags = 0; |
2434 | ip->i_d.di_dmevmask = 0; | 2414 | ip->i_d.di_dmevmask = 0; |
2435 | ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ | 2415 | ip->i_d.di_forkoff = 0; /* mark the attr fork not in use */ |
@@ -2439,7 +2419,7 @@ xfs_ifree( | |||
2439 | * Bump the generation count so no one will be confused | 2419 | * Bump the generation count so no one will be confused |
2440 | * by reincarnations of this inode. | 2420 | * by reincarnations of this inode. |
2441 | */ | 2421 | */ |
2442 | ip->i_d.di_gen++; | 2422 | VFS_I(ip)->i_generation++; |
2443 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); | 2423 | xfs_trans_log_inode(tp, ip, XFS_ILOG_CORE); |
2444 | 2424 | ||
2445 | if (xic.deleted) | 2425 | if (xic.deleted) |
@@ -2526,7 +2506,7 @@ xfs_remove( | |||
2526 | { | 2506 | { |
2527 | xfs_mount_t *mp = dp->i_mount; | 2507 | xfs_mount_t *mp = dp->i_mount; |
2528 | xfs_trans_t *tp = NULL; | 2508 | xfs_trans_t *tp = NULL; |
2529 | int is_dir = S_ISDIR(ip->i_d.di_mode); | 2509 | int is_dir = S_ISDIR(VFS_I(ip)->i_mode); |
2530 | int error = 0; | 2510 | int error = 0; |
2531 | xfs_bmap_free_t free_list; | 2511 | xfs_bmap_free_t free_list; |
2532 | xfs_fsblock_t first_block; | 2512 | xfs_fsblock_t first_block; |
@@ -2580,8 +2560,8 @@ xfs_remove( | |||
2580 | * If we're removing a directory perform some additional validation. | 2560 | * If we're removing a directory perform some additional validation. |
2581 | */ | 2561 | */ |
2582 | if (is_dir) { | 2562 | if (is_dir) { |
2583 | ASSERT(ip->i_d.di_nlink >= 2); | 2563 | ASSERT(VFS_I(ip)->i_nlink >= 2); |
2584 | if (ip->i_d.di_nlink != 2) { | 2564 | if (VFS_I(ip)->i_nlink != 2) { |
2585 | error = -ENOTEMPTY; | 2565 | error = -ENOTEMPTY; |
2586 | goto out_trans_cancel; | 2566 | goto out_trans_cancel; |
2587 | } | 2567 | } |
@@ -2771,7 +2751,7 @@ xfs_cross_rename( | |||
2771 | if (dp1 != dp2) { | 2751 | if (dp1 != dp2) { |
2772 | dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; | 2752 | dp2_flags = XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; |
2773 | 2753 | ||
2774 | if (S_ISDIR(ip2->i_d.di_mode)) { | 2754 | if (S_ISDIR(VFS_I(ip2)->i_mode)) { |
2775 | error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot, | 2755 | error = xfs_dir_replace(tp, ip2, &xfs_name_dotdot, |
2776 | dp1->i_ino, first_block, | 2756 | dp1->i_ino, first_block, |
2777 | free_list, spaceres); | 2757 | free_list, spaceres); |
@@ -2779,7 +2759,7 @@ xfs_cross_rename( | |||
2779 | goto out_trans_abort; | 2759 | goto out_trans_abort; |
2780 | 2760 | ||
2781 | /* transfer ip2 ".." reference to dp1 */ | 2761 | /* transfer ip2 ".." reference to dp1 */ |
2782 | if (!S_ISDIR(ip1->i_d.di_mode)) { | 2762 | if (!S_ISDIR(VFS_I(ip1)->i_mode)) { |
2783 | error = xfs_droplink(tp, dp2); | 2763 | error = xfs_droplink(tp, dp2); |
2784 | if (error) | 2764 | if (error) |
2785 | goto out_trans_abort; | 2765 | goto out_trans_abort; |
@@ -2798,7 +2778,7 @@ xfs_cross_rename( | |||
2798 | ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; | 2778 | ip2_flags |= XFS_ICHGTIME_MOD | XFS_ICHGTIME_CHG; |
2799 | } | 2779 | } |
2800 | 2780 | ||
2801 | if (S_ISDIR(ip1->i_d.di_mode)) { | 2781 | if (S_ISDIR(VFS_I(ip1)->i_mode)) { |
2802 | error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot, | 2782 | error = xfs_dir_replace(tp, ip1, &xfs_name_dotdot, |
2803 | dp2->i_ino, first_block, | 2783 | dp2->i_ino, first_block, |
2804 | free_list, spaceres); | 2784 | free_list, spaceres); |
@@ -2806,7 +2786,7 @@ xfs_cross_rename( | |||
2806 | goto out_trans_abort; | 2786 | goto out_trans_abort; |
2807 | 2787 | ||
2808 | /* transfer ip1 ".." reference to dp2 */ | 2788 | /* transfer ip1 ".." reference to dp2 */ |
2809 | if (!S_ISDIR(ip2->i_d.di_mode)) { | 2789 | if (!S_ISDIR(VFS_I(ip2)->i_mode)) { |
2810 | error = xfs_droplink(tp, dp1); | 2790 | error = xfs_droplink(tp, dp1); |
2811 | if (error) | 2791 | if (error) |
2812 | goto out_trans_abort; | 2792 | goto out_trans_abort; |
@@ -2903,7 +2883,7 @@ xfs_rename( | |||
2903 | struct xfs_inode *inodes[__XFS_SORT_INODES]; | 2883 | struct xfs_inode *inodes[__XFS_SORT_INODES]; |
2904 | int num_inodes = __XFS_SORT_INODES; | 2884 | int num_inodes = __XFS_SORT_INODES; |
2905 | bool new_parent = (src_dp != target_dp); | 2885 | bool new_parent = (src_dp != target_dp); |
2906 | bool src_is_directory = S_ISDIR(src_ip->i_d.di_mode); | 2886 | bool src_is_directory = S_ISDIR(VFS_I(src_ip)->i_mode); |
2907 | int spaceres; | 2887 | int spaceres; |
2908 | int error; | 2888 | int error; |
2909 | 2889 | ||
@@ -3032,12 +3012,12 @@ xfs_rename( | |||
3032 | * target and source are directories and that target can be | 3012 | * target and source are directories and that target can be |
3033 | * destroyed, or that neither is a directory. | 3013 | * destroyed, or that neither is a directory. |
3034 | */ | 3014 | */ |
3035 | if (S_ISDIR(target_ip->i_d.di_mode)) { | 3015 | if (S_ISDIR(VFS_I(target_ip)->i_mode)) { |
3036 | /* | 3016 | /* |
3037 | * Make sure target dir is empty. | 3017 | * Make sure target dir is empty. |
3038 | */ | 3018 | */ |
3039 | if (!(xfs_dir_isempty(target_ip)) || | 3019 | if (!(xfs_dir_isempty(target_ip)) || |
3040 | (target_ip->i_d.di_nlink > 2)) { | 3020 | (VFS_I(target_ip)->i_nlink > 2)) { |
3041 | error = -EEXIST; | 3021 | error = -EEXIST; |
3042 | goto out_trans_cancel; | 3022 | goto out_trans_cancel; |
3043 | } | 3023 | } |
@@ -3144,7 +3124,7 @@ xfs_rename( | |||
3144 | * intermediate state on disk. | 3124 | * intermediate state on disk. |
3145 | */ | 3125 | */ |
3146 | if (wip) { | 3126 | if (wip) { |
3147 | ASSERT(VFS_I(wip)->i_nlink == 0 && wip->i_d.di_nlink == 0); | 3127 | ASSERT(VFS_I(wip)->i_nlink == 0); |
3148 | error = xfs_bumplink(tp, wip); | 3128 | error = xfs_bumplink(tp, wip); |
3149 | if (error) | 3129 | if (error) |
3150 | goto out_bmap_cancel; | 3130 | goto out_bmap_cancel; |
@@ -3313,7 +3293,7 @@ cluster_corrupt_out: | |||
3313 | * mark it as stale and brelse. | 3293 | * mark it as stale and brelse. |
3314 | */ | 3294 | */ |
3315 | if (bp->b_iodone) { | 3295 | if (bp->b_iodone) { |
3316 | XFS_BUF_UNDONE(bp); | 3296 | bp->b_flags &= ~XBF_DONE; |
3317 | xfs_buf_stale(bp); | 3297 | xfs_buf_stale(bp); |
3318 | xfs_buf_ioerror(bp, -EIO); | 3298 | xfs_buf_ioerror(bp, -EIO); |
3319 | xfs_buf_ioend(bp); | 3299 | xfs_buf_ioend(bp); |
@@ -3462,14 +3442,7 @@ xfs_iflush_int( | |||
3462 | __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip); | 3442 | __func__, ip->i_ino, be16_to_cpu(dip->di_magic), dip); |
3463 | goto corrupt_out; | 3443 | goto corrupt_out; |
3464 | } | 3444 | } |
3465 | if (XFS_TEST_ERROR(ip->i_d.di_magic != XFS_DINODE_MAGIC, | 3445 | if (S_ISREG(VFS_I(ip)->i_mode)) { |
3466 | mp, XFS_ERRTAG_IFLUSH_2, XFS_RANDOM_IFLUSH_2)) { | ||
3467 | xfs_alert_tag(mp, XFS_PTAG_IFLUSH, | ||
3468 | "%s: Bad inode %Lu, ptr 0x%p, magic number 0x%x", | ||
3469 | __func__, ip->i_ino, ip, ip->i_d.di_magic); | ||
3470 | goto corrupt_out; | ||
3471 | } | ||
3472 | if (S_ISREG(ip->i_d.di_mode)) { | ||
3473 | if (XFS_TEST_ERROR( | 3446 | if (XFS_TEST_ERROR( |
3474 | (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && | 3447 | (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && |
3475 | (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), | 3448 | (ip->i_d.di_format != XFS_DINODE_FMT_BTREE), |
@@ -3479,7 +3452,7 @@ xfs_iflush_int( | |||
3479 | __func__, ip->i_ino, ip); | 3452 | __func__, ip->i_ino, ip); |
3480 | goto corrupt_out; | 3453 | goto corrupt_out; |
3481 | } | 3454 | } |
3482 | } else if (S_ISDIR(ip->i_d.di_mode)) { | 3455 | } else if (S_ISDIR(VFS_I(ip)->i_mode)) { |
3483 | if (XFS_TEST_ERROR( | 3456 | if (XFS_TEST_ERROR( |
3484 | (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && | 3457 | (ip->i_d.di_format != XFS_DINODE_FMT_EXTENTS) && |
3485 | (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && | 3458 | (ip->i_d.di_format != XFS_DINODE_FMT_BTREE) && |
@@ -3523,12 +3496,11 @@ xfs_iflush_int( | |||
3523 | ip->i_d.di_flushiter++; | 3496 | ip->i_d.di_flushiter++; |
3524 | 3497 | ||
3525 | /* | 3498 | /* |
3526 | * Copy the dirty parts of the inode into the on-disk | 3499 | * Copy the dirty parts of the inode into the on-disk inode. We always |
3527 | * inode. We always copy out the core of the inode, | 3500 | * copy out the core of the inode, because if the inode is dirty at all |
3528 | * because if the inode is dirty at all the core must | 3501 | * the core must be. |
3529 | * be. | ||
3530 | */ | 3502 | */ |
3531 | xfs_dinode_to_disk(dip, &ip->i_d); | 3503 | xfs_inode_to_disk(ip, dip, iip->ili_item.li_lsn); |
3532 | 3504 | ||
3533 | /* Wrap, we never let the log put out DI_MAX_FLUSH */ | 3505 | /* Wrap, we never let the log put out DI_MAX_FLUSH */ |
3534 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) | 3506 | if (ip->i_d.di_flushiter == DI_MAX_FLUSH) |
@@ -3580,10 +3552,6 @@ xfs_iflush_int( | |||
3580 | */ | 3552 | */ |
3581 | xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item); | 3553 | xfs_buf_attach_iodone(bp, xfs_iflush_done, &iip->ili_item); |
3582 | 3554 | ||
3583 | /* update the lsn in the on disk inode if required */ | ||
3584 | if (ip->i_d.di_version == 3) | ||
3585 | dip->di_lsn = cpu_to_be64(iip->ili_item.li_lsn); | ||
3586 | |||
3587 | /* generate the checksum. */ | 3555 | /* generate the checksum. */ |
3588 | xfs_dinode_calc_crc(mp, dip); | 3556 | xfs_dinode_calc_crc(mp, dip); |
3589 | 3557 | ||