Module Name: src Committed By: hannken Date: Fri Dec 5 09:13:32 UTC 2014
Modified Files: src/external/cddl/osnet/dist/uts/common/fs/zfs: zfs_vfsops.c zfs_znode.c src/external/cddl/osnet/dist/uts/common/fs/zfs/sys: zfs_znode.h Log Message: Change zfs to vcache. - zfs_loadvnode() is based on zfs_zget() plus zfs_znode_alloc(). To generate a diff of this commit: cvs rdiff -u -r1.13 -r1.14 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c cvs rdiff -u -r1.17 -r1.18 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_znode.c cvs rdiff -u -r1.5 -r1.6 \ src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/zfs_znode.h Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c:1.13 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c:1.14 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c:1.13 Sat May 24 16:34:03 2014 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_vfsops.c Fri Dec 5 09:13:32 2014 @@ -104,6 +104,7 @@ static struct vfsops zfs_vfsops_template .vfs_statvfs = zfs_statvfs, .vfs_sync = zfs_sync, .vfs_vget = zfs_vget, + .vfs_loadvnode = zfs_loadvnode, .vfs_fhtovp = zfs_fhtovp, .vfs_init = zfs_init, .vfs_done = zfs_fini, Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_znode.c diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_znode.c:1.17 src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_znode.c:1.18 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_znode.c:1.17 Fri Dec 5 09:12:29 2014 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/zfs_znode.c Fri Dec 5 09:13:32 2014 @@ -596,95 +596,6 @@ zfs_znode_dmu_fini(znode_t *zp) } /* - * Construct a new znode/vnode and intialize. - * - * This does not do a call to dmu_set_user() that is - * up to the caller to do, in case you don't want to - * return the znode - */ - -static znode_t * -zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz) -{ - znode_t *zp; - vnode_t *vp; - int error; - - zp = kmem_cache_alloc(znode_cache, KM_SLEEP); - - for (;;) { - error = getnewvnode(VT_ZFS, zfsvfs->z_parent->z_vfs, - zfs_vnodeop_p, NULL, &zp->z_vnode); - if (__predict_true(error == 0)) - break; - printf("WARNING: zfs_znode_alloc: unable to get vnode, " - "error=%d\n", error); - (void)kpause("zfsnewvn", false, hz, NULL); - } - - ASSERT(zp->z_dirlocks == NULL); - ASSERT(zp->z_dbuf == NULL); - ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); - - /* - * Defer setting z_zfsvfs until the znode is ready to be a candidate for - * the zfs_znode_move() callback. - */ - zp->z_phys = NULL; - zp->z_unlinked = 0; - zp->z_atime_dirty = 0; - zp->z_mapcnt = 0; - zp->z_last_itx = 0; - zp->z_id = db->db_object; - zp->z_blksz = blksz; - zp->z_seq = 0x7A4653; - zp->z_sync_cnt = 0; - - vp = ZTOV(zp); - - zfs_znode_dmu_init(zfsvfs, zp, db); - - zp->z_gen = zp->z_phys->zp_gen; - - vp->v_vfsp = zfsvfs->z_parent->z_vfs; - vp->v_type = IFTOVT((mode_t)zp->z_phys->zp_mode); - vp->v_data = zp; - genfs_node_init(vp, &zfs_genfsops); - switch (vp->v_type) { - case VDIR: - zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */ - break; - case VBLK: - case VCHR: - /* XXX NetBSD vp->v_op = zfs_specop_p; */ - spec_node_init(vp, zfs_cmpldev(zp->z_phys->zp_rdev)); - break; - case VFIFO: - /* XXX NetBSD vp->v_op = zfs_fifoop_p; */ - break; - } - - dprintf("zfs_znode_alloc znode %p -- vnode %p\n", zp, vp); - dprintf("zfs_znode_alloc z_id %ld\n", zp->z_id); - //cpu_Debugger(); - - uvm_vnp_setsize(vp, zp->z_phys->zp_size); - - mutex_enter(&zfsvfs->z_znodes_lock); - list_insert_tail(&zfsvfs->z_all_znodes, zp); - membar_producer(); - /* - * Everything else must be valid before assigning z_zfsvfs makes the - * znode eligible for zfs_znode_move(). - */ - zp->z_zfsvfs = zfsvfs; - mutex_exit(&zfsvfs->z_znodes_lock); - - VFS_HOLD(zfsvfs->z_vfs); - return (zp); -} - -/* * Create a new DMU object to hold a zfs znode. * * IN: dzp - parent directory for new znode @@ -820,7 +731,12 @@ zfs_mknode(znode_t *dzp, vattr_t *vap, d pzp->zp_gid = acl_ids->z_fgid; pzp->zp_mode = acl_ids->z_mode; if (!(flag & IS_ROOT_NODE)) { - *zpp = zfs_znode_alloc(zfsvfs, db, 0); + struct vnode *vp; + + err = vcache_get(zfsvfs->z_vfs, &obj, sizeof(obj), &vp); + ASSERT3U(err, ==, 0); + *zpp = VTOZ(vp); + dmu_buf_rele(db, NULL); } else { /* * If we are creating the root node, the "parent" we @@ -905,84 +821,36 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xv } int -zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) +zfs_loadvnode(struct mount *mp, struct vnode *vp, + const void *key, size_t key_len, const void **new_key) { + uint64_t obj_num; + zfsvfs_t *zfsvfs; dmu_object_info_t doi; - dmu_buf_t *db; - znode_t *zp; - vnode_t *vp; - int err, first = 1; + dmu_buf_t *db; + znode_t *zp; + int err; - *zpp = NULL; -again: - ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); + KASSERT(key_len == sizeof(obj_num)); + memcpy(&obj_num, key, key_len); + + zfsvfs = mp->mnt_data; err = dmu_bonus_hold(zfsvfs->z_os, obj_num, NULL, &db); if (err) { - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); - return (err); + return err; } dmu_object_info_from_db(db, &doi); if (doi.doi_bonus_type != DMU_OT_ZNODE || doi.doi_bonus_size < sizeof (znode_phys_t)) { dmu_buf_rele(db, NULL); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); - return (EINVAL); + return EINVAL; } - zp = dmu_buf_get_user(db); - if (zp != NULL) { - mutex_enter(&zp->z_lock); - - /* - * Since we do immediate eviction of the z_dbuf, we - * should never find a dbuf with a znode that doesn't - * know about the dbuf. - */ - ASSERT3P(zp->z_dbuf, ==, db); - ASSERT3U(zp->z_id, ==, obj_num); - if (zp->z_unlinked) { - err = ENOENT; - } else { - if ((vp = ZTOV(zp)) != NULL) { - mutex_enter(vp->v_interlock); - mutex_exit(&zp->z_lock); - if (vget(vp, 0) != 0) { - dmu_buf_rele(db, NULL); - mutex_exit(vp->v_interlock); - goto again; - } - mutex_enter(&zp->z_lock); - } else { - if (first) { - ZFS_LOG(1, "dying znode detected (zp=%p)", zp); - first = 0; - } - /* - * znode is dying so we can't reuse it, we must - * wait until destruction is completed. - */ - dmu_buf_rele(db, NULL); - mutex_exit(&zp->z_lock); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); - kpause("zcollide", 0, 1, NULL); - goto again; - } - *zpp = zp; - err = 0; - } - - dmu_buf_rele(db, NULL); - mutex_exit(&zp->z_lock); - ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); - return (err); - } + KASSERT(dmu_buf_get_user(db) == NULL); /* - * 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 @@ -990,16 +858,98 @@ again: * file. */ - 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 { + if (((znode_phys_t *)db->db_data)->zp_gen == 0) { dmu_buf_rele(db, NULL); - err = ENOENT; + return ENOENT; + } + + zp = kmem_cache_alloc(znode_cache, KM_SLEEP); + + ASSERT(zp->z_dirlocks == NULL); + ASSERT(zp->z_dbuf == NULL); + ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs)); + + /* + * Defer setting z_zfsvfs until the znode is ready to be a candidate for + * the zfs_znode_move() callback. + */ + zp->z_phys = NULL; + zp->z_unlinked = 0; + zp->z_atime_dirty = 0; + zp->z_mapcnt = 0; + zp->z_last_itx = 0; + zp->z_id = db->db_object; + zp->z_blksz = doi.doi_data_block_size; + zp->z_seq = 0x7A4653; + zp->z_sync_cnt = 0; + zp->z_vnode = vp; + + zfs_znode_dmu_init(zfsvfs, zp, db); + + zp->z_gen = zp->z_phys->zp_gen; + + vp->v_op = zfs_vnodeop_p; + vp->v_tag = VT_ZFS; + vp->v_type = IFTOVT((mode_t)zp->z_phys->zp_mode); + vp->v_data = zp; + genfs_node_init(vp, &zfs_genfsops); + switch (vp->v_type) { + case VDIR: + zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */ + break; + case VBLK: + case VCHR: + /* XXX NetBSD vp->v_op = zfs_specop_p; */ + spec_node_init(vp, zfs_cmpldev(zp->z_phys->zp_rdev)); + break; + case VFIFO: + /* XXX NetBSD vp->v_op = zfs_fifoop_p; */ + break; + } + + dprintf("zfs_loadvnode znode %p -- vnode %p\n", zp, vp); + dprintf("zfs_loadvnode z_id %ld\n", zp->z_id); + + uvm_vnp_setsize(vp, zp->z_phys->zp_size); + + mutex_enter(&zfsvfs->z_znodes_lock); + list_insert_tail(&zfsvfs->z_all_znodes, zp); + membar_producer(); + /* + * Everything else must be valid before assigning z_zfsvfs makes the + * znode eligible for zfs_znode_move(). + */ + zp->z_zfsvfs = zfsvfs; + mutex_exit(&zfsvfs->z_znodes_lock); + + VFS_HOLD(zfsvfs->z_vfs); + + *new_key = &zp->z_id; + + return 0; +} + +int +zfs_zget(zfsvfs_t *zfsvfs, uint64_t obj_num, znode_t **zpp) +{ + struct vnode *vp; + int error; + + ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num); + + error = vcache_get(zfsvfs->z_vfs, &obj_num, sizeof(obj_num), &vp); + if (error == 0 && VTOZ(vp)->z_unlinked) { + vrele(vp); + error = ENOENT; } + if (error) + *zpp = NULL; + else + *zpp = VTOZ(vp); + ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num); - return (err); + + return error; } int @@ -1102,14 +1052,21 @@ void zfs_znode_free(znode_t *zp) { zfsvfs_t *zfsvfs = zp->z_zfsvfs; - struct vnode *vp = ZTOV(zp); + struct vnode *vp; - /* XXX Not all callers are from VOP_RECLAIM. What to do? */ - KASSERT(vp != NULL); - mutex_enter(vp->v_interlock); /* XXX Necessary? */ - genfs_node_destroy(vp); - vp->v_data = NULL; - mutex_exit(vp->v_interlock); + mutex_enter(&zp->z_lock); + vp = ZTOV(zp); + if (vp != NULL) { + vcache_remove(vp->v_mount, &zp->z_id, sizeof(zp->z_id)); + genfs_node_destroy(vp); + /* + * To interlock with zfs_sync(). + */ + mutex_enter(vp->v_interlock); + vp->v_data = NULL; + mutex_exit(vp->v_interlock); + } + mutex_exit(&zp->z_lock); dprintf("destroying znode %p\n", zp); //cpu_Debugger(); Index: src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/zfs_znode.h diff -u src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/zfs_znode.h:1.5 src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/zfs_znode.h:1.6 --- src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/zfs_znode.h:1.5 Mon Oct 15 14:03:06 2012 +++ src/external/cddl/osnet/dist/uts/common/fs/zfs/sys/zfs_znode.h Fri Dec 5 09:13:32 2014 @@ -318,6 +318,8 @@ extern void zfs_grow_blocksize(znode_t * extern int zfs_freesp(znode_t *, uint64_t, uint64_t, int, boolean_t); extern void zfs_znode_init(void); extern void zfs_znode_fini(void); +extern int zfs_loadvnode(struct mount *, struct vnode *, + const void *, size_t, const void **); extern int zfs_zget(zfsvfs_t *, uint64_t, znode_t **); extern int zfs_rezget(znode_t *); extern void zfs_zinactive(znode_t *);