Eliminate Linux specific inode usage from common code

Change many of the znops routines to take a znode rather
than an inode so that zfs_replay code can be largely shared
and in the future the much of the znops code may be shared.

Reviewed-by: Jorgen Lundman <lundman@lundman.net>
Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Signed-off-by: Matt Macy <mmacy@FreeBSD.org>
Closes #9708
This commit is contained in:
Matthew Macy 2019-12-11 11:53:57 -08:00 committed by Brian Behlendorf
parent f0bf435176
commit 657ce25357
18 changed files with 346 additions and 333 deletions

View File

@ -55,7 +55,7 @@ extern void zfs_dirent_unlock(zfs_dirlock_t *);
extern int zfs_link_create(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int); extern int zfs_link_create(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int);
extern int zfs_link_destroy(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int, extern int zfs_link_destroy(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int,
boolean_t *); boolean_t *);
extern int zfs_dirlook(znode_t *, char *, struct inode **, int, int *, extern int zfs_dirlook(znode_t *, char *, znode_t **, int, int *,
pathname_t *); pathname_t *);
extern void zfs_mknode(znode_t *, vattr_t *, dmu_tx_t *, cred_t *, extern void zfs_mknode(znode_t *, vattr_t *, dmu_tx_t *, cred_t *,
uint_t, znode_t **, zfs_acl_ids_t *); uint_t, znode_t **, zfs_acl_ids_t *);
@ -66,8 +66,8 @@ extern void zfs_unlinked_add(znode_t *, dmu_tx_t *);
extern void zfs_unlinked_drain(zfsvfs_t *zfsvfs); extern void zfs_unlinked_drain(zfsvfs_t *zfsvfs);
extern void zfs_unlinked_drain_stop_wait(zfsvfs_t *zfsvfs); extern void zfs_unlinked_drain_stop_wait(zfsvfs_t *zfsvfs);
extern int zfs_sticky_remove_access(znode_t *, znode_t *, cred_t *cr); extern int zfs_sticky_remove_access(znode_t *, znode_t *, cred_t *cr);
extern int zfs_get_xattrdir(znode_t *, struct inode **, cred_t *, int); extern int zfs_get_xattrdir(znode_t *, znode_t **, cred_t *, int);
extern int zfs_make_xattrdir(znode_t *, vattr_t *, struct inode **, cred_t *); extern int zfs_make_xattrdir(znode_t *, vattr_t *, znode_t **, cred_t *);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -44,36 +44,36 @@ extern int zfs_holey(struct inode *ip, int cmd, loff_t *off);
extern int zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr); extern int zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
extern int zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr); extern int zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
extern int zfs_access(struct inode *ip, int mode, int flag, cred_t *cr); extern int zfs_access(struct inode *ip, int mode, int flag, cred_t *cr);
extern int zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, extern int zfs_lookup(znode_t *dzp, char *nm, znode_t **zpp,
int flags, cred_t *cr, int *direntflags, pathname_t *realpnp); int flags, cred_t *cr, int *direntflags, pathname_t *realpnp);
extern int zfs_create(struct inode *dip, char *name, vattr_t *vap, int excl, extern int zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp);
extern int zfs_tmpfile(struct inode *dip, vattr_t *vapzfs, int excl,
int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp); int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp);
extern int zfs_tmpfile(struct inode *dip, vattr_t *vap, int excl, extern int zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags);
int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp); extern int zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap,
extern int zfs_remove(struct inode *dip, char *name, cred_t *cr, int flags); znode_t **zpp, cred_t *cr, int flags, vsecattr_t *vsecp);
extern int zfs_mkdir(struct inode *dip, char *dirname, vattr_t *vap, extern int zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd,
struct inode **ipp, cred_t *cr, int flags, vsecattr_t *vsecp);
extern int zfs_rmdir(struct inode *dip, char *name, struct inode *cwd,
cred_t *cr, int flags); cred_t *cr, int flags);
extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr); extern int zfs_readdir(struct inode *ip, zpl_dir_context_t *ctx, cred_t *cr);
extern int zfs_fsync(struct inode *ip, int syncflag, cred_t *cr); extern int zfs_fsync(znode_t *zp, int syncflag, cred_t *cr);
extern int zfs_getattr(struct inode *ip, vattr_t *vap, int flag, cred_t *cr); extern int zfs_getattr(struct inode *ip, vattr_t *vap, int flag, cred_t *cr);
extern int zfs_getattr_fast(struct inode *ip, struct kstat *sp); extern int zfs_getattr_fast(struct inode *ip, struct kstat *sp);
extern int zfs_setattr(struct inode *ip, vattr_t *vap, int flag, cred_t *cr); extern int zfs_setattr(znode_t *zp, vattr_t *vap, int flag, cred_t *cr);
extern int zfs_rename(struct inode *sdip, char *snm, struct inode *tdip, extern int zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp,
char *tnm, cred_t *cr, int flags); char *tnm, cred_t *cr, int flags);
extern int zfs_symlink(struct inode *dip, char *name, vattr_t *vap, extern int zfs_symlink(znode_t *dzp, char *name, vattr_t *vap,
char *link, struct inode **ipp, cred_t *cr, int flags); char *link, znode_t **zpp, cred_t *cr, int flags);
extern int zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr); extern int zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr);
extern int zfs_link(struct inode *tdip, struct inode *sip, extern int zfs_link(znode_t *tdzp, znode_t *szp,
char *name, cred_t *cr, int flags); char *name, cred_t *cr, int flags);
extern void zfs_inactive(struct inode *ip); extern void zfs_inactive(struct inode *ip);
extern int zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag, extern int zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
offset_t offset, cred_t *cr); offset_t offset, cred_t *cr);
extern int zfs_fid(struct inode *ip, fid_t *fidp); extern int zfs_fid(struct inode *ip, fid_t *fidp);
extern int zfs_getsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, extern int zfs_getsecattr(struct inode *ip, vsecattr_t *vsecp, int flag,
cred_t *cr); cred_t *cr);
extern int zfs_setsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, extern int zfs_setsecattr(znode_t *zp, vsecattr_t *vsecp, int flag,
cred_t *cr); cred_t *cr);
extern int zfs_getpage(struct inode *ip, struct page *pl[], int nr_pages); extern int zfs_getpage(struct inode *ip, struct page *pl[], int nr_pages);
extern int zfs_putpage(struct inode *ip, struct page *pp, extern int zfs_putpage(struct inode *ip, struct page *pp,
@ -81,7 +81,7 @@ extern int zfs_putpage(struct inode *ip, struct page *pp,
extern int zfs_dirty_inode(struct inode *ip, int flags); extern int zfs_dirty_inode(struct inode *ip, int flags);
extern int zfs_map(struct inode *ip, offset_t off, caddr_t *addrp, extern int zfs_map(struct inode *ip, offset_t off, caddr_t *addrp,
size_t len, unsigned long vm_flags); size_t len, unsigned long vm_flags);
extern void zfs_iput_async(struct inode *ip); extern void zfs_zrele_async(znode_t *zp);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -69,6 +69,9 @@ extern "C" {
#define Z_ISLNK(type) S_ISLNK(type) #define Z_ISLNK(type) S_ISLNK(type)
#define Z_ISDEV(type) (S_ISCHR(type) || S_ISBLK(type) || S_ISFIFO(type)) #define Z_ISDEV(type) (S_ISCHR(type) || S_ISBLK(type) || S_ISFIFO(type))
#define zhold(zp) igrab(ZTOI((zp)))
#define zrele(zp) iput(ZTOI((zp)))
/* Called on entry to each ZFS inode and vfs operation. */ /* Called on entry to each ZFS inode and vfs operation. */
#define ZFS_ENTER_ERROR(zfsvfs, error) \ #define ZFS_ENTER_ERROR(zfsvfs, error) \
do { \ do { \

View File

@ -96,7 +96,7 @@ typedef struct dsl_pool {
struct dsl_dir *dp_leak_dir; struct dsl_dir *dp_leak_dir;
struct dsl_dataset *dp_origin_snap; struct dsl_dataset *dp_origin_snap;
uint64_t dp_root_dir_obj; uint64_t dp_root_dir_obj;
struct taskq *dp_iput_taskq; struct taskq *dp_zrele_taskq;
struct taskq *dp_unlinked_drain_taskq; struct taskq *dp_unlinked_drain_taskq;
/* No lock needed - sync context only */ /* No lock needed - sync context only */
@ -177,7 +177,7 @@ void dsl_pool_config_exit(dsl_pool_t *dp, void *tag);
boolean_t dsl_pool_config_held(dsl_pool_t *dp); boolean_t dsl_pool_config_held(dsl_pool_t *dp);
boolean_t dsl_pool_config_held_writer(dsl_pool_t *dp); boolean_t dsl_pool_config_held_writer(dsl_pool_t *dp);
taskq_t *dsl_pool_iput_taskq(dsl_pool_t *dp); taskq_t *dsl_pool_zrele_taskq(dsl_pool_t *dp);
taskq_t *dsl_pool_unlinked_drain_taskq(dsl_pool_t *dp); taskq_t *dsl_pool_unlinked_drain_taskq(dsl_pool_t *dp);
int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj, int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj,

View File

@ -2540,14 +2540,14 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
if ((error = zfs_zaccess_common(check_zp, mode, &working_mode, if ((error = zfs_zaccess_common(check_zp, mode, &working_mode,
&check_privs, skipaclchk, cr)) == 0) { &check_privs, skipaclchk, cr)) == 0) {
if (is_attr) if (is_attr)
iput(ZTOI(xzp)); zrele(xzp);
return (secpolicy_vnode_access2(cr, ZTOI(zp), owner, return (secpolicy_vnode_access2(cr, ZTOI(zp), owner,
needed_bits, needed_bits)); needed_bits, needed_bits));
} }
if (error && !check_privs) { if (error && !check_privs) {
if (is_attr) if (is_attr)
iput(ZTOI(xzp)); zrele(xzp);
return (error); return (error);
} }
@ -2609,7 +2609,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
} }
if (is_attr) if (is_attr)
iput(ZTOI(xzp)); zrele(xzp);
return (error); return (error);
} }

View File

@ -1185,7 +1185,7 @@ zfsctl_shares_lookup(struct inode *dip, char *name, struct inode **ipp,
int flags, cred_t *cr, int *direntflags, pathname_t *realpnp) int flags, cred_t *cr, int *direntflags, pathname_t *realpnp)
{ {
zfsvfs_t *zfsvfs = ITOZSB(dip); zfsvfs_t *zfsvfs = ITOZSB(dip);
struct inode *ip; znode_t *zp;
znode_t *dzp; znode_t *dzp;
int error; int error;
@ -1197,8 +1197,8 @@ zfsctl_shares_lookup(struct inode *dip, char *name, struct inode **ipp,
} }
if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) { if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &dzp)) == 0) {
error = zfs_lookup(ZTOI(dzp), name, &ip, 0, cr, NULL, NULL); error = zfs_lookup(dzp, name, &zp, 0, cr, NULL, NULL);
iput(ZTOI(dzp)); zrele(dzp);
} }
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);

View File

