Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[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>

authored by

Dave Chinner and committed by
Lachlan McIlroy
6307091f cb4f0d1d

+9 -3
-1
fs/xfs/linux-2.6/xfs_iops.c
··· 780 780 inode->i_ino = ip->i_ino; 781 781 inode->i_state = I_NEW|I_LOCK; 782 782 inode_add_to_lists(ip->i_mount->m_super, inode); 783 - ASSERT(atomic_read(&inode->i_count) == 1); 784 783 785 784 inode->i_mode = ip->i_d.di_mode; 786 785 inode->i_nlink = ip->i_d.di_nlink;
+3 -2
fs/xfs/linux-2.6/xfs_sync.c
··· 117 117 } 118 118 read_unlock(&pag->pag_ici_lock); 119 119 120 - /* bad inodes are dealt with elsewhere */ 121 - if (is_bad_inode(inode)) { 120 + /* avoid new or bad inodes */ 121 + if (is_bad_inode(inode) || 122 + xfs_iflags_test(ip, XFS_INEW)) { 122 123 IRELE(ip); 123 124 continue; 124 125 }
+6
fs/xfs/quota/xfs_qm_syscalls.c
··· 1080 1080 } 1081 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 1089 xfs_ilock(ip, XFS_ILOCK_EXCL); 1084 1090 if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) { 1085 1091 xfs_qm_dqrele(ip->i_udquot);