Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6307091f authored by Dave Chinner's avatar Dave Chinner Committed by Lachlan McIlroy
Browse files

[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: default avatarDave Chinner <david@fromorbit.com>
Signed-off-by: default avatarLachlan McIlroy <lachlan@sgi.com>
parent cb4f0d1d
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -780,7 +780,6 @@ xfs_setup_inode(
	inode->i_ino = ip->i_ino;
	inode->i_ino = ip->i_ino;
	inode->i_state = I_NEW|I_LOCK;
	inode->i_state = I_NEW|I_LOCK;
	inode_add_to_lists(ip->i_mount->m_super, inode);
	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_mode	= ip->i_d.di_mode;
	inode->i_nlink	= ip->i_d.di_nlink;
	inode->i_nlink	= ip->i_d.di_nlink;
+3 −2
Original line number Original line Diff line number Diff line
@@ -117,8 +117,9 @@ xfs_sync_inodes_ag(
		}
		}
		read_unlock(&pag->pag_ici_lock);
		read_unlock(&pag->pag_ici_lock);


		/* bad inodes are dealt with elsewhere */
		/* avoid new or bad inodes */
		if (is_bad_inode(inode)) {
		if (is_bad_inode(inode) ||
		    xfs_iflags_test(ip, XFS_INEW)) {
			IRELE(ip);
			IRELE(ip);
			continue;
			continue;
		}
		}
+6 −0
Original line number Original line Diff line number Diff line
@@ -1080,6 +1080,12 @@ xfs_qm_dqrele_inodes_ag(
		}
		}
		read_unlock(&pag->pag_ici_lock);
		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);
		xfs_ilock(ip, XFS_ILOCK_EXCL);
		if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
		if ((flags & XFS_UQUOTA_ACCT) && ip->i_udquot) {
			xfs_qm_dqrele(ip->i_udquot);
			xfs_qm_dqrele(ip->i_udquot);