@ -377,17 +377,18 @@ zfs_dirent_unlock(zfs_dirlock_t *dl)
* special pseudo-directory. * special pseudo-directory.
*/ */
int int
zfs_dirlook(znode_t *dzp, char *name, struct inode **ipp, int flags, zfs_dirlook(znode_t *dzp, char *name, znode_t **zpp, int flags,
int *deflg, pathname_t *rpnp) int *deflg, pathname_t *rpnp)
{ {
zfs_dirlock_t *dl; zfs_dirlock_t *dl;
znode_t *zp; znode_t *zp;
struct inode *ip;
int error = 0; int error = 0;
uint64_t parent; uint64_t parent;
if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) { if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) {
*ipp = ZTOI(dzp); *zpp = dzp;
igrab(*ipp); zhold(*zpp);
} else if (name[0] == '.' && name[1] == '.' && name[2] == 0) { } else if (name[0] == '.' && name[1] == '.' && name[2] == 0) {
zfsvfs_t *zfsvfs = ZTOZSB(dzp); zfsvfs_t *zfsvfs = ZTOZSB(dzp);
@ -401,16 +402,18 @@ zfs_dirlook(znode_t *dzp, char *name, struct inode **ipp, int flags,
if (parent == dzp->z_id && zfsvfs->z_parent != zfsvfs) { if (parent == dzp->z_id && zfsvfs->z_parent != zfsvfs) {
error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir, error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir,
"snapshot", ipp, 0, kcred, NULL, NULL); "snapshot", &ip, 0, kcred, NULL, NULL);
*zpp = ITOZ(ip);
return (error); return (error);
} }
rw_enter(&dzp->z_parent_lock, RW_READER); rw_enter(&dzp->z_parent_lock, RW_READER);
error = zfs_zget(zfsvfs, parent, &zp); error = zfs_zget(zfsvfs, parent, &zp);
if (error == 0) if (error == 0)
*ipp = ZTOI(zp); *zpp = zp;
rw_exit(&dzp->z_parent_lock); rw_exit(&dzp->z_parent_lock);
} else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) { } else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) {
*ipp = zfsctl_root(dzp); ip = zfsctl_root(dzp);
*zpp = ITOZ(ip);
} else { } else {
int zf; int zf;
@ -420,7 +423,7 @@ zfs_dirlook(znode_t *dzp, char *name, struct inode **ipp, int flags,
error = zfs_dirent_lock(&dl, dzp, name, &zp, zf, deflg, rpnp); error = zfs_dirent_lock(&dl, dzp, name, &zp, zf, deflg, rpnp);
if (error == 0) { if (error == 0) {
*ipp = ZTOI(zp); *zpp = zp;
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */ dzp->z_zn_prefetch = B_TRUE; /* enable prefetching */
} }
@ -513,13 +516,13 @@ zfs_unlinked_drain_task(void *arg)
zp->z_unlinked = B_TRUE; zp->z_unlinked = B_TRUE;
/* /*
* iput() is Linux's equivalent to illumos' VN_RELE(). It will * zrele() decrements the znode's ref count and may cause
* decrement the inode's ref count and may cause the inode to be * it to be synchronously freed. We interrupt freeing
* synchronously freed. We interrupt freeing of this inode, by * of this znode by checking the return value of
* checking the return value of dmu_objset_zfs_unmounting() in * dmu_objset_zfs_unmounting() in dmu_free_long_range()
* dmu_free_long_range(), when an unmount is requested. * when an unmount is requested.
*/ */
iput(ZTOI(zp)); zrele(zp);
ASSERT3B(zfsvfs->z_unmounted, ==, B_FALSE); ASSERT3B(zfsvfs->z_unmounted, ==, B_FALSE);
} }
zap_cursor_fini(&zc); zap_cursor_fini(&zc);
@ -615,7 +618,7 @@ zfs_purgedir(znode_t *dzp)
error = dmu_tx_assign(tx, TXG_WAIT); error = dmu_tx_assign(tx, TXG_WAIT);
if (error) { if (error) {
dmu_tx_abort(tx); dmu_tx_abort(tx);
zfs_iput_async(ZTOI(xzp)); zfs_zrele_async(xzp);
skipped += 1; skipped += 1;
continue; continue;
} }
@ -628,7 +631,7 @@ zfs_purgedir(znode_t *dzp)
skipped += 1; skipped += 1;
dmu_tx_commit(tx); dmu_tx_commit(tx);
zfs_iput_async(ZTOI(xzp)); zfs_zrele_async(xzp);
} }
zap_cursor_fini(&zc); zap_cursor_fini(&zc);
if (error != ENOENT) if (error != ENOENT)
@ -747,7 +750,7 @@ zfs_rmnode(znode_t *zp)
dmu_tx_commit(tx); dmu_tx_commit(tx);
out: out:
if (xzp) if (xzp)
zfs_iput_async(ZTOI(xzp)); zfs_zrele_async(xzp);
} }
static uint64_t static uint64_t
@ -1031,7 +1034,7 @@ zfs_dirempty(znode_t *dzp)
} }
int int
zfs_make_xattrdir(znode_t *zp, vattr_t *vap, struct inode **xipp, cred_t *cr) zfs_make_xattrdir(znode_t *zp, vattr_t *vap, znode_t **xzpp, cred_t *cr)
{ {
zfsvfs_t *zfsvfs = ZTOZSB(zp); zfsvfs_t *zfsvfs = ZTOZSB(zp);
znode_t *xzp; znode_t *xzp;
@ -1043,7 +1046,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, struct inode **xipp, cred_t *cr)
uint64_t parent; uint64_t parent;
#endif #endif
*xipp = NULL; *xzpp = NULL;
if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr))) if ((error = zfs_zaccess(zp, ACE_WRITE_NAMED_ATTRS, 0, B_FALSE, cr)))
return (error); return (error);
@ -1091,7 +1094,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, struct inode **xipp, cred_t *cr)
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
dmu_tx_commit(tx); dmu_tx_commit(tx);
*xipp = ZTOI(xzp); *xzpp = xzp;
return (0); return (0);
} }
@ -1110,7 +1113,7 @@ zfs_make_xattrdir(znode_t *zp, vattr_t *vap, struct inode **xipp, cred_t *cr)
* error number on failure * error number on failure
*/ */
int int
zfs_get_xattrdir(znode_t *zp, struct inode **xipp, cred_t *cr, int flags) zfs_get_xattrdir(znode_t *zp, znode_t **xzpp, cred_t *cr, int flags)
{ {
zfsvfs_t *zfsvfs = ZTOZSB(zp); zfsvfs_t *zfsvfs = ZTOZSB(zp);
znode_t *xzp; znode_t *xzp;
@ -1123,7 +1126,7 @@ top:
return (error); return (error);
if (xzp != NULL) { if (xzp != NULL) {
*xipp = ZTOI(xzp); *xzpp = xzp;
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
return (0); return (0);
} }
@ -1153,7 +1156,7 @@ top:
zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid); zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid);
va.va_dentry = NULL; va.va_dentry = NULL;
error = zfs_make_xattrdir(zp, &va, xipp, cr); error = zfs_make_xattrdir(zp, &va, xzpp, cr);
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
if (error == ERESTART) { if (error == ERESTART) {

View File

@ -1658,7 +1658,7 @@ zfs_prune_aliases(zfsvfs_t *zfsvfs, unsigned long nr_to_scan)
if (atomic_read(&ZTOI(zp)->i_count) == 1) if (atomic_read(&ZTOI(zp)->i_count) == 1)
objects++; objects++;
iput(ZTOI(zp)); zrele(zp);
} }
kmem_free(zp_array, max_array * sizeof (znode_t *)); kmem_free(zp_array, max_array * sizeof (znode_t *));
@ -1742,7 +1742,7 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
/* /*
* If someone has not already unmounted this file system, * If someone has not already unmounted this file system,
* drain the iput_taskq to ensure all active references to the * drain the zrele_taskq to ensure all active references to the
* zfsvfs_t have been handled only then can it be safely destroyed. * zfsvfs_t have been handled only then can it be safely destroyed.
*/ */
if (zfsvfs->z_os) { if (zfsvfs->z_os) {
@ -1761,7 +1761,7 @@ zfsvfs_teardown(zfsvfs_t *zfsvfs, boolean_t unmounting)
*/ */
int round = 0; int round = 0;
while (zfsvfs->z_nr_znodes > 0) { while (zfsvfs->z_nr_znodes > 0) {
taskq_wait_outstanding(dsl_pool_iput_taskq( taskq_wait_outstanding(dsl_pool_zrele_taskq(
dmu_objset_pool(zfsvfs->z_os)), 0); dmu_objset_pool(zfsvfs->z_os)), 0);
if (++round > 1 && !unmounting) if (++round > 1 && !unmounting)
break; break;
@ -2008,10 +2008,10 @@ zfs_preumount(struct super_block *sb)
zfs_unlinked_drain_stop_wait(zfsvfs); zfs_unlinked_drain_stop_wait(zfsvfs);
zfsctl_destroy(sb->s_fs_info); zfsctl_destroy(sb->s_fs_info);
/* /*
* Wait for iput_async before entering evict_inodes in * Wait for zrele_async before entering evict_inodes in
* generic_shutdown_super. The reason we must finish before * generic_shutdown_super. The reason we must finish before
* evict_inodes is when lazytime is on, or when zfs_purgedir * evict_inodes is when lazytime is on, or when zfs_purgedir
* calls zfs_zget, iput would bump i_count from 0 to 1. This * calls zfs_zget, zrele would bump i_count from 0 to 1. This
* would race with the i_count check in evict_inodes. This means * would race with the i_count check in evict_inodes. This means
* it could destroy the inode while we are still using it. * it could destroy the inode while we are still using it.
* *
@ -2019,12 +2019,12 @@ zfs_preumount(struct super_block *sb)
* may add xattr entries in zfs_purgedir, so in the second pass * may add xattr entries in zfs_purgedir, so in the second pass
* we wait for them. We don't use taskq_wait here because it is * we wait for them. We don't use taskq_wait here because it is
* a pool wide taskq. Other mounted filesystems can constantly * a pool wide taskq. Other mounted filesystems can constantly
* do iput_async and there's no guarantee when taskq will be * do zrele_async and there's no guarantee when taskq will be
* empty. * empty.
*/ */
taskq_wait_outstanding(dsl_pool_iput_taskq( taskq_wait_outstanding(dsl_pool_zrele_taskq(
dmu_objset_pool(zfsvfs->z_os)), 0); dmu_objset_pool(zfsvfs->z_os)), 0);
taskq_wait_outstanding(dsl_pool_iput_taskq( taskq_wait_outstanding(dsl_pool_zrele_taskq(
dmu_objset_pool(zfsvfs->z_os)), 0); dmu_objset_pool(zfsvfs->z_os)), 0);
} }
} }
@ -2180,7 +2180,7 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
/* Don't export xattr stuff */ /* Don't export xattr stuff */
if (zp->z_pflags & ZFS_XATTR) { if (zp->z_pflags & ZFS_XATTR) {
iput(ZTOI(zp)); zrele(zp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (SET_ERROR(ENOENT)); return (SET_ERROR(ENOENT));
} }
@ -2195,7 +2195,7 @@ zfs_vget(struct super_block *sb, struct inode **ipp, fid_t *fidp)
if (zp->z_unlinked || zp_gen != fid_gen) { if (zp->z_unlinked || zp_gen != fid_gen) {
dprintf("znode gen (%llu) != fid gen (%llu)\n", zp_gen, dprintf("znode gen (%llu) != fid gen (%llu)\n", zp_gen,
fid_gen); fid_gen);
iput(ZTOI(zp)); zrele(zp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (SET_ERROR(ENOENT)); return (SET_ERROR(ENOENT));
} }
@ -2281,7 +2281,7 @@ zfs_resume_fs(zfsvfs_t *zfsvfs, dsl_dataset_t *ds)
/* see comment in zfs_suspend_fs() */ /* see comment in zfs_suspend_fs() */
if (zp->z_suspended) { if (zp->z_suspended) {
zfs_iput_async(ZTOI(zp)); zfs_zrele_async(zp);
zp->z_suspended = B_FALSE; zp->z_suspended = B_FALSE;
} }
} }

View File

