summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorMark Shellenbaum <Mark.Shellenbaum@Sun.COM>2009-08-06 12:51:48 -0600
committerMark Shellenbaum <Mark.Shellenbaum@Sun.COM>2009-08-06 12:51:48 -0600
commit6638ae1dc32acc370fecf2c4ce2e588f1183dd6e (patch)
tree6f648d5c57647b211cabb8cee7af89056a00484a /usr/src
parentd7747cbcf0e2da91e8d0e3dfd6d3ac45da469773 (diff)
downloadillumos-joyent-6638ae1dc32acc370fecf2c4ce2e588f1183dd6e.tar.gz
6868276 zfs_rezget() can be hazardous when znode has a cached ACL
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/zfs/zfs_znode.c15
1 files changed, 10 insertions, 5 deletions
diff --git a/usr/src/uts/common/fs/zfs/zfs_znode.c b/usr/src/uts/common/fs/zfs/zfs_znode.c
index f99e72f1d5..62156fb4f6 100644
--- a/usr/src/uts/common/fs/zfs/zfs_znode.c
+++ b/usr/src/uts/common/fs/zfs/zfs_znode.c
@@ -202,11 +202,8 @@ zfs_znode_move_impl(znode_t *ozp, znode_t *nzp)
nzp->z_dbuf = ozp->z_dbuf;
/*
- * Release any cached ACL, since it *may* have
- * zfs_acl_node_t's that directly references an
- * embedded ACL in the zp_acl of the old znode_phys_t
- *
- * It will be recached the next time the ACL is needed.
+ * Since this is just an idle znode and kmem is already dealing with
+ * memory pressure, release any cached ACL.
*/
if (ozp->z_acl_cached) {
zfs_acl_free(ozp->z_acl_cached);
@@ -571,6 +568,7 @@ zfs_znode_dmu_init(zfsvfs_t *zfsvfs, znode_t *zp, dmu_buf_t *db)
mutex_enter(&zp->z_lock);
ASSERT(zp->z_dbuf == NULL);
+ ASSERT(zp->z_acl_cached == NULL);
zp->z_dbuf = db;
nzp = dmu_buf_set_user_ie(db, zp, &zp->z_phys, znode_evict_error);
@@ -1003,6 +1001,13 @@ zfs_rezget(znode_t *zp)
return (EIO);
}
+ mutex_enter(&zp->z_acl_lock);
+ if (zp->z_acl_cached) {
+ zfs_acl_free(zp->z_acl_cached);
+ zp->z_acl_cached = NULL;
+ }
+ mutex_exit(&zp->z_acl_lock);
+
zfs_znode_dmu_init(zfsvfs, zp, db);
zp->z_unlinked = (zp->z_phys->zp_links == 0);
zp->z_blksz = doi.doi_data_block_size;