summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Yao <[email protected]>2015-09-30 13:25:11 -0400
committerBrian Behlendorf <[email protected]>2015-09-30 10:47:40 -0700
commit919efe93cb1263a3cfa1b8edf4b0a636a9e579cd (patch)
treea613a243f48ed91513d288857dbfabeae0e8e1c3
parentbc8ffb2d0855b76dd0f8f0993cadf8ef0dfe0f0a (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.c6
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);