@ -86,7 +86,7 @@
* must be checked with ZFS_VERIFY_ZP(zp). Both of these macros * must be checked with ZFS_VERIFY_ZP(zp). Both of these macros
* can return EIO from the calling function. * can return EIO from the calling function.
* *
* (2) iput() should always be the last thing except for zil_commit() * (2) zrele() should always be the last thing except for zil_commit()
* (if necessary) and ZFS_EXIT(). This is for 3 reasons: * (if necessary) and ZFS_EXIT(). This is for 3 reasons:
* First, if it's the last reference, the vnode/znode * First, if it's the last reference, the vnode/znode
* can be freed, so the zp may point to freed memory. Second, the last * can be freed, so the zp may point to freed memory. Second, the last
@ -94,7 +94,7 @@
* pushing cached pages (which acquires range locks) and syncing out * pushing cached pages (which acquires range locks) and syncing out
* cached atime changes. Third, zfs_zinactive() may require a new tx, * cached atime changes. Third, zfs_zinactive() may require a new tx,
* which could deadlock the system if you were already holding one. * which could deadlock the system if you were already holding one.
* If you must call iput() within a tx then use zfs_iput_async(). * If you must call zrele() within a tx then use zfs_zrele_async().
* *
* (3) All range locks must be grabbed before calling dmu_tx_assign(), * (3) All range locks must be grabbed before calling dmu_tx_assign(),
* as they can span dmu_tx_assign() calls. * as they can span dmu_tx_assign() calls.
@ -148,7 +148,7 @@
* if (error) { * if (error) {
* rw_exit(...); // drop locks * rw_exit(...); // drop locks
* zfs_dirent_unlock(dl); // unlock directory entry * zfs_dirent_unlock(dl); // unlock directory entry
* iput(...); // release held vnodes * zrele(...); // release held znodes
* if (error == ERESTART) { * if (error == ERESTART) {
* waited = B_TRUE; * waited = B_TRUE;
* dmu_tx_wait(tx); * dmu_tx_wait(tx);
@ -165,7 +165,7 @@
* dmu_tx_commit(tx); // commit DMU tx -- error or not * dmu_tx_commit(tx); // commit DMU tx -- error or not
* rw_exit(...); // drop locks * rw_exit(...); // drop locks
* zfs_dirent_unlock(dl); // unlock directory entry * zfs_dirent_unlock(dl); // unlock directory entry
* iput(...); // release held vnodes * zrele(...); // release held znodes
* zil_commit(zilog, foid); // synchronous when necessary * zil_commit(zilog, foid); // synchronous when necessary
* ZFS_EXIT(zfsvfs); // finished in zfs * ZFS_EXIT(zfsvfs); // finished in zfs
* return (error); // done, report error * return (error); // done, report error
@ -979,18 +979,19 @@ zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr)
* in a deadlock if iput_final() re-enters the filesystem code. * in a deadlock if iput_final() re-enters the filesystem code.
*/ */
void void
zfs_iput_async(struct inode *ip) zfs_zrele_async(znode_t *zp)
{ {
struct inode *ip = ZTOI(zp);
objset_t *os = ITOZSB(ip)->z_os; objset_t *os = ITOZSB(ip)->z_os;
ASSERT(atomic_read(&ip->i_count) > 0); ASSERT(atomic_read(&ip->i_count) > 0);
ASSERT(os != NULL); ASSERT(os != NULL);
if (atomic_read(&ip->i_count) == 1) if (atomic_read(&ip->i_count) == 1)
VERIFY(taskq_dispatch(dsl_pool_iput_taskq(dmu_objset_pool(os)), VERIFY(taskq_dispatch(dsl_pool_zrele_taskq(dmu_objset_pool(os)),
(task_func_t *)iput, ip, TQ_SLEEP) != TASKQID_INVALID); (task_func_t *)iput, ip, TQ_SLEEP) != TASKQID_INVALID);
else else
iput(ip); zrele(zp);
} }
/* ARGSUSED */ /* ARGSUSED */
@ -1008,7 +1009,7 @@ zfs_get_done(zgd_t *zgd, int error)
* Release the vnode asynchronously as we currently have the * Release the vnode asynchronously as we currently have the
* txg stopped from syncing. * txg stopped from syncing.
*/ */
zfs_iput_async(ZTOI(zp)); zfs_zrele_async(zp);
kmem_free(zgd, sizeof (zgd_t)); kmem_free(zgd, sizeof (zgd_t));
} }
@ -1047,7 +1048,7 @@ zfs_get_data(void *arg, lr_write_t *lr, char *buf, struct lwb *lwb, zio_t *zio)
* Release the vnode asynchronously as we currently have the * Release the vnode asynchronously as we currently have the
* txg stopped from syncing. * txg stopped from syncing.
*/ */
zfs_iput_async(ZTOI(zp)); zfs_zrele_async(zp);
return (SET_ERROR(ENOENT)); return (SET_ERROR(ENOENT));
} }
@ -1171,14 +1172,14 @@ zfs_access(struct inode *ip, int mode, int flag, cred_t *cr)
* Lookup an entry in a directory, or an extended attribute directory. * Lookup an entry in a directory, or an extended attribute directory.
* If it exists, return a held inode reference for it. * If it exists, return a held inode reference for it.
* *
* IN: dip - inode of directory to search. * IN: zdp - znode of directory to search.
* nm - name of entry to lookup. * nm - name of entry to lookup.
* flags - LOOKUP_XATTR set if looking for an attribute. * flags - LOOKUP_XATTR set if looking for an attribute.
* cr - credentials of caller. * cr - credentials of caller.
* direntflags - directory lookup flags * direntflags - directory lookup flags
* realpnp - returned pathname. * realpnp - returned pathname.
* *
* OUT: ipp - inode of located entry, NULL if not found. * OUT: zpp - znode of located entry, NULL if not found.
* *
* RETURN: 0 on success, error code on failure. * RETURN: 0 on success, error code on failure.
* *
@ -1187,11 +1188,10 @@ zfs_access(struct inode *ip, int mode, int flag, cred_t *cr)
*/ */
/* ARGSUSED */ /* ARGSUSED */
int int
zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags, zfs_lookup(znode_t *zdp, char *nm, znode_t **zpp, int flags,
cred_t *cr, int *direntflags, pathname_t *realpnp) cred_t *cr, int *direntflags, pathname_t *realpnp)
{ {
znode_t *zdp = ITOZ(dip); zfsvfs_t *zfsvfs = ZTOZSB(zdp);
zfsvfs_t *zfsvfs = ITOZSB(dip);
int error = 0; int error = 0;
/* /*
@ -1205,7 +1205,7 @@ zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
*/ */
if (!(flags & (LOOKUP_XATTR | FIGNORECASE))) { if (!(flags & (LOOKUP_XATTR | FIGNORECASE))) {
if (!S_ISDIR(dip->i_mode)) { if (!S_ISDIR(ZTOI(zdp)->i_mode)) {
return (SET_ERROR(ENOTDIR)); return (SET_ERROR(ENOTDIR));
} else if (zdp->z_sa_hdl == NULL) { } else if (zdp->z_sa_hdl == NULL) {
return (SET_ERROR(EIO)); return (SET_ERROR(EIO));
@ -1214,8 +1214,8 @@ zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
if (nm[0] == 0 || (nm[0] == '.' && nm[1] == '\0')) { if (nm[0] == 0 || (nm[0] == '.' && nm[1] == '\0')) {
error = zfs_fastaccesschk_execute(zdp, cr); error = zfs_fastaccesschk_execute(zdp, cr);
if (!error) { if (!error) {
*ipp = dip; *zpp = zdp;
igrab(*ipp); zhold(*zpp);
return (0); return (0);
} }
return (error); return (error);
@ -1225,7 +1225,7 @@ zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
ZFS_ENTER(zfsvfs); ZFS_ENTER(zfsvfs);
ZFS_VERIFY_ZP(zdp); ZFS_VERIFY_ZP(zdp);
*ipp = NULL; *zpp = NULL;
if (flags & LOOKUP_XATTR) { if (flags & LOOKUP_XATTR) {
/* /*
@ -1237,7 +1237,7 @@ zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
if ((error = zfs_get_xattrdir(zdp, ipp, cr, flags))) { if ((error = zfs_get_xattrdir(zdp, zpp, cr, flags))) {
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
} }
@ -1246,17 +1246,17 @@ zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
* Do we have permission to get into attribute directory? * Do we have permission to get into attribute directory?
*/ */
if ((error = zfs_zaccess(ITOZ(*ipp), ACE_EXECUTE, 0, if ((error = zfs_zaccess(*zpp, ACE_EXECUTE, 0,
B_FALSE, cr))) { B_FALSE, cr))) {
iput(*ipp); zrele(*zpp);
*ipp = NULL; *zpp = NULL;
} }
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
} }
if (!S_ISDIR(dip->i_mode)) { if (!S_ISDIR(ZTOI(zdp)->i_mode)) {
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (SET_ERROR(ENOTDIR)); return (SET_ERROR(ENOTDIR));
} }
@ -1276,9 +1276,9 @@ zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
return (SET_ERROR(EILSEQ)); return (SET_ERROR(EILSEQ));
} }
error = zfs_dirlook(zdp, nm, ipp, flags, direntflags, realpnp); error = zfs_dirlook(zdp, nm, zpp, flags, direntflags, realpnp);
if ((error == 0) && (*ipp)) if ((error == 0) && (*zpp))
zfs_inode_update(ITOZ(*ipp)); zfs_inode_update(*zpp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
@ -1289,7 +1289,7 @@ zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
* already exists, truncate the file if permissible, else return * already exists, truncate the file if permissible, else return
* an error. Return the ip of the created or trunc'd file. * an error. Return the ip of the created or trunc'd file.
* *
* IN: dip - inode of directory to put new file entry in. * IN: dzp - znode of directory to put new file entry in.
* name - name of new file entry. * name - name of new file entry.
* vap - attributes of new file. * vap - attributes of new file.
* excl - flag indicating exclusive or non-exclusive mode. * excl - flag indicating exclusive or non-exclusive mode.
@ -1298,22 +1298,22 @@ zfs_lookup(struct inode *dip, char *nm, struct inode **ipp, int flags,
* flag - file flag. * flag - file flag.
* vsecp - ACL to be set * vsecp - ACL to be set
* *
* OUT: ipp - inode of created or trunc'd entry. * OUT: zpp - znode of created or trunc'd entry.
* *
* RETURN: 0 on success, error code on failure. * RETURN: 0 on success, error code on failure.
* *
* Timestamps: * Timestamps:
* dip - ctime|mtime updated if new entry created * dzp - ctime|mtime updated if new entry created
* ip - ctime|mtime always, atime if new * zp - ctime|mtime always, atime if new
*/ */
/* ARGSUSED */ /* ARGSUSED */
int int
zfs_create(struct inode *dip, char *name, vattr_t *vap, int excl, zfs_create(znode_t *dzp, char *name, vattr_t *vap, int excl,
int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp) int mode, znode_t **zpp, cred_t *cr, int flag, vsecattr_t *vsecp)
{ {
znode_t *zp, *dzp = ITOZ(dip); znode_t *zp;
zfsvfs_t *zfsvfs = ITOZSB(dip); zfsvfs_t *zfsvfs = ZTOZSB(dzp);
zilog_t *zilog; zilog_t *zilog;
objset_t *os; objset_t *os;
zfs_dirlock_t *dl; zfs_dirlock_t *dl;
@ -1361,12 +1361,12 @@ zfs_create(struct inode *dip, char *name, vattr_t *vap, int excl,
} }
top: top:
*ipp = NULL; *zpp = NULL;
if (*name == '\0') { if (*name == '\0') {
/* /*
* Null component name refers to the directory itself. * Null component name refers to the directory itself.
*/ */
igrab(dip); zhold(dzp);
zp = dzp; zp = dzp;
dl = NULL; dl = NULL;
error = 0; error = 0;
@ -1539,11 +1539,11 @@ out:
if (error) { if (error) {
if (zp) if (zp)
iput(ZTOI(zp)); zrele(zp);
} else { } else {
zfs_inode_update(dzp); zfs_inode_update(dzp);
zfs_inode_update(zp); zfs_inode_update(zp);
*ipp = ZTOI(zp); *zpp = zp;
} }
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
@ -1662,7 +1662,7 @@ out:
if (error) { if (error) {
if (zp) if (zp)
iput(ZTOI(zp)); zrele(zp);
} else { } else {
zfs_inode_update(dzp); zfs_inode_update(dzp);
zfs_inode_update(zp); zfs_inode_update(zp);
@ -1676,7 +1676,7 @@ out:
/* /*
* Remove an entry from a directory. * Remove an entry from a directory.
* *
* IN: dip - inode of directory to remove entry from. * IN: dzp - znode of directory to remove entry from.
* name - name of entry to remove. * name - name of entry to remove.
* cr - credentials of caller. * cr - credentials of caller.
* flags - case flags. * flags - case flags.
@ -1685,7 +1685,7 @@ out:
* error code if failure * error code if failure
* *
* Timestamps: * Timestamps:
* dip - ctime|mtime * dzp - ctime|mtime
* ip - ctime (if nlink > 0) * ip - ctime (if nlink > 0)
*/ */
@ -1693,12 +1693,11 @@ uint64_t null_xattr = 0;
/*ARGSUSED*/ /*ARGSUSED*/
int int
zfs_remove(struct inode *dip, char *name, cred_t *cr, int flags) zfs_remove(znode_t *dzp, char *name, cred_t *cr, int flags)
{ {
znode_t *zp, *dzp = ITOZ(dip); znode_t *zp;
znode_t *xzp; znode_t *xzp;
struct inode *ip; zfsvfs_t *zfsvfs = ZTOZSB(dzp);
zfsvfs_t *zfsvfs = ITOZSB(dip);
zilog_t *zilog; zilog_t *zilog;
uint64_t acl_obj, xattr_obj; uint64_t acl_obj, xattr_obj;
uint64_t xattr_obj_unlinked = 0; uint64_t xattr_obj_unlinked = 0;
@ -1742,8 +1741,6 @@ top:
return (error); return (error);
} }
ip = ZTOI(zp);
if ((error = zfs_zaccess_delete(dzp, zp, cr))) { if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
goto out; goto out;
} }
@ -1751,13 +1748,14 @@ top:
/* /*
* Need to use rmdir for removing directories. * Need to use rmdir for removing directories.
*/ */
if (S_ISDIR(ip->i_mode)) { if (S_ISDIR(ZTOI(zp)->i_mode)) {
error = SET_ERROR(EPERM); error = SET_ERROR(EPERM);
goto out; goto out;
} }
mutex_enter(&zp->z_lock); mutex_enter(&zp->z_lock);
may_delete_now = atomic_read(&ip->i_count) == 1 && !(zp->z_is_mapped); may_delete_now = atomic_read(&ZTOI(zp)->i_count) == 1 &&
!(zp->z_is_mapped);
mutex_exit(&zp->z_lock); mutex_exit(&zp->z_lock);
/* /*
@ -1809,17 +1807,17 @@ top:
waited = B_TRUE; waited = B_TRUE;
dmu_tx_wait(tx); dmu_tx_wait(tx);
dmu_tx_abort(tx); dmu_tx_abort(tx);
iput(ip); zrele(zp);
if (xzp) if (xzp)
iput(ZTOI(xzp)); zrele(xzp);
goto top; goto top;
} }
if (realnmp) if (realnmp)
pn_free(realnmp); pn_free(realnmp);
dmu_tx_abort(tx); dmu_tx_abort(tx);
iput(ip); zrele(zp);
if (xzp) if (xzp)
iput(ZTOI(xzp)); zrele(xzp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
} }
@ -1844,9 +1842,9 @@ top:
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs),
&xattr_obj_unlinked, sizeof (xattr_obj_unlinked)); &xattr_obj_unlinked, sizeof (xattr_obj_unlinked));
delete_now = may_delete_now && !toobig && delete_now = may_delete_now && !toobig &&
atomic_read(&ip->i_count) == 1 && !(zp->z_is_mapped) && atomic_read(&ZTOI(zp)->i_count) == 1 &&
xattr_obj == xattr_obj_unlinked && zfs_external_acl(zp) == !(zp->z_is_mapped) && xattr_obj == xattr_obj_unlinked &&
acl_obj; zfs_external_acl(zp) == acl_obj;
} }
if (delete_now) { if (delete_now) {
@ -1897,13 +1895,13 @@ out:
zfs_inode_update(zp); zfs_inode_update(zp);
if (delete_now) if (delete_now)
iput(ip); zrele(zp);
else else
zfs_iput_async(ip); zfs_zrele_async(zp);
if (xzp) { if (xzp) {
zfs_inode_update(xzp); zfs_inode_update(xzp);
zfs_iput_async(ZTOI(xzp)); zfs_zrele_async(xzp);
} }
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
@ -1914,32 +1912,32 @@ out:
} }
/* /*
* Create a new directory and insert it into dip using the name * Create a new directory and insert it into dzp using the name
* provided. Return a pointer to the inserted directory. * provided. Return a pointer to the inserted directory.
* *
* IN: dip - inode of directory to add subdir to. * IN: dzp - znode of directory to add subdir to.
* dirname - name of new directory. * dirname - name of new directory.
* vap - attributes of new directory. * vap - attributes of new directory.
* cr - credentials of caller. * cr - credentials of caller.
* flags - case flags. * flags - case flags.
* vsecp - ACL to be set * vsecp - ACL to be set
* *
* OUT: ipp - inode of created directory. * OUT: zpp - znode of created directory.
* *
* RETURN: 0 if success * RETURN: 0 if success
* error code if failure * error code if failure
* *
* Timestamps: * Timestamps:
* dip - ctime|mtime updated * dzp - ctime|mtime updated
* ipp - ctime|mtime|atime updated * zpp - ctime|mtime|atime updated
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
int int
zfs_mkdir(struct inode *dip, char *dirname, vattr_t *vap, struct inode **ipp, zfs_mkdir(znode_t *dzp, char *dirname, vattr_t *vap, znode_t **zpp,
cred_t *cr, int flags, vsecattr_t *vsecp) cred_t *cr, int flags, vsecattr_t *vsecp)
{ {
znode_t *zp, *dzp = ITOZ(dip); znode_t *zp;
zfsvfs_t *zfsvfs = ITOZSB(dip); zfsvfs_t *zfsvfs = ZTOZSB(dzp);
zilog_t *zilog; zilog_t *zilog;
zfs_dirlock_t *dl; zfs_dirlock_t *dl;
uint64_t txtype; uint64_t txtype;
@ -2005,7 +2003,7 @@ zfs_mkdir(struct inode *dip, char *dirname, vattr_t *vap, struct inode **ipp,
* to fail. * to fail.
*/ */
top: top:
*ipp = NULL; *zpp = NULL;
if ((error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf, if ((error = zfs_dirent_lock(&dl, dzp, dirname, &zp, zf,
NULL, NULL))) { NULL, NULL))) {
@ -2078,7 +2076,7 @@ top:
if (fuid_dirtied) if (fuid_dirtied)
zfs_fuid_sync(zfsvfs, tx); zfs_fuid_sync(zfsvfs, tx);
*ipp = ZTOI(zp); *zpp = zp;
txtype = zfs_log_create_txtype(Z_DIR, vsecp, vap); txtype = zfs_log_create_txtype(Z_DIR, vsecp, vap);
if (flags & FIGNORECASE) if (flags & FIGNORECASE)
@ -2097,7 +2095,7 @@ out:
zil_commit(zilog, 0); zil_commit(zilog, 0);
if (error != 0) { if (error != 0) {
iput(ZTOI(zp)); zrele(zp);
} else { } else {
zfs_inode_update(dzp); zfs_inode_update(dzp);
zfs_inode_update(zp); zfs_inode_update(zp);
@ -2111,7 +2109,7 @@ out:
* directory is the same as the subdir to be removed, the * directory is the same as the subdir to be removed, the
* remove will fail. * remove will fail.
* *
* IN: dip - inode of directory to remove from. * IN: dzp - znode of directory to remove from.
* name - name of directory to be removed. * name - name of directory to be removed.
* cwd - inode of current working directory. * cwd - inode of current working directory.
* cr - credentials of caller. * cr - credentials of caller.
@ -2120,17 +2118,15 @@ out:
* RETURN: 0 on success, error code on failure. * RETURN: 0 on success, error code on failure.
* *
* Timestamps: * Timestamps:
* dip - ctime|mtime updated * dzp - ctime|mtime updated
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
int int
zfs_rmdir(struct inode *dip, char *name, struct inode *cwd, cred_t *cr, zfs_rmdir(znode_t *dzp, char *name, znode_t *cwd, cred_t *cr,
int flags) int flags)
{ {
znode_t *dzp = ITOZ(dip);
znode_t *zp; znode_t *zp;
struct inode *ip; zfsvfs_t *zfsvfs = ZTOZSB(dzp);
zfsvfs_t *zfsvfs = ITOZSB(dip);
zilog_t *zilog; zilog_t *zilog;
zfs_dirlock_t *dl; zfs_dirlock_t *dl;
dmu_tx_t *tx; dmu_tx_t *tx;
@ -2159,18 +2155,16 @@ top:
return (error); return (error);
} }
ip = ZTOI(zp);
if ((error = zfs_zaccess_delete(dzp, zp, cr))) { if ((error = zfs_zaccess_delete(dzp, zp, cr))) {
goto out; goto out;
} }
if (!S_ISDIR(ip->i_mode)) { if (!S_ISDIR(ZTOI(zp)->i_mode)) {
error = SET_ERROR(ENOTDIR); error = SET_ERROR(ENOTDIR);
goto out; goto out;
} }
if (ip == cwd) { if (zp == cwd) {
error = SET_ERROR(EINVAL); error = SET_ERROR(EINVAL);
goto out; goto out;
} }
@ -2203,11 +2197,11 @@ top:
waited = B_TRUE; waited = B_TRUE;
dmu_tx_wait(tx); dmu_tx_wait(tx);
dmu_tx_abort(tx); dmu_tx_abort(tx);
iput(ip); zrele(zp);
goto top; goto top;
} }
dmu_tx_abort(tx); dmu_tx_abort(tx);
iput(ip); zrele(zp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
} }
@ -2231,7 +2225,7 @@ out:
zfs_inode_update(dzp); zfs_inode_update(dzp);
zfs_inode_update(zp); zfs_inode_update(zp);
iput(ip); zrele(zp);
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0); zil_commit(zilog, 0);
@ -2403,10 +2397,9 @@ out:
ulong_t zfs_fsync_sync_cnt = 4; ulong_t zfs_fsync_sync_cnt = 4;
int int
zfs_fsync(struct inode *ip, int syncflag, cred_t *cr) zfs_fsync(znode_t *zp, int syncflag, cred_t *cr)
{ {
znode_t *zp = ITOZ(ip); zfsvfs_t *zfsvfs = ZTOZSB(zp);
zfsvfs_t *zfsvfs = ITOZSB(ip);
(void) tsd_set(zfs_fsyncer_key, (void *)zfs_fsync_sync_cnt); (void) tsd_set(zfs_fsyncer_key, (void *)zfs_fsync_sync_cnt);
@ -2711,7 +2704,7 @@ zfs_setattr_dir(znode_t *dzp)
{ {
struct inode *dxip = ZTOI(dzp); struct inode *dxip = ZTOI(dzp);
struct inode *xip = NULL; struct inode *xip = NULL;
zfsvfs_t *zfsvfs = ITOZSB(dxip); zfsvfs_t *zfsvfs = ZTOZSB(dzp);
objset_t *os = zfsvfs->z_os; objset_t *os = zfsvfs->z_os;
zap_cursor_t zc; zap_cursor_t zc;
zap_attribute_t zap; zap_attribute_t zap;
@ -2796,9 +2789,9 @@ zfs_setattr_dir(znode_t *dzp)
break; break;
next: next:
if (xip) { if (zp) {
iput(xip); zrele(zp);
xip = NULL; zp = NULL;
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
} }
zap_cursor_advance(&zc); zap_cursor_advance(&zc);
@ -2806,8 +2799,8 @@ next:
if (tx) if (tx)
dmu_tx_abort(tx); dmu_tx_abort(tx);
if (xip) { if (zp) {
iput(xip); zrele(zp);
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
} }
zap_cursor_fini(&zc); zap_cursor_fini(&zc);
@ -2819,7 +2812,7 @@ next:
* Set the file attributes to the values contained in the * Set the file attributes to the values contained in the
* vattr structure. * vattr structure.
* *
* IN: ip - inode of file to be modified. * IN: zp - znode of file to be modified.
* vap - new attribute values. * vap - new attribute values.
* If ATTR_XVATTR set, then optional attrs are being set * If ATTR_XVATTR set, then optional attrs are being set
* flags - ATTR_UTIME set if non-default time values provided. * flags - ATTR_UTIME set if non-default time values provided.
@ -2834,10 +2827,10 @@ next:
*/ */
/* ARGSUSED */ /* ARGSUSED */
int int
zfs_setattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr) zfs_setattr(znode_t *zp, vattr_t *vap, int flags, cred_t *cr)
{ {
znode_t *zp = ITOZ(ip); struct inode *ip;
zfsvfs_t *zfsvfs = ITOZSB(ip); zfsvfs_t *zfsvfs = ZTOZSB(zp);
objset_t *os = zfsvfs->z_os; objset_t *os = zfsvfs->z_os;
zilog_t *zilog; zilog_t *zilog;
dmu_tx_t *tx; dmu_tx_t *tx;
@ -2869,6 +2862,7 @@ zfs_setattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr)
ZFS_ENTER(zfsvfs); ZFS_ENTER(zfsvfs);
ZFS_VERIFY_ZP(zp); ZFS_VERIFY_ZP(zp);
ip = ZTOI(zp);
/* /*
* If this is a xvattr_t, then get a pointer to the structure of * If this is a xvattr_t, then get a pointer to the structure of
@ -3215,7 +3209,7 @@ top:
zfs_id_overquota(zfsvfs, DMU_USERUSED_OBJECT, zfs_id_overquota(zfsvfs, DMU_USERUSED_OBJECT,
new_kuid)) { new_kuid)) {
if (attrzp) if (attrzp)
iput(ZTOI(attrzp)); zrele(attrzp);
err = SET_ERROR(EDQUOT); err = SET_ERROR(EDQUOT);
goto out2; goto out2;
} }
@ -3228,7 +3222,7 @@ top:
zfs_id_overquota(zfsvfs, DMU_GROUPUSED_OBJECT, zfs_id_overquota(zfsvfs, DMU_GROUPUSED_OBJECT,
new_kgid)) { new_kgid)) {
if (attrzp) if (attrzp)
iput(ZTOI(attrzp)); zrele(attrzp);
err = SET_ERROR(EDQUOT); err = SET_ERROR(EDQUOT);
goto out2; goto out2;
} }
@ -3237,7 +3231,7 @@ top:
if (projid != ZFS_INVALID_PROJID && if (projid != ZFS_INVALID_PROJID &&
zfs_id_overquota(zfsvfs, DMU_PROJECTUSED_OBJECT, projid)) { zfs_id_overquota(zfsvfs, DMU_PROJECTUSED_OBJECT, projid)) {
if (attrzp) if (attrzp)
iput(ZTOI(attrzp)); zrele(attrzp);
err = EDQUOT; err = EDQUOT;
goto out2; goto out2;
} }
@ -3514,7 +3508,7 @@ out:
if (err) { if (err) {
dmu_tx_abort(tx); dmu_tx_abort(tx);
if (attrzp) if (attrzp)
iput(ZTOI(attrzp)); zrele(attrzp);
if (err == ERESTART) if (err == ERESTART)
goto top; goto top;
} else { } else {
@ -3524,7 +3518,7 @@ out:
if (attrzp) { if (attrzp) {
if (err2 == 0 && handle_eadir) if (err2 == 0 && handle_eadir)
err2 = zfs_setattr_dir(attrzp); err2 = zfs_setattr_dir(attrzp);
iput(ZTOI(attrzp)); zrele(attrzp);
} }
zfs_inode_update(zp); zfs_inode_update(zp);
} }
@ -3557,7 +3551,7 @@ zfs_rename_unlock(zfs_zlock_t **zlpp)
while ((zl = *zlpp) != NULL) { while ((zl = *zlpp) != NULL) {
if (zl->zl_znode != NULL) if (zl->zl_znode != NULL)
zfs_iput_async(ZTOI(zl->zl_znode)); zfs_zrele_async(zl->zl_znode);
rw_exit(zl->zl_rwlock); rw_exit(zl->zl_rwlock);
*zlpp = zl->zl_next; *zlpp = zl->zl_next;
kmem_free(zl, sizeof (*zl)); kmem_free(zl, sizeof (*zl));
@ -3642,9 +3636,9 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp)
* Move an entry from the provided source directory to the target * Move an entry from the provided source directory to the target
* directory. Change the entry name as indicated. * directory. Change the entry name as indicated.
* *
* IN: sdip - Source directory containing the "old entry". * IN: sdzp - Source directory containing the "old entry".
* snm - Old entry name. * snm - Old entry name.
* tdip - Target directory to contain the "new entry". * tdzp - Target directory to contain the "new entry".
* tnm - New entry name. * tnm - New entry name.
* cr - credentials of caller. * cr - credentials of caller.
* flags - case flags * flags - case flags
@ -3652,16 +3646,15 @@ zfs_rename_lock(znode_t *szp, znode_t *tdzp, znode_t *sdzp, zfs_zlock_t **zlpp)
* RETURN: 0 on success, error code on failure. * RETURN: 0 on success, error code on failure.
* *
* Timestamps: * Timestamps:
* sdip,tdip - ctime|mtime updated * sdzp,tdzp - ctime|mtime updated
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
int int
zfs_rename(struct inode *sdip, char *snm, struct inode *tdip, char *tnm, zfs_rename(znode_t *sdzp, char *snm, znode_t *tdzp, char *tnm,
cred_t *cr, int flags) cred_t *cr, int flags)
{ {
znode_t *tdzp, *szp, *tzp; znode_t *szp, *tzp;
znode_t *sdzp = ITOZ(sdip); zfsvfs_t *zfsvfs = ZTOZSB(sdzp);
zfsvfs_t *zfsvfs = ITOZSB(sdip);
zilog_t *zilog; zilog_t *zilog;
zfs_dirlock_t *sdl, *tdl; zfs_dirlock_t *sdl, *tdl;
dmu_tx_t *tx; dmu_tx_t *tx;
@ -3678,14 +3671,14 @@ zfs_rename(struct inode *sdip, char *snm, struct inode *tdip, char *tnm,
ZFS_VERIFY_ZP(sdzp); ZFS_VERIFY_ZP(sdzp);
zilog = zfsvfs->z_log; zilog = zfsvfs->z_log;
tdzp = ITOZ(tdip);
ZFS_VERIFY_ZP(tdzp); ZFS_VERIFY_ZP(tdzp);
/* /*
* We check i_sb because snapshots and the ctldir must have different * We check i_sb because snapshots and the ctldir must have different
* super blocks. * super blocks.
*/ */
if (tdip->i_sb != sdip->i_sb || zfsctl_is_node(tdip)) { if (ZTOI(tdzp)->i_sb != ZTOI(sdzp)->i_sb ||
zfsctl_is_node(ZTOI(tdzp))) {
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (SET_ERROR(EXDEV)); return (SET_ERROR(EXDEV));
} }
@ -3804,7 +3797,7 @@ top:
if (!terr) { if (!terr) {
zfs_dirent_unlock(tdl); zfs_dirent_unlock(tdl);
if (tzp) if (tzp)
iput(ZTOI(tzp)); zrele(tzp);
} }
if (sdzp == tdzp) if (sdzp == tdzp)
@ -3817,7 +3810,7 @@ top:
} }
if (terr) { if (terr) {
zfs_dirent_unlock(sdl); zfs_dirent_unlock(sdl);
iput(ZTOI(szp)); zrele(szp);
if (sdzp == tdzp) if (sdzp == tdzp)
rw_exit(&sdzp->z_name_lock); rw_exit(&sdzp->z_name_lock);
@ -3919,15 +3912,15 @@ top:
waited = B_TRUE; waited = B_TRUE;
dmu_tx_wait(tx); dmu_tx_wait(tx);
dmu_tx_abort(tx); dmu_tx_abort(tx);
iput(ZTOI(szp)); zrele(szp);
if (tzp) if (tzp)
iput(ZTOI(tzp)); zrele(tzp);
goto top; goto top;
} }
dmu_tx_abort(tx); dmu_tx_abort(tx);
iput(ZTOI(szp)); zrele(szp);
if (tzp) if (tzp)
iput(ZTOI(tzp)); zrele(tzp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
} }
@ -3993,10 +3986,10 @@ out:
zfs_inode_update(tdzp); zfs_inode_update(tdzp);
zfs_inode_update(szp); zfs_inode_update(szp);
iput(ZTOI(szp)); zrele(szp);
if (tzp) { if (tzp) {
zfs_inode_update(tzp); zfs_inode_update(tzp);
iput(ZTOI(tzp)); zrele(tzp);
} }
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
@ -4009,14 +4002,14 @@ out:
/* /*
* Insert the indicated symbolic reference entry into the directory. * Insert the indicated symbolic reference entry into the directory.
* *
* IN: dip - Directory to contain new symbolic link. * IN: dzp - Directory to contain new symbolic link.
* name - Name of directory entry in dip. * name - Name of directory entry in dip.
* vap - Attributes of new entry. * vap - Attributes of new entry.
* link - Name for new symlink entry. * link - Name for new symlink entry.
* cr - credentials of caller. * cr - credentials of caller.
* flags - case flags * flags - case flags
* *
* OUT: ipp - Inode for new symbolic link. * OUT: zpp - Znode for new symbolic link.
* *
* RETURN: 0 on success, error code on failure. * RETURN: 0 on success, error code on failure.
* *
@ -4025,13 +4018,13 @@ out:
*/ */
/*ARGSUSED*/ /*ARGSUSED*/
int int
zfs_symlink(struct inode *dip, char *name, vattr_t *vap, char *link, zfs_symlink(znode_t *dzp, char *name, vattr_t *vap, char *link,
struct inode **ipp, cred_t *cr, int flags) znode_t **zpp, cred_t *cr, int flags)
{ {
znode_t *zp, *dzp = ITOZ(dip); znode_t *zp;
zfs_dirlock_t *dl; zfs_dirlock_t *dl;
dmu_tx_t *tx; dmu_tx_t *tx;
zfsvfs_t *zfsvfs = ITOZSB(dip); zfsvfs_t *zfsvfs = ZTOZSB(dzp);
zilog_t *zilog; zilog_t *zilog;
uint64_t len = strlen(link); uint64_t len = strlen(link);
int error; int error;
@ -4069,7 +4062,7 @@ zfs_symlink(struct inode *dip, char *name, vattr_t *vap, char *link,
return (error); return (error);
} }
top: top:
*ipp = NULL; *zpp = NULL;
/* /*
* Attempt to lock directory; fail if entry already exists. * Attempt to lock directory; fail if entry already exists.
@ -4165,12 +4158,12 @@ top:
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
if (error == 0) { if (error == 0) {
*ipp = ZTOI(zp); *zpp = zp;
if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS) if (zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
zil_commit(zilog, 0); zil_commit(zilog, 0);
} else { } else {
iput(ZTOI(zp)); zrele(zp);
} }
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
@ -4215,10 +4208,10 @@ zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr)
} }
/* /*
* Insert a new entry into directory tdip referencing sip. * Insert a new entry into directory tdzp referencing szp.
* *
* IN: tdip - Directory to contain new entry. * IN: tdzp - Directory to contain new entry.
* sip - inode of new entry. * szp - znode of new entry.
* name - name of new entry. * name - name of new entry.
* cr - credentials of caller. * cr - credentials of caller.
* flags - case flags. * flags - case flags.
@ -4227,17 +4220,17 @@ zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr)
* error code if failure * error code if failure
* *
* Timestamps: * Timestamps:
* tdip - ctime|mtime updated * tdzp - ctime|mtime updated
* sip - ctime updated * szp - ctime updated
*/ */
/* ARGSUSED */ /* ARGSUSED */
int int
zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr, zfs_link(znode_t *tdzp, znode_t *szp, char *name, cred_t *cr,
int flags) int flags)
{ {
znode_t *dzp = ITOZ(tdip); struct inode *sip = ZTOI(szp);
znode_t *tzp, *szp; znode_t *tzp;
zfsvfs_t *zfsvfs = ITOZSB(tdip); zfsvfs_t *zfsvfs = ZTOZSB(tdzp);
zilog_t *zilog; zilog_t *zilog;
zfs_dirlock_t *dl; zfs_dirlock_t *dl;
dmu_tx_t *tx; dmu_tx_t *tx;
@ -4251,13 +4244,13 @@ zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr,
#ifdef HAVE_TMPFILE #ifdef HAVE_TMPFILE
is_tmpfile = (sip->i_nlink == 0 && (sip->i_state & I_LINKABLE)); is_tmpfile = (sip->i_nlink == 0 && (sip->i_state & I_LINKABLE));
#endif #endif
ASSERT(S_ISDIR(tdip->i_mode)); ASSERT(S_ISDIR(ZTOI(tdzp)->i_mode));
if (name == NULL) if (name == NULL)
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
ZFS_ENTER(zfsvfs); ZFS_ENTER(zfsvfs);
ZFS_VERIFY_ZP(dzp); ZFS_VERIFY_ZP(tdzp);
zilog = zfsvfs->z_log; zilog = zfsvfs->z_log;
/* /*
@ -4269,7 +4262,6 @@ zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr,
return (SET_ERROR(EPERM)); return (SET_ERROR(EPERM));
} }
szp = ITOZ(sip);
ZFS_VERIFY_ZP(szp); ZFS_VERIFY_ZP(szp);
/* /*
@ -4279,7 +4271,8 @@ zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr,
* such case, we only allow hard link creation in our tree when the * such case, we only allow hard link creation in our tree when the
* project IDs are the same. * project IDs are the same.
*/ */
if (dzp->z_pflags & ZFS_PROJINHERIT && dzp->z_projid != szp->z_projid) { if (tdzp->z_pflags & ZFS_PROJINHERIT &&
tdzp->z_projid != szp->z_projid) {
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (SET_ERROR(EXDEV)); return (SET_ERROR(EXDEV));
} }
@ -4288,7 +4281,7 @@ zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr,
* We check i_sb because snapshots and the ctldir must have different * We check i_sb because snapshots and the ctldir must have different
* super blocks. * super blocks.
*/ */
if (sip->i_sb != tdip->i_sb || zfsctl_is_node(sip)) { if (sip->i_sb != ZTOI(tdzp)->i_sb || zfsctl_is_node(sip)) {
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (SET_ERROR(EXDEV)); return (SET_ERROR(EXDEV));
} }
@ -4319,7 +4312,7 @@ zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr,
* into "normal" file space in order to circumvent restrictions * into "normal" file space in order to circumvent restrictions
* imposed in attribute space. * imposed in attribute space.
*/ */
if ((szp->z_pflags & ZFS_XATTR) != (dzp->z_pflags & ZFS_XATTR)) { if ((szp->z_pflags & ZFS_XATTR) != (tdzp->z_pflags & ZFS_XATTR)) {
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (SET_ERROR(EINVAL)); return (SET_ERROR(EINVAL));
} }
@ -4331,7 +4324,7 @@ zfs_link(struct inode *tdip, struct inode *sip, char *name, cred_t *cr,
return (SET_ERROR(EPERM)); return (SET_ERROR(EPERM));
} }
if ((error = zfs_zaccess(dzp, ACE_ADD_FILE, 0, B_FALSE, cr))) { if ((error = zfs_zaccess(tdzp, ACE_ADD_FILE, 0, B_FALSE, cr))) {
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
} }
@ -4340,7 +4333,7 @@ top:
/* /*
* Attempt to lock directory; fail if entry already exists. * Attempt to lock directory; fail if entry already exists.
*/ */
error = zfs_dirent_lock(&dl, dzp, name, &tzp, zf, NULL, NULL); error = zfs_dirent_lock(&dl, tdzp, name, &tzp, zf, NULL, NULL);
if (error) { if (error) {
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
@ -4348,12 +4341,12 @@ top:
tx = dmu_tx_create(zfsvfs->z_os); tx = dmu_tx_create(zfsvfs->z_os);
dmu_tx_hold_sa(tx, szp->z_sa_hdl, B_FALSE); dmu_tx_hold_sa(tx, szp->z_sa_hdl, B_FALSE);
dmu_tx_hold_zap(tx, dzp->z_id, TRUE, name); dmu_tx_hold_zap(tx, tdzp->z_id, TRUE, name);
if (is_tmpfile) if (is_tmpfile)
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL); dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL);
zfs_sa_upgrade_txholds(tx, szp); zfs_sa_upgrade_txholds(tx, szp);
zfs_sa_upgrade_txholds(tx, dzp); zfs_sa_upgrade_txholds(tx, tdzp);
error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT); error = dmu_tx_assign(tx, (waited ? TXG_NOTHROTTLE : 0) | TXG_NOWAIT);
if (error) { if (error) {
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
@ -4387,7 +4380,7 @@ top:
} else { } else {
if (flags & FIGNORECASE) if (flags & FIGNORECASE)
txtype |= TX_CI; txtype |= TX_CI;
zfs_log_link(zilog, tx, txtype, dzp, szp, name); zfs_log_link(zilog, tx, txtype, tdzp, szp, name);
} }
} else if (is_tmpfile) { } else if (is_tmpfile) {
/* restore z_unlinked since when linking failed */ /* restore z_unlinked since when linking failed */
@ -4404,7 +4397,7 @@ top:
if (is_tmpfile) if (is_tmpfile)
txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), txg); txg_wait_synced(dmu_objset_pool(zfsvfs->z_os), txg);
zfs_inode_update(dzp); zfs_inode_update(tdzp);
zfs_inode_update(szp); zfs_inode_update(szp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
@ -4925,7 +4918,7 @@ convoff(struct inode *ip, flock64_t *lckdat, int whence, offset_t offset)
* misnamed, as its functionality includes the ability to allocate as * misnamed, as its functionality includes the ability to allocate as
* well as free space. * well as free space.
* *
* IN: ip - inode of file to free data in. * IN: zp - znode of file to free data in.
* cmd - action to take (only F_FREESP supported). * cmd - action to take (only F_FREESP supported).
* bfp - section of file to free/alloc. * bfp - section of file to free/alloc.
* flag - current file open mode flags. * flag - current file open mode flags.
@ -4935,15 +4928,14 @@ convoff(struct inode *ip, flock64_t *lckdat, int whence, offset_t offset)
* RETURN: 0 on success, error code on failure. * RETURN: 0 on success, error code on failure.
* *
* Timestamps: * Timestamps:
* ip - ctime|mtime updated * zp - ctime|mtime updated
*/ */
/* ARGSUSED */ /* ARGSUSED */
int int
zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag, zfs_space(znode_t *zp, int cmd, flock64_t *bfp, int flag,
offset_t offset, cred_t *cr) offset_t offset, cred_t *cr)
{ {
znode_t *zp = ITOZ(ip); zfsvfs_t *zfsvfs = ZTOZSB(zp);
zfsvfs_t *zfsvfs = ITOZSB(ip);
uint64_t off, len; uint64_t off, len;
int error; int error;
@ -4964,7 +4956,7 @@ zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag,
return (SET_ERROR(EROFS)); return (SET_ERROR(EROFS));
} }
if ((error = convoff(ip, bfp, SEEK_SET, offset))) { if ((error = convoff(ZTOI(zp), bfp, SEEK_SET, offset))) {
ZFS_EXIT(zfsvfs); ZFS_EXIT(zfsvfs);
return (error); return (error);
} }
@ -5055,10 +5047,9 @@ zfs_getsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, cred_t *cr)
/*ARGSUSED*/ /*ARGSUSED*/
int int
zfs_setsecattr(struct inode *ip, vsecattr_t *vsecp, int flag, cred_t *cr) zfs_setsecattr(znode_t *zp, vsecattr_t *vsecp, int flag, cred_t *cr)
{ {
znode_t *zp = ITOZ(ip); zfsvfs_t *zfsvfs = ZTOZSB(zp);
zfsvfs_t *zfsvfs = ITOZSB(ip);
int error; int error;
boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE; boolean_t skipaclchk = (flag & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
zilog_t *zilog = zfsvfs->z_log; zilog_t *zilog = zfsvfs->z_log;

View File

@ -27,9 +27,9 @@
* Brian Behlendorf <behlendorf1@llnl.gov> * Brian Behlendorf <behlendorf1@llnl.gov>
*/ */
#include <sys/zfs_znode.h>
#include <sys/zfs_vfsops.h> #include <sys/zfs_vfsops.h>
#include <sys/zfs_vnops.h> #include <sys/zfs_vnops.h>
#include <sys/zfs_znode.h>
#include <sys/zfs_ctldir.h> #include <sys/zfs_ctldir.h>
#include <sys/zpl.h> #include <sys/zpl.h>

View File

@ -24,8 +24,8 @@
*/ */
#include <sys/zfs_vnops.h>
#include <sys/zfs_znode.h> #include <sys/zfs_znode.h>
#include <sys/zfs_vnops.h>
#include <sys/zfs_ctldir.h> #include <sys/zfs_ctldir.h>
#include <sys/zpl.h> #include <sys/zpl.h>
@ -110,12 +110,12 @@ zpl_get_parent(struct dentry *child)
{ {
cred_t *cr = CRED(); cred_t *cr = CRED();
fstrans_cookie_t cookie; fstrans_cookie_t cookie;
struct inode *ip; znode_t *zp;
int error; int error;
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_lookup(child->d_inode, "..", &ip, 0, cr, NULL, NULL); error = -zfs_lookup(ITOZ(child->d_inode), "..", &zp, 0, cr, NULL, NULL);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);
ASSERT3S(error, <=, 0); ASSERT3S(error, <=, 0);
@ -123,7 +123,7 @@ zpl_get_parent(struct dentry *child)
if (error) if (error)
return (ERR_PTR(error)); return (ERR_PTR(error));
return (d_obtain_alias(ip)); return (d_obtain_alias(ZTOI(zp)));
} }
static int static int
@ -138,7 +138,7 @@ zpl_commit_metadata(struct inode *inode)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_fsync(inode, 0, cr); error = -zfs_fsync(ITOZ(inode), 0, cr);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);
ASSERT3S(error, <=, 0); ASSERT3S(error, <=, 0);

View File

@ -29,9 +29,9 @@
#endif #endif
#include <sys/file.h> #include <sys/file.h>
#include <sys/dmu_objset.h> #include <sys/dmu_objset.h>
#include <sys/zfs_znode.h>
#include <sys/zfs_vfsops.h> #include <sys/zfs_vfsops.h>
#include <sys/zfs_vnops.h> #include <sys/zfs_vnops.h>
#include <sys/zfs_znode.h>
#include <sys/zfs_project.h> #include <sys/zfs_project.h>
@ -125,7 +125,7 @@ zpl_fsync(struct file *filp, int datasync)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_fsync(inode, datasync, cr); error = -zfs_fsync(ITOZ(inode), datasync, cr);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);
ASSERT3S(error, <=, 0); ASSERT3S(error, <=, 0);
@ -163,7 +163,7 @@ zpl_fsync(struct file *filp, loff_t start, loff_t end, int datasync)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_fsync(inode, datasync, cr); error = -zfs_fsync(ITOZ(inode), datasync, cr);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);
ASSERT3S(error, <=, 0); ASSERT3S(error, <=, 0);
@ -757,7 +757,7 @@ zpl_fallocate_common(struct inode *ip, int mode, loff_t offset, loff_t len)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_space(ip, F_FREESP, &bf, O_RDWR, offset, cr); error = -zfs_space(ITOZ(ip), F_FREESP, &bf, O_RDWR, offset, cr);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
spl_inode_unlock(ip); spl_inode_unlock(ip);
@ -886,7 +886,7 @@ zpl_ioctl_setflags(struct file *filp, void __user *arg)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
err = -zfs_setattr(ip, (vattr_t *)&xva, 0, cr); err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);
@ -934,7 +934,7 @@ zpl_ioctl_setxattr(struct file *filp, void __user *arg)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
err = -zfs_setattr(ip, (vattr_t *)&xva, 0, cr); err = -zfs_setattr(ITOZ(ip), (vattr_t *)&xva, 0, cr);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);

View File

@ -39,6 +39,7 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
{ {
cred_t *cr = CRED(); cred_t *cr = CRED();
struct inode *ip; struct inode *ip;
znode_t *zp;
int error; int error;
fstrans_cookie_t cookie; fstrans_cookie_t cookie;
pathname_t *ppn = NULL; pathname_t *ppn = NULL;
@ -59,7 +60,8 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
ppn = &pn; ppn = &pn;
} }
error = -zfs_lookup(dir, dname(dentry), &ip, zfs_flags, cr, NULL, ppn); error = -zfs_lookup(ITOZ(dir), dname(dentry), &zp,
zfs_flags, cr, NULL, ppn);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
ASSERT3S(error, <=, 0); ASSERT3S(error, <=, 0);
crfree(cr); crfree(cr);
@ -85,6 +87,7 @@ zpl_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
else else
return (ERR_PTR(error)); return (ERR_PTR(error));
} }
ip = ZTOI(zp);
/* /*
* If we are case insensitive, call the correct function * If we are case insensitive, call the correct function
@ -128,7 +131,7 @@ static int
zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag) zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
{ {
cred_t *cr = CRED(); cred_t *cr = CRED();
struct inode *ip; znode_t *zp;
vattr_t *vap; vattr_t *vap;
int error; int error;
fstrans_cookie_t cookie; fstrans_cookie_t cookie;
@ -138,16 +141,17 @@ zpl_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool flag)
zpl_vap_init(vap, dir, mode, cr); zpl_vap_init(vap, dir, mode, cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL); error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0,
mode, &zp, cr, 0, NULL);
if (error == 0) { if (error == 0) {
d_instantiate(dentry, ip); d_instantiate(dentry, ZTOI(zp));
error = zpl_xattr_security_init(ip, dir, &dentry->d_name); error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
if (error == 0) if (error == 0)
error = zpl_init_acl(ip, dir); error = zpl_init_acl(ZTOI(zp), dir);
if (error) if (error)
(void) zfs_remove(dir, dname(dentry), cr, 0); (void) zfs_remove(ITOZ(dir), dname(dentry), cr, 0);
} }
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
@ -163,7 +167,7 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
dev_t rdev) dev_t rdev)
{ {
cred_t *cr = CRED(); cred_t *cr = CRED();
struct inode *ip; znode_t *zp;
vattr_t *vap; vattr_t *vap;
int error; int error;
fstrans_cookie_t cookie; fstrans_cookie_t cookie;
@ -181,16 +185,17 @@ zpl_mknod(struct inode *dir, struct dentry *dentry, umode_t mode,
vap->va_rdev = rdev; vap->va_rdev = rdev;
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_create(dir, dname(dentry), vap, 0, mode, &ip, cr, 0, NULL); error = -zfs_create(ITOZ(dir), dname(dentry), vap, 0,
mode, &zp, cr, 0, NULL);
if (error == 0) { if (error == 0) {
d_instantiate(dentry, ip); d_instantiate(dentry, ZTOI(zp));
error = zpl_xattr_security_init(ip, dir, &dentry->d_name); error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
if (error == 0) if (error == 0)
error = zpl_init_acl(ip, dir); error = zpl_init_acl(ZTOI(zp), dir);
if (error) if (error)
(void) zfs_remove(dir, dname(dentry), cr, 0); (void) zfs_remove(ITOZ(dir), dname(dentry), cr, 0);
} }
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
@ -250,7 +255,7 @@ zpl_unlink(struct inode *dir, struct dentry *dentry)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_remove(dir, dname(dentry), cr, 0); error = -zfs_remove(ITOZ(dir), dname(dentry), cr, 0);
/* /*
* For a CI FS we must invalidate the dentry to prevent the * For a CI FS we must invalidate the dentry to prevent the
@ -271,7 +276,7 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{ {
cred_t *cr = CRED(); cred_t *cr = CRED();
vattr_t *vap; vattr_t *vap;
struct inode *ip; znode_t *zp;
int error; int error;
fstrans_cookie_t cookie; fstrans_cookie_t cookie;
@ -280,16 +285,16 @@ zpl_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
zpl_vap_init(vap, dir, mode | S_IFDIR, cr); zpl_vap_init(vap, dir, mode | S_IFDIR, cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_mkdir(dir, dname(dentry), vap, &ip, cr, 0, NULL); error = -zfs_mkdir(ITOZ(dir), dname(dentry), vap, &zp, cr, 0, NULL);
if (error == 0) { if (error == 0) {
d_instantiate(dentry, ip); d_instantiate(dentry, ZTOI(zp));
error = zpl_xattr_security_init(ip, dir, &dentry->d_name); error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
if (error == 0) if (error == 0)
error = zpl_init_acl(ip, dir); error = zpl_init_acl(ZTOI(zp), dir);
if (error) if (error)
(void) zfs_rmdir(dir, dname(dentry), NULL, cr, 0); (void) zfs_rmdir(ITOZ(dir), dname(dentry), NULL, cr, 0);
} }
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
@ -310,7 +315,7 @@ zpl_rmdir(struct inode *dir, struct dentry *dentry)
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_rmdir(dir, dname(dentry), NULL, cr, 0); error = -zfs_rmdir(ITOZ(dir), dname(dentry), NULL, cr, 0);
/* /*
* For a CI FS we must invalidate the dentry to prevent the * For a CI FS we must invalidate the dentry to prevent the
@ -377,7 +382,7 @@ zpl_setattr(struct dentry *dentry, struct iattr *ia)
} }
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_setattr(ip, vap, 0, cr); error = -zfs_setattr(ITOZ(ip), vap, 0, cr);
if (!error && (ia->ia_valid & ATTR_MODE)) if (!error && (ia->ia_valid & ATTR_MODE))
error = zpl_chmod_acl(ip); error = zpl_chmod_acl(ip);
@ -403,7 +408,8 @@ zpl_rename2(struct inode *sdip, struct dentry *sdentry,
crhold(cr); crhold(cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_rename(sdip, dname(sdentry), tdip, dname(tdentry), cr, 0); error = -zfs_rename(ITOZ(sdip), dname(sdentry), ITOZ(tdip),
dname(tdentry), cr, 0);
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
crfree(cr); crfree(cr);
ASSERT3S(error, <=, 0); ASSERT3S(error, <=, 0);
@ -425,7 +431,7 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
{ {
cred_t *cr = CRED(); cred_t *cr = CRED();
vattr_t *vap; vattr_t *vap;
struct inode *ip; znode_t *zp;
int error; int error;
fstrans_cookie_t cookie; fstrans_cookie_t cookie;
@ -434,13 +440,14 @@ zpl_symlink(struct inode *dir, struct dentry *dentry, const char *name)
zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr); zpl_vap_init(vap, dir, S_IFLNK | S_IRWXUGO, cr);
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_symlink(dir, dname(dentry), vap, (char *)name, &ip, cr, 0); error = -zfs_symlink(ITOZ(dir), dname(dentry), vap,
(char *)name, &zp, cr, 0);
if (error == 0) { if (error == 0) {
d_instantiate(dentry, ip); d_instantiate(dentry, ZTOI(zp));
error = zpl_xattr_security_init(ip, dir, &dentry->d_name); error = zpl_xattr_security_init(ZTOI(zp), dir, &dentry->d_name);
if (error) if (error)
(void) zfs_remove(dir, dname(dentry), cr, 0); (void) zfs_remove(ITOZ(dir), dname(dentry), cr, 0);
} }
spl_fstrans_unmark(cookie); spl_fstrans_unmark(cookie);
@ -587,7 +594,7 @@ zpl_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
igrab(ip); /* Use ihold() if available */ igrab(ip); /* Use ihold() if available */
cookie = spl_fstrans_mark(); cookie = spl_fstrans_mark();
error = -zfs_link(dir, ip, dname(dentry), cr, 0); error = -zfs_link(ITOZ(dir), ITOZ(ip), dname(dentry), cr, 0);
if (error) { if (error) {
iput(ip); iput(ip);
goto out; goto out;

View File

@ -23,9 +23,9 @@
*/ */
#include <sys/zfs_znode.h>
#include <sys/zfs_vfsops.h> #include <sys/zfs_vfsops.h>
#include <sys/zfs_vnops.h> #include <sys/zfs_vnops.h>
#include <sys/zfs_znode.h>
#include <sys/zfs_ctldir.h> #include <sys/zfs_ctldir.h>
#include <sys/zpl.h> #include <sys/zpl.h>

View File

@ -77,9 +77,9 @@
* largely avoids the issue except in the overflow case. * largely avoids the issue except in the overflow case.
*/ */
#include <sys/zfs_znode.h>
#include <sys/zfs_vfsops.h> #include <sys/zfs_vfsops.h>
#include <sys/zfs_vnops.h> #include <sys/zfs_vnops.h>
#include <sys/zfs_znode.h>
#include <sys/zap.h> #include <sys/zap.h>
#include <sys/vfs.h> #include <sys/vfs.h>
#include <sys/zpl.h> #include <sys/zpl.h>
@ -184,10 +184,12 @@ zpl_xattr_list_dir(xattr_filldir_t *xf, cred_t *cr)
{ {
struct inode *ip = xf->dentry->d_inode; struct inode *ip = xf->dentry->d_inode;
struct inode *dxip = NULL; struct inode *dxip = NULL;
znode_t *dxzp;
int error; int error;
/* Lookup the xattr directory */ /* Lookup the xattr directory */
error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR, cr, NULL, NULL); error = -zfs_lookup(ITOZ(ip), NULL, &dxzp, LOOKUP_XATTR,
cr, NULL, NULL);
if (error) { if (error) {
if (error == -ENOENT) if (error == -ENOENT)
error = 0; error = 0;
@ -195,6 +197,7 @@ zpl_xattr_list_dir(xattr_filldir_t *xf, cred_t *cr)
return (error); return (error);
} }
dxip = ZTOI(dxzp);
error = zpl_xattr_readdir(dxip, xf); error = zpl_xattr_readdir(dxip, xf);
iput(dxip); iput(dxip);
@ -271,21 +274,24 @@ static int
zpl_xattr_get_dir(struct inode *ip, const char *name, void *value, zpl_xattr_get_dir(struct inode *ip, const char *name, void *value,
size_t size, cred_t *cr) size_t size, cred_t *cr)
{ {
struct inode *dxip = NULL;
struct inode *xip = NULL; struct inode *xip = NULL;
znode_t *dxzp = NULL;
znode_t *xzp = NULL;
loff_t pos = 0; loff_t pos = 0;
int error; int error;
/* Lookup the xattr directory */ /* Lookup the xattr directory */
error = -zfs_lookup(ip, NULL, &dxip, LOOKUP_XATTR, cr, NULL, NULL); error = -zfs_lookup(ITOZ(ip), NULL, &dxzp, LOOKUP_XATTR,
cr, NULL, NULL);
if (error) if (error)
goto out; goto out;
/* Lookup a specific xattr name in the directory */ /* Lookup a specific xattr name in the directory */
error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL); error = -zfs_lookup(dxzp, (char *)name, &xzp, 0, cr, NULL, NULL);
if (error) if (error)
goto out; goto out;
xip = ZTOI(xzp);
if (!size) { if (!size) {
error = i_size_read(xip); error = i_size_read(xip);
goto out; goto out;
@ -298,11 +304,11 @@ zpl_xattr_get_dir(struct inode *ip, const char *name, void *value,
error = zpl_read_common(xip, value, size, &pos, UIO_SYSSPACE, 0, cr); error = zpl_read_common(xip, value, size, &pos, UIO_SYSSPACE, 0, cr);
out: out:
if (xip) if (xzp)
iput(xip); zrele(xzp);
if (dxip) if (dxzp)
iput(dxip); zrele(dxzp);
return (error); return (error);
} }
@ -432,8 +438,8 @@ static int
zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value, zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
size_t size, int flags, cred_t *cr) size_t size, int flags, cred_t *cr)
{ {
struct inode *dxip = NULL; znode_t *dxzp = NULL;
struct inode *xip = NULL; znode_t *xzp = NULL;
vattr_t *vap = NULL; vattr_t *vap = NULL;
ssize_t wrote; ssize_t wrote;
int lookup_flags, error; int lookup_flags, error;
@ -450,12 +456,13 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
if (value != NULL) if (value != NULL)
lookup_flags |= CREATE_XATTR_DIR; lookup_flags |= CREATE_XATTR_DIR;
error = -zfs_lookup(ip, NULL, &dxip, lookup_flags, cr, NULL, NULL); error = -zfs_lookup(ITOZ(ip), NULL, &dxzp, lookup_flags,
cr, NULL, NULL);
if (error) if (error)
goto out; goto out;
/* Lookup a specific xattr name in the directory */ /* Lookup a specific xattr name in the directory */
error = -zfs_lookup(dxip, (char *)name, &xip, 0, cr, NULL, NULL); error = -zfs_lookup(dxzp, (char *)name, &xzp, 0, cr, NULL, NULL);
if (error && (error != -ENOENT)) if (error && (error != -ENOENT))
goto out; goto out;
@ -463,33 +470,34 @@ zpl_xattr_set_dir(struct inode *ip, const char *name, const void *value,
/* Remove a specific name xattr when value is set to NULL. */ /* Remove a specific name xattr when value is set to NULL. */
if (value == NULL) { if (value == NULL) {
if (xip) if (xzp)
error = -zfs_remove(dxip, (char *)name, cr, 0); error = -zfs_remove(dxzp, (char *)name, cr, 0);
goto out; goto out;
} }
/* Lookup failed create a new xattr. */ /* Lookup failed create a new xattr. */
if (xip == NULL) { if (xzp == NULL) {
vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP); vap = kmem_zalloc(sizeof (vattr_t), KM_SLEEP);
vap->va_mode = xattr_mode; vap->va_mode = xattr_mode;
vap->va_mask = ATTR_MODE; vap->va_mask = ATTR_MODE;
vap->va_uid = crgetfsuid(cr); vap->va_uid = crgetfsuid(cr);
vap->va_gid = crgetfsgid(cr); vap->va_gid = crgetfsgid(cr);
error = -zfs_create(dxip, (char *)name, vap, 0, 0644, &xip, error = -zfs_create(dxzp, (char *)name, vap, 0, 0644, &xzp,
cr, 0, NULL); cr, 0, NULL);
if (error) if (error)
goto out; goto out;
} }
ASSERT(xip != NULL); ASSERT(xzp != NULL);
error = -zfs_freesp(ITOZ(xip), 0, 0, xattr_mode, TRUE); error = -zfs_freesp(xzp, 0, 0, xattr_mode, TRUE);
if (error) if (error)
goto out; goto out;
wrote = zpl_write_common(xip, value, size, &pos, UIO_SYSSPACE, 0, cr); wrote = zpl_write_common(ZTOI(xzp), value, size, &pos,
UIO_SYSSPACE, 0, cr);
if (wrote < 0) if (wrote < 0)
error = wrote; error = wrote;
@ -503,11 +511,11 @@ out:
if (vap) if (vap)
kmem_free(vap, sizeof (vattr_t)); kmem_free(vap, sizeof (vattr_t));
if (xip) if (xzp)
iput(xip); zrele(xzp);
if (dxip) if (dxzp)
iput(dxip); zrele(dxzp);
if (error == -ENOENT) if (error == -ENOENT)
error = -ENODATA; error = -ENODATA;

View File

@ -220,7 +220,7 @@ dsl_pool_open_impl(spa_t *spa, uint64_t txg)
mutex_init(&dp->dp_lock, NULL, MUTEX_DEFAULT, NULL); mutex_init(&dp->dp_lock, NULL, MUTEX_DEFAULT, NULL);
cv_init(&dp->dp_spaceavail_cv, NULL, CV_DEFAULT, NULL); cv_init(&dp->dp_spaceavail_cv, NULL, CV_DEFAULT, NULL);
dp->dp_iput_taskq = taskq_create("z_iput", max_ncpus, defclsyspri, dp->dp_zrele_taskq = taskq_create("z_zrele", max_ncpus, defclsyspri,
max_ncpus * 8, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC); max_ncpus * 8, INT_MAX, TASKQ_PREPOPULATE | TASKQ_DYNAMIC);
dp->dp_unlinked_drain_taskq = taskq_create("z_unlinked_drain", dp->dp_unlinked_drain_taskq = taskq_create("z_unlinked_drain",
max_ncpus, defclsyspri, max_ncpus, INT_MAX, max_ncpus, defclsyspri, max_ncpus, INT_MAX,
@ -416,7 +416,7 @@ dsl_pool_close(dsl_pool_t *dp)
mutex_destroy(&dp->dp_lock); mutex_destroy(&dp->dp_lock);
cv_destroy(&dp->dp_spaceavail_cv); cv_destroy(&dp->dp_spaceavail_cv);
taskq_destroy(dp->dp_unlinked_drain_taskq); taskq_destroy(dp->dp_unlinked_drain_taskq);
taskq_destroy(dp->dp_iput_taskq); taskq_destroy(dp->dp_zrele_taskq);
if (dp->dp_blkstats != NULL) { if (dp->dp_blkstats != NULL) {
mutex_destroy(&dp->dp_blkstats->zab_lock); mutex_destroy(&dp->dp_blkstats->zab_lock);
vmem_free(dp->dp_blkstats, sizeof (zfs_all_blkstats_t)); vmem_free(dp->dp_blkstats, sizeof (zfs_all_blkstats_t));
@ -1102,9 +1102,9 @@ dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx)
} }
taskq_t * taskq_t *
dsl_pool_iput_taskq(dsl_pool_t *dp) dsl_pool_zrele_taskq(dsl_pool_t *dp)
{ {
return (dp->dp_iput_taskq); return (dp->dp_zrele_taskq);
} }
taskq_t * taskq_t *

View File

@ -231,7 +231,8 @@ zfs_xattr_owner_unlinked(znode_t *zp)
{ {
int unlinked = 0; int unlinked = 0;
znode_t *dzp; znode_t *dzp;
igrab(ZTOI(zp));
zhold(zp);
/* /*
* if zp is XATTR node, keep walking up via z_xattr_parent until we * if zp is XATTR node, keep walking up via z_xattr_parent until we
* get the owner * get the owner
@ -242,11 +243,11 @@ zfs_xattr_owner_unlinked(znode_t *zp)
unlinked = 1; unlinked = 1;
break; break;
} }
iput(ZTOI(zp)); zrele(zp);
zp = dzp; zp = dzp;
unlinked = zp->z_unlinked; unlinked = zp->z_unlinked;
} }
iput(ZTOI(zp)); zrele(zp);
return (unlinked); return (unlinked);
} }

View File

@ -280,7 +280,7 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
char *name = NULL; /* location determined later */ char *name = NULL; /* location determined later */
lr_create_t *lr = (lr_create_t *)lracl; lr_create_t *lr = (lr_create_t *)lracl;
znode_t *dzp; znode_t *dzp;
struct inode *ip = NULL; znode_t *zp;
xvattr_t xva; xvattr_t xva;
int vflg = 0; int vflg = 0;
vsecattr_t vsec = { 0 }; vsecattr_t vsec = { 0 };
@ -371,8 +371,8 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
lr->lr_uid, lr->lr_gid); lr->lr_uid, lr->lr_gid);
} }
error = zfs_create(ZTOI(dzp), name, &xva.xva_vattr, error = zfs_create(dzp, name, &xva.xva_vattr,
0, 0, &ip, kcred, vflg, &vsec); 0, 0, &zp, kcred, vflg, &vsec);
break; break;
case TX_MKDIR_ACL: case TX_MKDIR_ACL:
aclstart = (caddr_t)(lracl + 1); aclstart = (caddr_t)(lracl + 1);
@ -401,18 +401,18 @@ zfs_replay_create_acl(void *arg1, void *arg2, boolean_t byteswap)
(void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt, (void *)&name, lracl->lr_fuidcnt, lracl->lr_domcnt,
lr->lr_uid, lr->lr_gid); lr->lr_uid, lr->lr_gid);
} }
error = zfs_mkdir(ZTOI(dzp), name, &xva.xva_vattr, error = zfs_mkdir(dzp, name, &xva.xva_vattr,
&ip, kcred, vflg, &vsec); &zp, kcred, vflg, &vsec);
break; break;
default: default:
error = SET_ERROR(ENOTSUP); error = SET_ERROR(ENOTSUP);
} }
bail: bail:
if (error == 0 && ip != NULL) if (error == 0 && zp != NULL)
iput(ip); zrele(zp);
iput(ZTOI(dzp)); zrele(dzp);
if (zfsvfs->z_fuid_replay) if (zfsvfs->z_fuid_replay)
zfs_fuid_info_free(zfsvfs->z_fuid_replay); zfs_fuid_info_free(zfsvfs->z_fuid_replay);
@ -429,7 +429,7 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
char *name = NULL; /* location determined later */ char *name = NULL; /* location determined later */
char *link; /* symlink content follows name */ char *link; /* symlink content follows name */
znode_t *dzp; znode_t *dzp;
struct inode *ip = NULL; znode_t *zp = NULL;
xvattr_t xva; xvattr_t xva;
int vflg = 0; int vflg = 0;
size_t lrsize = sizeof (lr_create_t); size_t lrsize = sizeof (lr_create_t);
@ -509,8 +509,8 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
if (name == NULL) if (name == NULL)
name = (char *)start; name = (char *)start;
error = zfs_create(ZTOI(dzp), name, &xva.xva_vattr, error = zfs_create(dzp, name, &xva.xva_vattr,
0, 0, &ip, kcred, vflg, NULL); 0, 0, &zp, kcred, vflg, NULL);
break; break;
case TX_MKDIR_ATTR: case TX_MKDIR_ATTR:
lrattr = (lr_attr_t *)(caddr_t)(lr + 1); lrattr = (lr_attr_t *)(caddr_t)(lr + 1);
@ -527,27 +527,27 @@ zfs_replay_create(void *arg1, void *arg2, boolean_t byteswap)
if (name == NULL) if (name == NULL)
name = (char *)(lr + 1); name = (char *)(lr + 1);
error = zfs_mkdir(ZTOI(dzp), name, &xva.xva_vattr, error = zfs_mkdir(dzp, name, &xva.xva_vattr,
&ip, kcred, vflg, NULL); &zp, kcred, vflg, NULL);
break; break;
case TX_MKXATTR: case TX_MKXATTR:
error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &ip, kcred); error = zfs_make_xattrdir(dzp, &xva.xva_vattr, &zp, kcred);
break; break;
case TX_SYMLINK: case TX_SYMLINK:
name = (char *)(lr + 1); name = (char *)(lr + 1);
link = name + strlen(name) + 1; link = name + strlen(name) + 1;
error = zfs_symlink(ZTOI(dzp), name, &xva.xva_vattr, error = zfs_symlink(dzp, name, &xva.xva_vattr,
link, &ip, kcred, vflg); link, &zp, kcred, vflg);
break; break;
default: default:
error = SET_ERROR(ENOTSUP); error = SET_ERROR(ENOTSUP);
} }
out: out:
if (error == 0 && ip != NULL) if (error == 0 && zp != NULL)
iput(ip); zrele(zp);
iput(ZTOI(dzp)); zrele(dzp);
if (zfsvfs->z_fuid_replay) if (zfsvfs->z_fuid_replay)
zfs_fuid_info_free(zfsvfs->z_fuid_replay); zfs_fuid_info_free(zfsvfs->z_fuid_replay);
@ -576,16 +576,16 @@ zfs_replay_remove(void *arg1, void *arg2, boolean_t byteswap)
switch ((int)lr->lr_common.lrc_txtype) { switch ((int)lr->lr_common.lrc_txtype) {
case TX_REMOVE: case TX_REMOVE:
error = zfs_remove(ZTOI(dzp), name, kcred, vflg); error = zfs_remove(dzp, name, kcred, vflg);
break; break;
case TX_RMDIR: case TX_RMDIR:
error = zfs_rmdir(ZTOI(dzp), name, NULL, kcred, vflg); error = zfs_rmdir(dzp, name, NULL, kcred, vflg);
break; break;
default: default:
error = SET_ERROR(ENOTSUP); error = SET_ERROR(ENOTSUP);
} }
iput(ZTOI(dzp)); zrele(dzp);
return (error); return (error);
} }
@ -607,17 +607,17 @@ zfs_replay_link(void *arg1, void *arg2, boolean_t byteswap)
return (error); return (error);
if ((error = zfs_zget(zfsvfs, lr->lr_link_obj, &zp)) != 0) { if ((error = zfs_zget(zfsvfs, lr->lr_link_obj, &zp)) != 0) {
iput(ZTOI(dzp)); zrele(dzp);
return (error); return (error);
} }
if (lr->lr_common.lrc_txtype & TX_CI) if (lr->lr_common.lrc_txtype & TX_CI)
vflg |= FIGNORECASE; vflg |= FIGNORECASE;
error = zfs_link(ZTOI(dzp), ZTOI(zp), name, kcred, vflg); error = zfs_link(dzp, zp, name, kcred, vflg);
iput(ZTOI(zp)); zrele(zp);
iput(ZTOI(dzp)); zrele(dzp);
return (error); return (error);
} }
@ -640,17 +640,17 @@ zfs_replay_rename(void *arg1, void *arg2, boolean_t byteswap)
return (error); return (error);
if ((error = zfs_zget(zfsvfs, lr->lr_tdoid, &tdzp)) != 0) { if ((error = zfs_zget(zfsvfs, lr->lr_tdoid, &tdzp)) != 0) {
iput(ZTOI(sdzp)); zrele(sdzp);
return (error); return (error);
} }
if (lr->lr_common.lrc_txtype & TX_CI) if (lr->lr_common.lrc_txtype & TX_CI)
vflg |= FIGNORECASE; vflg |= FIGNORECASE;
error = zfs_rename(ZTOI(sdzp), sname, ZTOI(tdzp), tname, kcred, vflg); error = zfs_rename(sdzp, sname, tdzp, tname, kcred, vflg);
iput(ZTOI(tdzp)); zrele(tdzp);
iput(ZTOI(sdzp)); zrele(sdzp);
return (error); return (error);
} }
@ -714,7 +714,7 @@ zfs_replay_write(void *arg1, void *arg2, boolean_t byteswap)
else if (written < length) else if (written < length)
error = SET_ERROR(EIO); /* short write */ error = SET_ERROR(EIO); /* short write */
iput(ZTOI(zp)); zrele(zp);
zfsvfs->z_replay_eof = 0; /* safety */ zfsvfs->z_replay_eof = 0; /* safety */
return (error); return (error);
@ -750,7 +750,7 @@ top:
dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_FALSE);
error = dmu_tx_assign(tx, TXG_WAIT); error = dmu_tx_assign(tx, TXG_WAIT);
if (error) { if (error) {
iput(ZTOI(zp)); zrele(zp);
if (error == ERESTART) { if (error == ERESTART) {
dmu_tx_wait(tx); dmu_tx_wait(tx);
dmu_tx_abort(tx); dmu_tx_abort(tx);
@ -768,7 +768,7 @@ top:
dmu_tx_commit(tx); dmu_tx_commit(tx);
} }
iput(ZTOI(zp)); zrele(zp);
return (error); return (error);
} }
@ -794,10 +794,10 @@ zfs_replay_truncate(void *arg1, void *arg2, boolean_t byteswap)
fl.l_start = lr->lr_offset; fl.l_start = lr->lr_offset;
fl.l_len = lr->lr_length; fl.l_len = lr->lr_length;
error = zfs_space(ZTOI(zp), F_FREESP, &fl, O_RDWR | O_LARGEFILE, error = zfs_space(zp, F_FREESP, &fl, O_RDWR | O_LARGEFILE,
lr->lr_offset, kcred); lr->lr_offset, kcred);
iput(ZTOI(zp)); zrele(zp);
return (error); return (error);
} }
@ -849,11 +849,11 @@ zfs_replay_setattr(void *arg1, void *arg2, boolean_t byteswap)
zfsvfs->z_fuid_replay = zfs_replay_fuid_domain(start, &start, zfsvfs->z_fuid_replay = zfs_replay_fuid_domain(start, &start,
lr->lr_uid, lr->lr_gid); lr->lr_uid, lr->lr_gid);
error = zfs_setattr(ZTOI(zp), vap, 0, kcred); error = zfs_setattr(zp, vap, 0, kcred);
zfs_fuid_info_free(zfsvfs->z_fuid_replay); zfs_fuid_info_free(zfsvfs->z_fuid_replay);
zfsvfs->z_fuid_replay = NULL; zfsvfs->z_fuid_replay = NULL;
iput(ZTOI(zp)); zrele(zp);
return (error); return (error);
} }
@ -883,9 +883,9 @@ zfs_replay_acl_v0(void *arg1, void *arg2, boolean_t byteswap)
vsa.vsa_aclflags = 0; vsa.vsa_aclflags = 0;
vsa.vsa_aclentp = ace; vsa.vsa_aclentp = ace;
error = zfs_setsecattr(ZTOI(zp), &vsa, 0, kcred); error = zfs_setsecattr(zp, &vsa, 0, kcred);
iput(ZTOI(zp)); zrele(zp);
return (error); return (error);
} }
@ -943,13 +943,13 @@ zfs_replay_acl(void *arg1, void *arg2, boolean_t byteswap)
lr->lr_fuidcnt, lr->lr_domcnt, 0, 0); lr->lr_fuidcnt, lr->lr_domcnt, 0, 0);
} }
error = zfs_setsecattr(ZTOI(zp), &vsa, 0, kcred); error = zfs_setsecattr(zp, &vsa, 0, kcred);
if (zfsvfs->z_fuid_replay) if (zfsvfs->z_fuid_replay)
zfs_fuid_info_free(zfsvfs->z_fuid_replay); zfs_fuid_info_free(zfsvfs->z_fuid_replay);
zfsvfs->z_fuid_replay = NULL; zfsvfs->z_fuid_replay = NULL;
iput(ZTOI(zp)); zrele(zp);
return (error); return (error);
} }