diff options
author | Richard Yao <[email protected]> | 2015-09-30 13:25:11 -0400 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2015-09-30 10:47:40 -0700 |
commit | 919efe93cb1263a3cfa1b8edf4b0a636a9e579cd (patch) | |
tree | a613a243f48ed91513d288857dbfabeae0e8e1c3 | |
parent | bc8ffb2d0855b76dd0f8f0993cadf8ef0dfe0f0a (diff) |
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 <[email protected]>
Signed-off-by: Brian Behlendorf <[email protected]>
Issue #3858
-rw-r--r-- | module/zfs/zfs_znode.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c index d39743de9..8fd16408b 100644 --- a/module/zfs/zfs_znode.c +++ b/module/zfs/zfs_znode.c @@ -485,6 +485,7 @@ zfs_inode_update(znode_t *zp) zfs_sb_t *zsb; struct inode *ip; uint32_t blksize; + u_longlong_t i_blocks; uint64_t atime[2], mtime[2], ctime[2]; 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_CTIME(zsb), &ctime, 16); + dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &blksize, &i_blocks); + spin_lock(&ip->i_lock); ip->i_generation = zp->z_gen; 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; zfs_set_inode_flags(zp, ip); ip->i_blkbits = SPA_MINBLOCKSHIFT; - dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &blksize, - (u_longlong_t *)&ip->i_blocks); + ip->i_blocks = i_blocks; ZFS_TIME_DECODE(&ip->i_atime, atime); ZFS_TIME_DECODE(&ip->i_mtime, mtime); |