diff options
Diffstat (limited to 'fs/xfs/xfs_inode.c')
-rw-r--r-- | fs/xfs/xfs_inode.c | 153 |
1 files changed, 36 insertions, 117 deletions
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c index db43308aae93..df0d4572d70a 100644 --- a/fs/xfs/xfs_inode.c +++ b/fs/xfs/xfs_inode.c | |||
@@ -1,40 +1,27 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2000-2003 Silicon Graphics, Inc. All Rights Reserved. | 2 | * Copyright (c) 2000-2003,2005 Silicon Graphics, Inc. |
3 | * All Rights Reserved. | ||
3 | * | 4 | * |
4 | * This program is free software; you can redistribute it and/or modify it | 5 | * This program is free software; you can redistribute it and/or |
5 | * under the terms of version 2 of the GNU General Public License as | 6 | * modify it under the terms of the GNU General Public License as |
6 | * published by the Free Software Foundation. | 7 | * published by the Free Software Foundation. |
7 | * | 8 | * |
8 | * This program is distributed in the hope that it would be useful, but | 9 | * This program is distributed in the hope that it would be useful, |
9 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. | 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
12 | * GNU General Public License for more details. | ||
11 | * | 13 | * |
12 | * Further, this software is distributed without any warranty that it is | 14 | * You should have received a copy of the GNU General Public License |
13 | * free of the rightful claim of any third person regarding infringement | 15 | * along with this program; if not, write the Free Software Foundation, |
14 | * or the like. Any license provided herein, whether implied or | 16 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
15 | * otherwise, applies only to this software file. Patent licenses, if | ||
16 | * any, provided herein do not apply to combinations of this program with | ||
17 | * other software, or any other product whatsoever. | ||
18 | * | ||
19 | * You should have received a copy of the GNU General Public License along | ||
20 | * with this program; if not, write the Free Software Foundation, Inc., 59 | ||
21 | * Temple Place - Suite 330, Boston MA 02111-1307, USA. | ||
22 | * | ||
23 | * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, | ||
24 | * Mountain View, CA 94043, or: | ||
25 | * | ||
26 | * http://www.sgi.com | ||
27 | * | ||
28 | * For further information regarding this notice, see: | ||
29 | * | ||
30 | * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ | ||
31 | */ | 17 | */ |
32 | |||
33 | #include "xfs.h" | 18 | #include "xfs.h" |
34 | #include "xfs_macros.h" | 19 | #include "xfs_fs.h" |
35 | #include "xfs_types.h" | 20 | #include "xfs_types.h" |
36 | #include "xfs_inum.h" | 21 | #include "xfs_bit.h" |
37 | #include "xfs_log.h" | 22 | #include "xfs_log.h" |
23 | #include "xfs_inum.h" | ||
24 | #include "xfs_imap.h" | ||
38 | #include "xfs_trans.h" | 25 | #include "xfs_trans.h" |
39 | #include "xfs_trans_priv.h" | 26 | #include "xfs_trans_priv.h" |
40 | #include "xfs_sb.h" | 27 | #include "xfs_sb.h" |
@@ -43,24 +30,22 @@ | |||
43 | #include "xfs_dir2.h" | 30 | #include "xfs_dir2.h" |
44 | #include "xfs_dmapi.h" | 31 | #include "xfs_dmapi.h" |
45 | #include "xfs_mount.h" | 32 | #include "xfs_mount.h" |
46 | #include "xfs_alloc_btree.h" | ||
47 | #include "xfs_bmap_btree.h" | 33 | #include "xfs_bmap_btree.h" |
34 | #include "xfs_alloc_btree.h" | ||
48 | #include "xfs_ialloc_btree.h" | 35 | #include "xfs_ialloc_btree.h" |
49 | #include "xfs_btree.h" | ||
50 | #include "xfs_imap.h" | ||
51 | #include "xfs_alloc.h" | ||
52 | #include "xfs_ialloc.h" | ||
53 | #include "xfs_attr_sf.h" | ||
54 | #include "xfs_dir_sf.h" | 36 | #include "xfs_dir_sf.h" |
55 | #include "xfs_dir2_sf.h" | 37 | #include "xfs_dir2_sf.h" |
38 | #include "xfs_attr_sf.h" | ||
56 | #include "xfs_dinode.h" | 39 | #include "xfs_dinode.h" |
57 | #include "xfs_inode_item.h" | ||
58 | #include "xfs_inode.h" | 40 | #include "xfs_inode.h" |
59 | #include "xfs_bmap.h" | ||
60 | #include "xfs_buf_item.h" | 41 | #include "xfs_buf_item.h" |
42 | #include "xfs_inode_item.h" | ||
43 | #include "xfs_btree.h" | ||
44 | #include "xfs_alloc.h" | ||
45 | #include "xfs_ialloc.h" | ||
46 | #include "xfs_bmap.h" | ||
61 | #include "xfs_rw.h" | 47 | #include "xfs_rw.h" |
62 | #include "xfs_error.h" | 48 | #include "xfs_error.h" |
63 | #include "xfs_bit.h" | ||
64 | #include "xfs_utils.h" | 49 | #include "xfs_utils.h" |
65 | #include "xfs_dir2_trace.h" | 50 | #include "xfs_dir2_trace.h" |
66 | #include "xfs_quota.h" | 51 | #include "xfs_quota.h" |
@@ -194,9 +179,10 @@ xfs_inotobp( | |||
194 | if ((imap.im_blkno + imap.im_len) > | 179 | if ((imap.im_blkno + imap.im_len) > |
195 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) { | 180 | XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks)) { |
196 | cmn_err(CE_WARN, | 181 | cmn_err(CE_WARN, |
197 | "xfs_inotobp: inode number (%d + %d) maps to a block outside the bounds " | 182 | "xfs_inotobp: inode number (%llu + %d) maps to a block outside the bounds " |
198 | "of the file system %s. Returning EINVAL.", | 183 | "of the file system %s. Returning EINVAL.", |
199 | imap.im_blkno, imap.im_len,mp->m_fsname); | 184 | (unsigned long long)imap.im_blkno, |
185 | imap.im_len, mp->m_fsname); | ||
200 | return XFS_ERROR(EINVAL); | 186 | return XFS_ERROR(EINVAL); |
201 | } | 187 | } |
202 | 188 | ||
@@ -1878,8 +1864,8 @@ xfs_iunlink( | |||
1878 | */ | 1864 | */ |
1879 | agi = XFS_BUF_TO_AGI(agibp); | 1865 | agi = XFS_BUF_TO_AGI(agibp); |
1880 | agi_ok = | 1866 | agi_ok = |
1881 | INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC && | 1867 | be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && |
1882 | XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT)); | 1868 | XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)); |
1883 | if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK, | 1869 | if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK, |
1884 | XFS_RANDOM_IUNLINK))) { | 1870 | XFS_RANDOM_IUNLINK))) { |
1885 | XFS_CORRUPTION_ERROR("xfs_iunlink", XFS_ERRLEVEL_LOW, mp, agi); | 1871 | XFS_CORRUPTION_ERROR("xfs_iunlink", XFS_ERRLEVEL_LOW, mp, agi); |
@@ -1894,9 +1880,9 @@ xfs_iunlink( | |||
1894 | ASSERT(agino != 0); | 1880 | ASSERT(agino != 0); |
1895 | bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; | 1881 | bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; |
1896 | ASSERT(agi->agi_unlinked[bucket_index]); | 1882 | ASSERT(agi->agi_unlinked[bucket_index]); |
1897 | ASSERT(INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) != agino); | 1883 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != agino); |
1898 | 1884 | ||
1899 | if (INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) != NULLAGINO) { | 1885 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO) { |
1900 | /* | 1886 | /* |
1901 | * There is already another inode in the bucket we need | 1887 | * There is already another inode in the bucket we need |
1902 | * to add ourselves to. Add us at the front of the list. | 1888 | * to add ourselves to. Add us at the front of the list. |
@@ -1923,7 +1909,7 @@ xfs_iunlink( | |||
1923 | * Point the bucket head pointer at the inode being inserted. | 1909 | * Point the bucket head pointer at the inode being inserted. |
1924 | */ | 1910 | */ |
1925 | ASSERT(agino != 0); | 1911 | ASSERT(agino != 0); |
1926 | INT_SET(agi->agi_unlinked[bucket_index], ARCH_CONVERT, agino); | 1912 | agi->agi_unlinked[bucket_index] = cpu_to_be32(agino); |
1927 | offset = offsetof(xfs_agi_t, agi_unlinked) + | 1913 | offset = offsetof(xfs_agi_t, agi_unlinked) + |
1928 | (sizeof(xfs_agino_t) * bucket_index); | 1914 | (sizeof(xfs_agino_t) * bucket_index); |
1929 | xfs_trans_log_buf(tp, agibp, offset, | 1915 | xfs_trans_log_buf(tp, agibp, offset, |
@@ -1981,8 +1967,8 @@ xfs_iunlink_remove( | |||
1981 | */ | 1967 | */ |
1982 | agi = XFS_BUF_TO_AGI(agibp); | 1968 | agi = XFS_BUF_TO_AGI(agibp); |
1983 | agi_ok = | 1969 | agi_ok = |
1984 | INT_GET(agi->agi_magicnum, ARCH_CONVERT) == XFS_AGI_MAGIC && | 1970 | be32_to_cpu(agi->agi_magicnum) == XFS_AGI_MAGIC && |
1985 | XFS_AGI_GOOD_VERSION(INT_GET(agi->agi_versionnum, ARCH_CONVERT)); | 1971 | XFS_AGI_GOOD_VERSION(be32_to_cpu(agi->agi_versionnum)); |
1986 | if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE, | 1972 | if (unlikely(XFS_TEST_ERROR(!agi_ok, mp, XFS_ERRTAG_IUNLINK_REMOVE, |
1987 | XFS_RANDOM_IUNLINK_REMOVE))) { | 1973 | XFS_RANDOM_IUNLINK_REMOVE))) { |
1988 | XFS_CORRUPTION_ERROR("xfs_iunlink_remove", XFS_ERRLEVEL_LOW, | 1974 | XFS_CORRUPTION_ERROR("xfs_iunlink_remove", XFS_ERRLEVEL_LOW, |
@@ -2000,10 +1986,10 @@ xfs_iunlink_remove( | |||
2000 | agino = XFS_INO_TO_AGINO(mp, ip->i_ino); | 1986 | agino = XFS_INO_TO_AGINO(mp, ip->i_ino); |
2001 | ASSERT(agino != 0); | 1987 | ASSERT(agino != 0); |
2002 | bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; | 1988 | bucket_index = agino % XFS_AGI_UNLINKED_BUCKETS; |
2003 | ASSERT(INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) != NULLAGINO); | 1989 | ASSERT(be32_to_cpu(agi->agi_unlinked[bucket_index]) != NULLAGINO); |
2004 | ASSERT(agi->agi_unlinked[bucket_index]); | 1990 | ASSERT(agi->agi_unlinked[bucket_index]); |
2005 | 1991 | ||
2006 | if (INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT) == agino) { | 1992 | if (be32_to_cpu(agi->agi_unlinked[bucket_index]) == agino) { |
2007 | /* | 1993 | /* |
2008 | * We're at the head of the list. Get the inode's | 1994 | * We're at the head of the list. Get the inode's |
2009 | * on-disk buffer to see if there is anyone after us | 1995 | * on-disk buffer to see if there is anyone after us |
@@ -2037,7 +2023,7 @@ xfs_iunlink_remove( | |||
2037 | */ | 2023 | */ |
2038 | ASSERT(next_agino != 0); | 2024 | ASSERT(next_agino != 0); |
2039 | ASSERT(next_agino != agino); | 2025 | ASSERT(next_agino != agino); |
2040 | INT_SET(agi->agi_unlinked[bucket_index], ARCH_CONVERT, next_agino); | 2026 | agi->agi_unlinked[bucket_index] = cpu_to_be32(next_agino); |
2041 | offset = offsetof(xfs_agi_t, agi_unlinked) + | 2027 | offset = offsetof(xfs_agi_t, agi_unlinked) + |
2042 | (sizeof(xfs_agino_t) * bucket_index); | 2028 | (sizeof(xfs_agino_t) * bucket_index); |
2043 | xfs_trans_log_buf(tp, agibp, offset, | 2029 | xfs_trans_log_buf(tp, agibp, offset, |
@@ -2046,7 +2032,7 @@ xfs_iunlink_remove( | |||
2046 | /* | 2032 | /* |
2047 | * We need to search the list for the inode being freed. | 2033 | * We need to search the list for the inode being freed. |
2048 | */ | 2034 | */ |
2049 | next_agino = INT_GET(agi->agi_unlinked[bucket_index], ARCH_CONVERT); | 2035 | next_agino = be32_to_cpu(agi->agi_unlinked[bucket_index]); |
2050 | last_ibp = NULL; | 2036 | last_ibp = NULL; |
2051 | while (next_agino != agino) { | 2037 | while (next_agino != agino) { |
2052 | /* | 2038 | /* |
@@ -3687,73 +3673,6 @@ xfs_iroundup( | |||
3687 | return( 0 ); | 3673 | return( 0 ); |
3688 | } | 3674 | } |
3689 | 3675 | ||
3690 | /* | ||
3691 | * Change the requested timestamp in the given inode. | ||
3692 | * We don't lock across timestamp updates, and we don't log them but | ||
3693 | * we do record the fact that there is dirty information in core. | ||
3694 | * | ||
3695 | * NOTE -- callers MUST combine XFS_ICHGTIME_MOD or XFS_ICHGTIME_CHG | ||
3696 | * with XFS_ICHGTIME_ACC to be sure that access time | ||
3697 | * update will take. Calling first with XFS_ICHGTIME_ACC | ||
3698 | * and then XFS_ICHGTIME_MOD may fail to modify the access | ||
3699 | * timestamp if the filesystem is mounted noacctm. | ||
3700 | */ | ||
3701 | void | ||
3702 | xfs_ichgtime(xfs_inode_t *ip, | ||
3703 | int flags) | ||
3704 | { | ||
3705 | timespec_t tv; | ||
3706 | vnode_t *vp = XFS_ITOV(ip); | ||
3707 | struct inode *inode = LINVFS_GET_IP(vp); | ||
3708 | |||
3709 | /* | ||
3710 | * We're not supposed to change timestamps in readonly-mounted | ||
3711 | * filesystems. Throw it away if anyone asks us. | ||
3712 | */ | ||
3713 | if (unlikely(vp->v_vfsp->vfs_flag & VFS_RDONLY)) | ||
3714 | return; | ||
3715 | |||
3716 | /* | ||
3717 | * Don't update access timestamps on reads if mounted "noatime" | ||
3718 | * Throw it away if anyone asks us. | ||
3719 | */ | ||
3720 | if ((ip->i_mount->m_flags & XFS_MOUNT_NOATIME || IS_NOATIME(inode)) && | ||
3721 | ((flags & (XFS_ICHGTIME_ACC|XFS_ICHGTIME_MOD|XFS_ICHGTIME_CHG)) | ||
3722 | == XFS_ICHGTIME_ACC)) | ||
3723 | return; | ||
3724 | |||
3725 | nanotime(&tv); | ||
3726 | if (flags & XFS_ICHGTIME_MOD) { | ||
3727 | VN_MTIMESET(vp, &tv); | ||
3728 | ip->i_d.di_mtime.t_sec = (__int32_t)tv.tv_sec; | ||
3729 | ip->i_d.di_mtime.t_nsec = (__int32_t)tv.tv_nsec; | ||
3730 | } | ||
3731 | if (flags & XFS_ICHGTIME_ACC) { | ||
3732 | VN_ATIMESET(vp, &tv); | ||
3733 | ip->i_d.di_atime.t_sec = (__int32_t)tv.tv_sec; | ||
3734 | ip->i_d.di_atime.t_nsec = (__int32_t)tv.tv_nsec; | ||
3735 | } | ||
3736 | if (flags & XFS_ICHGTIME_CHG) { | ||
3737 | VN_CTIMESET(vp, &tv); | ||
3738 | ip->i_d.di_ctime.t_sec = (__int32_t)tv.tv_sec; | ||
3739 | ip->i_d.di_ctime.t_nsec = (__int32_t)tv.tv_nsec; | ||
3740 | } | ||
3741 | |||
3742 | /* | ||
3743 | * We update the i_update_core field _after_ changing | ||
3744 | * the timestamps in order to coordinate properly with | ||
3745 | * xfs_iflush() so that we don't lose timestamp updates. | ||
3746 | * This keeps us from having to hold the inode lock | ||
3747 | * while doing this. We use the SYNCHRONIZE macro to | ||
3748 | * ensure that the compiler does not reorder the update | ||
3749 | * of i_update_core above the timestamp updates above. | ||
3750 | */ | ||
3751 | SYNCHRONIZE(); | ||
3752 | ip->i_update_core = 1; | ||
3753 | if (!(inode->i_state & I_LOCK)) | ||
3754 | mark_inode_dirty_sync(inode); | ||
3755 | } | ||
3756 | |||
3757 | #ifdef XFS_ILOCK_TRACE | 3676 | #ifdef XFS_ILOCK_TRACE |
3758 | ktrace_t *xfs_ilock_trace_buf; | 3677 | ktrace_t *xfs_ilock_trace_buf; |
3759 | 3678 | ||