summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/sys/zfs_znode.h1
-rw-r--r--module/zfs/zfs_vfsops.c3
-rw-r--r--module/zfs/zfs_vnops.c33
-rw-r--r--module/zfs/zfs_znode.c42
4 files changed, 77 insertions, 2 deletions
diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h
index 356092169..4dbecb4b5 100644
--- a/include/sys/zfs_znode.h
+++ b/include/sys/zfs_znode.h
@@ -326,6 +326,7 @@ extern dev_t zfs_cmpldev(uint64_t);
extern int zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value);
extern int zfs_get_stats(objset_t *os, nvlist_t *nv);
extern void zfs_znode_dmu_fini(znode_t *);
+extern void zfs_inode_update(znode_t *);
extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
znode_t *dzp, znode_t *zp, char *name, vsecattr_t *, zfs_fuid_info_t *,
diff --git a/module/zfs/zfs_vfsops.c b/module/zfs/zfs_vfsops.c
index ef433125a..4545c20e2 100644
--- a/module/zfs/zfs_vfsops.c
+++ b/module/zfs/zfs_vfsops.c
@@ -1942,6 +1942,9 @@ zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp)
}
*vpp = ZTOV(zp);
+ if (*vpp)
+ zfs_inode_update(VTOZ(*vpp));
+
ZFS_EXIT(zfsvfs);
return (0);
}
diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c
index b666ee39c..e5e187b15 100644
--- a/module/zfs/zfs_vnops.c
+++ b/module/zfs/zfs_vnops.c
@@ -564,6 +564,7 @@ out:
zfs_range_unlock(rl);
ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
+ zfs_inode_update(zp);
ZFS_EXIT(zfsvfs);
return (error);
}
@@ -938,6 +939,7 @@ again:
zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, zp->z_id);
+ zfs_inode_update(zp);
ZFS_EXIT(zfsvfs);
return (0);
}
@@ -1266,8 +1268,12 @@ zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, struct pathname *pnp,
}
error = zfs_dirlook(zdp, nm, vpp, flags, direntflags, realpnp);
- if (error == 0)
+ if (error == 0) {
+ if (*vpp)
+ zfs_inode_update(VTOZ(*vpp));
+
error = specvp_check(vpp, cr);
+ }
ZFS_EXIT(zfsvfs);
return (error);
@@ -1523,6 +1529,8 @@ out:
if (zp)
VN_RELE(ZTOV(zp));
} else {
+ zfs_inode_update(dzp);
+ zfs_inode_update(zp);
*vpp = ZTOV(zp);
error = specvp_check(vpp, cr);
}
@@ -1753,6 +1761,10 @@ out:
pn_free(realnmp);
zfs_dirent_unlock(dl);
+ zfs_inode_update(dzp);
+ zfs_inode_update(zp);
+ if (xzp)
+ zfs_inode_update(xzp);
if (!delete_now)
VN_RELE(vp);
@@ -1945,6 +1957,8 @@ top:
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0);
+ zfs_inode_update(dzp);
+ zfs_inode_update(zp);
ZFS_EXIT(zfsvfs);
return (0);
}
@@ -2074,6 +2088,8 @@ out:
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0);
+ zfs_inode_update(dzp);
+ zfs_inode_update(zp);
ZFS_EXIT(zfsvfs);
return (error);
}
@@ -3227,6 +3243,7 @@ out:
} else {
err2 = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
dmu_tx_commit(tx);
+ zfs_inode_update(zp);
}
out2:
@@ -3674,13 +3691,19 @@ out:
zfs_dirent_unlock(sdl);
zfs_dirent_unlock(tdl);
+ zfs_inode_update(sdzp);
if (sdzp == tdzp)
rw_exit(&sdzp->z_name_lock);
+ if (sdzp != tdzp)
+ zfs_inode_update(tdzp);
+ zfs_inode_update(szp);
VN_RELE(ZTOV(szp));
- if (tzp)
+ if (tzp) {
+ zfs_inode_update(tzp);
VN_RELE(ZTOV(tzp));
+ }
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0);
@@ -3828,6 +3851,9 @@ top:
txtype |= TX_CI;
zfs_log_symlink(zilog, tx, txtype, dzp, zp, name, link);
+ zfs_inode_update(dzp);
+ zfs_inode_update(zp);
+
zfs_acl_ids_free(&acl_ids);
dmu_tx_commit(tx);
@@ -3882,6 +3908,7 @@ zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, caller_context_t *ct)
ZFS_ACCESSTIME_STAMP(zfsvfs, zp);
+ zfs_inode_update(zp);
ZFS_EXIT(zfsvfs);
return (error);
}
@@ -4037,6 +4064,8 @@ top:
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0);
+ zfs_inode_update(dzp);
+ zfs_inode_update(szp);
ZFS_EXIT(zfsvfs);
return (error);
}
diff --git a/module/zfs/zfs_znode.c b/module/zfs/zfs_znode.c
index 7823bc5e7..0ae16448f 100644
--- a/module/zfs/zfs_znode.c
+++ b/module/zfs/zfs_znode.c
@@ -521,6 +521,47 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int blksz,
return (zp);
}
+/*
+ * Update the embedded inode given the znode. We should work toward
+ * eliminating this function as soon as possible by removing values
+ * which are duplicated between the znode and inode. If the generic
+ * inode has the correct field it should be used, and the ZFS code
+ * updated to access the inode. This can be done incrementally.
+ */
+void
+zfs_inode_update(znode_t *zp)
+{
+ zfsvfs_t *zfsvfs;
+ struct inode *inode;
+ uint32_t blksize;
+ uint64_t atime[2], mtime[2], ctime[2];
+
+ ASSERT(zp != NULL);
+ zfsvfs = zp->z_zfsvfs;
+ inode = ZTOI(zp);
+
+ sa_lookup(zp->z_sa_hdl, SA_ZPL_ATIME(zfsvfs), &atime, 16);
+ sa_lookup(zp->z_sa_hdl, SA_ZPL_MTIME(zfsvfs), &mtime, 16);
+ sa_lookup(zp->z_sa_hdl, SA_ZPL_CTIME(zfsvfs), &ctime, 16);
+
+ spin_lock(&inode->i_lock);
+ inode->i_generation = zp->z_gen;
+ inode->i_uid = zp->z_uid;
+ inode->i_gid = zp->z_gid;
+ inode->i_nlink = zp->z_links;
+ inode->i_mode = zp->z_mode;
+ inode->i_blkbits = SPA_MINBLOCKSHIFT;
+ dmu_object_size_from_db(sa_get_db(zp->z_sa_hdl), &blksize,
+ (u_longlong_t *)&inode->i_blocks);
+
+ ZFS_TIME_DECODE(&inode->i_atime, atime);
+ ZFS_TIME_DECODE(&inode->i_mtime, mtime);
+ ZFS_TIME_DECODE(&inode->i_ctime, ctime);
+
+ i_size_write(inode, zp->z_size);
+ spin_unlock(&inode->i_lock);
+}
+
static uint64_t empty_xattr;
static uint64_t pad[4];
static zfs_acl_phys_t acl_phys;
@@ -1534,6 +1575,7 @@ log:
zfs_log_truncate(zilog, tx, TX_TRUNCATE, zp, off, len);
dmu_tx_commit(tx);
+ zfs_inode_update(zp);
return (0);
}