summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sys/zfs_znode.h11
-rw-r--r--module/zfs/zfs_znode.c86
2 files changed, 36 insertions, 61 deletions
diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h
index aa1f449ac..356092169 100644
--- a/include/sys/zfs_znode.h
+++ b/include/sys/zfs_znode.h
@@ -211,6 +211,8 @@ typedef struct znode {
list_node_t z_link_node; /* all znodes in fs link */
sa_handle_t *z_sa_hdl; /* handle to sa data */
boolean_t z_is_sa; /* are we native sa? */
+ void (*z_set_ops_inode) (struct inode *); /* set inode ops */
+ struct inode z_inode; /* generic vfs inode */
} znode_t;
@@ -231,13 +233,18 @@ typedef struct znode {
*/
/*
- * Convert between znode pointers and vnode pointers
+ * Convert between znode pointers and inode pointers
*/
+#define ZTOI(ZP) (&((ZP)->z_inode))
+#define ITOZ(IP) (container_of((IP), znode_t, z_inode))
+
+/* XXX - REMOVE ME ONCE THE OTHER BUILD ISSUES ARE RESOLVED */
#define ZTOV(ZP) ((ZP)->z_vnode)
#define VTOZ(VP) ((znode_t *)(VP)->v_data)
+
/*
- * ZFS_ENTER() is called on entry to each ZFS vnode and vfs operation.
+ * ZFS_ENTER() is called on entry to each ZFS inode and vfs operation.
* ZFS_EXIT() must be called before exitting the vop.
* ZFS_VERIFY_ZP() verifies the znode is valid.
*/
diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c
index 72a077d08..7823bc5e7 100644
--- a/module/zfs/zfs_znode.c
+++ b/module/zfs/zfs_znode.c
@@ -425,7 +425,7 @@ zfs_znode_dmu_fini(znode_t *zp)
}
/*
- * Construct a new znode/vnode and intialize.
+ * Construct a new znode+inode and initialize.
*
* 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
@@ -436,16 +436,19 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
dmu_object_type_t obj_type, sa_handle_t *hdl)
{
znode_t *zp;
-#ifdef HAVE_ZPL
- vnode_t *vp;
- uint64_t mode;
+ struct inode *inode;
uint64_t parent;
sa_bulk_attr_t bulk[9];
int count = 0;
-#endif /* HAVE_ZPL */
- zp = kmem_cache_alloc(znode_cache, KM_SLEEP);
+ ASSERT(zfsvfs != NULL);
+ ASSERT(zfsvfs->z_vfs != NULL);
+ ASSERT(zfsvfs->z_vfs->mnt_sb != NULL);
+
+ inode = iget_locked(zfsvfs->z_vfs->mnt_sb, db->db_object);
+ zp = ITOZ(inode);
+ ASSERT(inode->i_state & I_NEW);
ASSERT(zp->z_dirlocks == NULL);
ASSERT(!POINTER_IS_VALID(zp->z_zfsvfs));
zp->z_moved = 0;
@@ -463,21 +466,20 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
zp->z_seq = 0x7A4653;
zp->z_sync_cnt = 0;
-#ifdef HAVE_ZPL
- vp = ZTOV(zp);
- vn_reinit(vp);
-
zfs_znode_sa_init(zfsvfs, zp, db, obj_type, hdl);
- SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8);
- SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL, &zp->z_gen, 8);
+ SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL,
+ &zp->z_mode, 8);
+ SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GEN(zfsvfs), NULL,
+ &zp->z_gen, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL,
&zp->z_size, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL,
&zp->z_links, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL,
&zp->z_pflags, 8);
- SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, &parent, 8);
+ SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL,
+ &parent, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ATIME(zfsvfs), NULL,
&zp->z_atime, 16);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL,
@@ -488,57 +490,23 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
if (sa_bulk_lookup(zp->z_sa_hdl, bulk, count) != 0 || zp->z_gen == 0) {
if (hdl == NULL)
sa_handle_destroy(zp->z_sa_hdl);
- kmem_cache_free(znode_cache, zp);
+ iput(inode);
return (NULL);
}
- zp->z_mode = mode;
- vp->v_vfsp = zfsvfs->z_parent->z_vfs;
+ inode->i_mode = (umode_t)zp->z_mode;
+ if ((S_ISCHR(inode->i_mode)) || (S_ISBLK(inode->i_mode))) {
+ uint64_t rdev;
+ VERIFY(sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zfsvfs),
+ &rdev, sizeof (rdev)) == 0);
+ inode->i_rdev = zfs_cmpldev(rdev);
+ }
- vp->v_type = IFTOVT((mode_t)mode);
+ /* zp->z_set_ops_inode() must be set in sb->alloc_inode() */
+ ASSERT(zp->z_set_ops_inode != NULL);
+ zp->z_set_ops_inode(inode);
+ unlock_new_inode(inode);
- switch (vp->v_type) {
- case VDIR:
- if (zp->z_pflags & ZFS_XATTR) {
- vn_setops(vp, zfs_xdvnodeops);
- vp->v_flag |= V_XATTRDIR;
- } else {
- vn_setops(vp, zfs_dvnodeops);
- }
- zp->z_zn_prefetch = B_TRUE; /* z_prefetch default is enabled */
- break;
- case VBLK:
- case VCHR:
- {
- uint64_t rdev;
- VERIFY(sa_lookup(zp->z_sa_hdl, SA_ZPL_RDEV(zfsvfs),
- &rdev, sizeof (rdev)) == 0);
-
- vp->v_rdev = zfs_cmpldev(rdev);
- }
- /*FALLTHROUGH*/
- case VFIFO:
- case VSOCK:
- case VDOOR:
- vn_setops(vp, zfs_fvnodeops);
- break;
- case VREG:
- vp->v_flag |= VMODSORT;
- if (parent == zfsvfs->z_shares_dir) {
- ASSERT(zp->z_uid == 0 && zp->z_gid == 0);
- vn_setops(vp, zfs_sharevnodeops);
- } else {
- vn_setops(vp, zfs_fvnodeops);
- }
- break;
- case VLNK:
- vn_setops(vp, zfs_symvnodeops);
- break;
- default:
- vn_setops(vp, zfs_evnodeops);
- break;
- }
-#endif /* HAVE_ZPL */
mutex_enter(&zfsvfs->z_znodes_lock);
list_insert_tail(&zfsvfs->z_all_znodes, zp);
membar_producer();