Mercurial > illumos > illumos-gate
changeset 10938:270624bd70f1
6895088 panic: existing znode ffffff84e4747da0 for dbuf ffffff8271678e18
author | Mark Shellenbaum <Mark.Shellenbaum@Sun.COM> |
---|---|
date | Tue, 03 Nov 2009 11:02:16 -0700 |
parents | b6ce4b1e9e41 |
children | 343d43cca32b |
files | usr/src/uts/common/fs/zfs/zfs_znode.c |
diffstat | 1 files changed, 31 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/fs/zfs/zfs_znode.c Tue Nov 03 12:28:49 2009 -0500 +++ b/usr/src/uts/common/fs/zfs/zfs_znode.c Tue Nov 03 11:02:16 2009 -0700 @@ -767,6 +767,8 @@ DMU_OT_ZNODE, sizeof (znode_phys_t) + bonuslen, tx); } } + + ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, obj, NULL, &db)); dmu_buf_will_dirty(db, tx); @@ -825,12 +827,11 @@ } else { ZFS_TIME_ENCODE(&now, pzp->zp_mtime); } - - pzp->zp_mode = MAKEIMODE(vap->va_type, vap->va_mode); + pzp->zp_uid = acl_ids->z_fuid; + pzp->zp_gid = acl_ids->z_fgid; + pzp->zp_mode = acl_ids->z_mode; if (!(flag & IS_ROOT_NODE)) { - ZFS_OBJ_HOLD_ENTER(zfsvfs, obj); *zpp = zfs_znode_alloc(zfsvfs, db, 0); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); } else { /* * If we are creating the root node, the "parent" we @@ -838,12 +839,11 @@ */ *zpp = dzp; } - pzp->zp_uid = acl_ids->z_fuid; - pzp->zp_gid = acl_ids->z_fgid; - pzp->zp_mode = acl_ids->z_mode; VERIFY(0 == zfs_aclset_common(*zpp, acl_ids->z_aclp, cr, tx)); if (vap->va_mask & AT_XVATTR) zfs_xvattr_set(*zpp, (xvattr_t *)vap); + + ZFS_OBJ_HOLD_EXIT(zfsvfs, obj); } void @@ -967,11 +967,25 @@ /* * Not found create new znode/vnode + * but only if file exists. + * + * There is a small window where zfs_vget() could + * find this object while a file create is still in + * progress. Since a gen number can never be zero + * we will check that to determine if its an allocated + * file. */ - zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size); + + if (((znode_phys_t *)db->db_data)->zp_gen != 0) { + zp = zfs_znode_alloc(zfsvfs, db, doi.doi_data_block_size); + *zpp = zp; + err = 0; + } else { + dmu_buf_rele(db, NULL); + err = ENOENT; + } ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); - *zpp = zp; - return (0); + return (err); } int @@ -1492,6 +1506,7 @@ uint64_t norm = 0; nvpair_t *elem; int error; + int i; znode_t *rootzp = NULL; vnode_t *vp; vattr_t vattr; @@ -1587,6 +1602,9 @@ list_create(&zfsvfs.z_all_znodes, sizeof (znode_t), offsetof(znode_t, z_link_node)); + for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) + mutex_init(&zfsvfs.z_hold_mtx[i], NULL, MUTEX_DEFAULT, NULL); + ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs)); rootzp->z_zfsvfs = &zfsvfs; VERIFY(0 == zfs_acl_ids_create(rootzp, IS_ROOT_NODE, &vattr, @@ -1611,6 +1629,9 @@ error = zfs_create_share_dir(&zfsvfs, tx); ASSERT(error == 0); + + for (i = 0; i != ZFS_OBJ_MTX_SZ; i++) + mutex_destroy(&zfsvfs.z_hold_mtx[i]); } #endif /* _KERNEL */