zfs_inode_update should not call dmu_object_size_from_db under spinlock

We should never block when holding a spin lock, but zfs_inode_update can
block in the critical section of a spin lock in zfs_inode_update:

zfs_inode_update -> dmu_object_size_from_db -> zrl_add -> mutex_enter

Signed-off-by: Richard Yao <ryao@gentoo.org>
Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov>
Issue #3858
This commit is contained in:
Richard Yao 2015-09-30 13:25:11 -04:00 committed by Brian Behlendorf
parent bc8ffb2d08
commit 919efe93cb

View File

@ -485,6 +485,7 @@ zfs_inode_update(znode_t *zp)
zfs_sb_t *zsb; zfs_sb_t *zsb;
struct inode *ip; struct inode *ip;
uint32_t blksize; uint32_t blksize;
u_longlong_t i_blocks;
uint64_t atime[2], mtime[2], ctime[2]; uint64_t atime[2], mtime[2], ctime[2];
ASSERT(zp != NULL); ASSERT(zp != NULL);
@ -499,6 +500,8 @@ zfs_inode_update(znode_t *zp)
sa_lookup(zp->z_sa_hdl, SA_ZPL_MTIME(zsb), &mtime, 16); sa_lookup(zp->z_sa_hdl, SA_ZPL_MTIME(zsb), &mtime, 16);
sa_lookup(zp->z_sa_hdl, SA_ZPL_CTIME(zsb), &ctime, 16); sa_lookup(zp->z_sa_hdl, SA_ZPL_CTIME(zsb), &ctime, 16);
dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &blksize, &i_blocks);
spin_lock(&ip->i_lock); spin_lock(&ip->i_lock);
ip->i_generation = zp->z_gen; ip->i_generation = zp->z_gen;
ip->i_uid = SUID_TO_KUID(zp->z_uid); ip->i_uid = SUID_TO_KUID(zp->z_uid);
@ -507,8 +510,7 @@ zfs_inode_update(znode_t *zp)
ip->i_mode = zp->z_mode; ip->i_mode = zp->z_mode;
zfs_set_inode_flags(zp, ip); zfs_set_inode_flags(zp, ip);
ip->i_blkbits = SPA_MINBLOCKSHIFT; ip->i_blkbits = SPA_MINBLOCKSHIFT;
dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &blksize, ip->i_blocks = i_blocks;
(u_longlong_t *)&ip->i_blocks);
ZFS_TIME_DECODE(&ip->i_atime, atime); ZFS_TIME_DECODE(&ip->i_atime, atime);
ZFS_TIME_DECODE(&ip->i_mtime, mtime); ZFS_TIME_DECODE(&ip->i_mtime, mtime);