diff options
author | Dave Chinner <david@fromorbit.com> | 2008-11-10 01:13:23 -0500 |
---|---|---|
committer | Lachlan McIlroy <lachlan@redback.melbourne.sgi.com> | 2008-11-10 01:13:23 -0500 |
commit | 6307091fe69ae74747298bdcaf43119ad67bda3a (patch) | |
tree | c1feb80479b7ae4ebcf9a4336e50dfd18aebcb38 /fs | |
parent | cb4f0d1d4229f609f43c68acec69c7618ed72397 (diff) |
[XFS] Avoid using inodes that haven't been completely initialised
The radix tree walks in xfs_sync_inodes_ag and xfs_qm_dqrele_all_inodes()
can find inodes that are still undergoing initialisation. Avoid
them by checking for the the XFS_INEW() flag once we have a reference
on the inode. This flag is cleared once the inode is properly initialised.
SGI-PV: 987246
Signed-off-by: Dave Chinner <david@fromorbit.com>
Signed-off-by: Lachlan McIlroy <lachlan@sgi.com>
Diffstat (limited to 'fs')
-rw-r--r-- | fs/xfs/linux-2.6/xfs_iops.c | 1 | ||||
-rw-r--r-- | fs/xfs/linux-2.6/xfs_sync.c | 5 | ||||
-rw-r--r-- | fs/xfs/quota/xfs_qm_syscalls.c | 6 |
3 files changed, 9 insertions, 3 deletions
diff --git a/fs/xfs/linux-2.6/xfs_iops.c b/fs/xfs/linux-2.6/xfs_iops.c index f78bc2215764..69c98cf32336 100644 --- a/fs/xfs/linux-2.6/xfs_iops.c +++ b/fs/xfs/linux-2.6/xfs_iops.c | |||
@@ -780,7 +780,6 @@ xfs_setup_inode( | |||
780 | inode->i_ino = ip->i_ino; | 780 | inode->i_ino = ip->i_ino; |
781 | inode->i_state = I_NEW|I_LOCK; | 781 | inode->i_state = I_NEW|I_LOCK; |
782 | inode_add_to_lists(ip->i_mount->m_super, inode); | 782 | inode_add_to_lists(ip->i_mount->m_super, inode); |
783 | ASSERT(atomic_read(&inode->i_count) == 1); | ||
784 | 783 | ||
785 | inode->i_mode = ip->i_d.di_mode; | 784 | inode->i_mode = ip->i_d.di_mode; |
786 | inode->i_nlink = ip->i_d.di_nlink; | 785 | inode->i_nlink = ip->i_d.di_nlink; |
diff --git a/fs/xfs/linux-2.6/xfs_sync.c b/fs/xfs/linux-2.6/xfs_sync.c index fb5cca3df840..d12d31b86fa0 100644 --- a/fs/xfs/linux-2.6/xfs_sync.c +++ b/fs/xfs/linux-2.6/xfs_sync.c | |||
@@ -117,8 +117,9 @@ xfs_sync_inodes_ag( | |||
117 | } | 117 | } |
118 | read_unlock(&pag->pag_ici_lock); | 118 | read_unlock(&pag->pag_ici_lock); |
119 | 119 | ||
120 | /* bad inodes are dealt with elsewhere */ | 120 | /* avoid new or bad inodes */ |
121 | if (is_bad_inode(inode)) { | 121 | if (is_bad_inode(inode) || |
122 | xfs_iflags_test(ip, XFS_INEW)) { | ||
122 | IRELE(ip); | 123 | IRELE(ip); |
123 | continue; | 124 | continue; |
124 | } | 125 | } |
diff --git a/fs/xfs/quota/xfs_qm_syscalls.c b/fs/xfs/quota/xfs_qm_syscalls.c index 2c57a6eaff36..68139b38aede 100644 --- a/fs/xfs/quota/xfs_qm_syscalls.c +++ b/fs/xfs/quota/xfs_qm_syscalls.c | |||
@@ -1080,6 +1080,12 @@ xfs_qm_dqrele_inodes_ag( | |||
1080 | } | 1080 | } |
1081 | read_unlock(&pag->pag_ici_lock); | 1081 | read_unlock(&pag->pag_ici_lock); |
1082 | 1082 | ||
1083 | /* avoid new inodes though we shouldn't find any here */ | ||
1084 | if (xfs_iflags_test(ip, XFS_INEW)) { | ||
1085 | IRELE(ip); | ||
1086 | continue; | ||
1087 | } | ||
1088 | |||
1083 | xfs_ilock(ip, XFS_ILOCK_EXCL); | 1089 | xfs_ilock(ip, XFS_ILOCK_EXCL); |
1084 | if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { | 1090 | if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { |
1085 | xfs_qm_dqrele(ip->i_udquot); | 1091 | xfs_qm_dqrele(ip->i_udquot); |