[XFS] Avoid using inodes that haven't been completely initialised
Dave Chinner [Mon, 10 Nov 2008 06:13:23 +0000 (17:13 +1100)]
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>

fs/xfs/linux-2.6/xfs_iops.c
fs/xfs/linux-2.6/xfs_sync.c
fs/xfs/quota/xfs_qm_syscalls.c

index f78bc22..69c98cf 100644 (file)
@@ -780,7 +780,6 @@ xfs_setup_inode(
        inode->i_ino = ip->i_ino;
        inode->i_state = I_NEW|I_LOCK;
        inode_add_to_lists(ip->i_mount->m_super, inode);
-       ASSERT(atomic_read(&inode->i_count) == 1);
 
        inode->i_mode   = ip->i_d.di_mode;
        inode->i_nlink  = ip->i_d.di_nlink;
index fb5cca3..d12d31b 100644 (file)
@@ -117,8 +117,9 @@ xfs_sync_inodes_ag(
                }
                read_unlock(&pag->pag_ici_lock);
 
-               /* bad inodes are dealt with elsewhere */
-               if (is_bad_inode(inode)) {
+               /* avoid new or bad inodes */
+               if (is_bad_inode(inode) ||
+                   xfs_iflags_test(ip, XFS_INEW)) {
                        IRELE(ip);
                        continue;
                }
index 2c57a6e..68139b3 100644 (file)
@@ -1080,6 +1080,12 @@ xfs_qm_dqrele_inodes_ag(
                }
                read_unlock(&pag->pag_ici_lock);
 
+               /* avoid new inodes though we shouldn't find any here */
+               if (xfs_iflags_test(ip, XFS_INEW)) {
+                       IRELE(ip);
+                       continue;
+               }
+
                xfs_ilock(ip, XFS_ILOCK_EXCL);
                if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
                        xfs_qm_dqrele(ip->i_udquot);