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.c153
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 */
3701void
3702xfs_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
3758ktrace_t *xfs_ilock_trace_buf; 3677ktrace_t *xfs_ilock_trace_buf;
3759 3678