Prototype/structure update for Linux

I appologize in advance why to many things ended up in this commit.
When it could be seperated in to a whole series of commits teasing
that all apart now would take considerable time and I'm not sure
there's much merrit in it.  As such I'll just summerize the intent
of the changes which are all (or partly) in this commit.  Broadly
the intent is to remove as much Solaris specific code as possible
and replace it with native Linux equivilants.  More specifically:

1) Replace all instances of zfsvfs_t with zfs_sb_t.  While the
type is largely the same calling it private super block data
rather than a zfsvfs is more consistent with how Linux names
this.  While non critical it makes the code easier to read when
your thinking in Linux friendly VFS terms.

2) Replace vnode_t with struct inode.  The Linux VFS doesn't have
the notion of a vnode and there's absolutely no good reason to
create one.  There are in fact several good reasons to remove it.
It just adds overhead on Linux if we were to manage one, it
conplicates the code, and it likely will lead to bugs so there's
a good change it will be out of date.  The code has been updated
to remove all need for this type.

3) Replace all vtype_t's with umode types.  Along with this shift
all uses of types to mode bits.  The Solaris code would pass a
vtype which is redundant with the Linux mode.  Just update all the
code to use the Linux mode macros and remove this redundancy.

4) Remove using of vn_* helpers and replace where needed with
inode helpers.  The big example here is creating iput_aync to
replace vn_rele_async.  Other vn helpers will be addressed as
needed but they should be be emulated.  They are a Solaris VFS'ism
and should simply be replaced with Linux equivilants.

5) Update znode alloc/free code.  Under Linux it's common to
embed the inode specific data with the inode itself.  This removes
the need for an extra memory allocation.  In zfs this information
is called a znode and it now embeds the inode with it.  Allocators
have been updated accordingly.

6) Minimal integration with the vfs flags for setting up the
super block and handling mount options has been added this
code will need to be refined but functionally it's all there.

This will be the first and last of these to large to review commits.
This commit is contained in:
Brian Behlendorf 2011-02-08 11:16:06 -08:00
parent 6149f4c45f
commit 3558fd73b5
22 changed files with 2103 additions and 3351 deletions

View File

@ -75,7 +75,7 @@ typedef struct dsl_pool {
struct dsl_dir *dp_free_dir; struct dsl_dir *dp_free_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_vnrele_taskq; struct taskq *dp_iput_taskq;
/* No lock needed - sync context only */ /* No lock needed - sync context only */
blkptr_t dp_meta_rootbp; blkptr_t dp_meta_rootbp;
@ -135,7 +135,7 @@ void dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx);
void dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx); void dsl_pool_upgrade_clones(dsl_pool_t *dp, dmu_tx_t *tx);
void dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx); void dsl_pool_upgrade_dir_clones(dsl_pool_t *dp, dmu_tx_t *tx);
taskq_t *dsl_pool_vnrele_taskq(dsl_pool_t *dp); taskq_t *dsl_pool_iput_taskq(dsl_pool_t *dp);
extern int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj, extern int dsl_pool_user_hold(dsl_pool_t *dp, uint64_t dsobj,
const char *tag, uint64_t *now, dmu_tx_t *tx); const char *tag, uint64_t *now, dmu_tx_t *tx);

View File

@ -200,13 +200,13 @@ typedef struct zfs_acl_ids {
#define ZFS_ACL_PASSTHROUGH_X 5 #define ZFS_ACL_PASSTHROUGH_X 5
struct znode; struct znode;
struct zfsvfs; struct zfs_sb;
#ifdef _KERNEL #ifdef _KERNEL
int zfs_acl_ids_create(struct znode *, int, vattr_t *, int zfs_acl_ids_create(struct znode *, int, vattr_t *,
cred_t *, vsecattr_t *, zfs_acl_ids_t *); cred_t *, vsecattr_t *, zfs_acl_ids_t *);
void zfs_acl_ids_free(zfs_acl_ids_t *); void zfs_acl_ids_free(zfs_acl_ids_t *);
boolean_t zfs_acl_ids_overquota(struct zfsvfs *, zfs_acl_ids_t *); boolean_t zfs_acl_ids_overquota(struct zfs_sb *, zfs_acl_ids_t *);
int zfs_getacl(struct znode *, vsecattr_t *, boolean_t, cred_t *); int zfs_getacl(struct znode *, vsecattr_t *, boolean_t, cred_t *);
int zfs_setacl(struct znode *, vsecattr_t *, boolean_t, cred_t *); int zfs_setacl(struct znode *, vsecattr_t *, boolean_t, cred_t *);
void zfs_acl_rele(void *); void zfs_acl_rele(void *);
@ -223,7 +223,7 @@ int zfs_zaccess_delete(struct znode *, struct znode *, cred_t *);
int zfs_zaccess_rename(struct znode *, struct znode *, int zfs_zaccess_rename(struct znode *, struct znode *,
struct znode *, struct znode *, cred_t *cr); struct znode *, struct znode *, cred_t *cr);
void zfs_acl_free(zfs_acl_t *); void zfs_acl_free(zfs_acl_t *);
int zfs_vsec_2_aclp(struct zfsvfs *, vtype_t, vsecattr_t *, cred_t *, int zfs_vsec_2_aclp(struct zfs_sb *, umode_t, vsecattr_t *, cred_t *,
struct zfs_fuid_info **, zfs_acl_t **); struct zfs_fuid_info **, zfs_acl_t **);
int zfs_aclset_common(struct znode *, zfs_acl_t *, cred_t *, dmu_tx_t *); int zfs_aclset_common(struct znode *, zfs_acl_t *, cred_t *, dmu_tx_t *);
uint64_t zfs_external_acl(struct znode *); uint64_t zfs_external_acl(struct znode *);

View File

@ -54,7 +54,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 *, vnode_t **, int, int *, extern int zfs_dirlook(znode_t *, char *, struct inode **, 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 *);
@ -62,10 +62,10 @@ extern void zfs_rmnode(znode_t *);
extern void zfs_dl_name_switch(zfs_dirlock_t *dl, char *new, char **old); extern void zfs_dl_name_switch(zfs_dirlock_t *dl, char *new, char **old);
extern boolean_t zfs_dirempty(znode_t *); extern boolean_t zfs_dirempty(znode_t *);
extern void zfs_unlinked_add(znode_t *, dmu_tx_t *); extern void zfs_unlinked_add(znode_t *, dmu_tx_t *);
extern void zfs_unlinked_drain(zfsvfs_t *zfsvfs); extern void zfs_unlinked_drain(zfs_sb_t *);
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 *, vnode_t **, cred_t *, int); extern int zfs_get_xattrdir(znode_t *, struct inode **, cred_t *, int);
extern int zfs_make_xattrdir(znode_t *, vattr_t *, vnode_t **, cred_t *); extern int zfs_make_xattrdir(znode_t *, vattr_t *, struct inode **, cred_t *);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -100,24 +100,24 @@ typedef struct zfs_fuid_info {
#ifdef _KERNEL #ifdef _KERNEL
struct znode; struct znode;
extern uid_t zfs_fuid_map_id(zfsvfs_t *, uint64_t, cred_t *, zfs_fuid_type_t); extern uid_t zfs_fuid_map_id(zfs_sb_t *, uint64_t, cred_t *, zfs_fuid_type_t);
extern void zfs_fuid_node_add(zfs_fuid_info_t **, const char *, uint32_t, extern void zfs_fuid_node_add(zfs_fuid_info_t **, const char *, uint32_t,
uint64_t, uint64_t, zfs_fuid_type_t); uint64_t, uint64_t, zfs_fuid_type_t);
extern void zfs_fuid_destroy(zfsvfs_t *); extern void zfs_fuid_destroy(zfs_sb_t *);
extern uint64_t zfs_fuid_create_cred(zfsvfs_t *, zfs_fuid_type_t, extern uint64_t zfs_fuid_create_cred(zfs_sb_t *, zfs_fuid_type_t,
cred_t *, zfs_fuid_info_t **); cred_t *, zfs_fuid_info_t **);
extern uint64_t zfs_fuid_create(zfsvfs_t *, uint64_t, cred_t *, zfs_fuid_type_t, extern uint64_t zfs_fuid_create(zfs_sb_t *, uint64_t, cred_t *, zfs_fuid_type_t,
zfs_fuid_info_t **); zfs_fuid_info_t **);
extern void zfs_fuid_map_ids(struct znode *zp, cred_t *cr, extern void zfs_fuid_map_ids(struct znode *zp, cred_t *cr,
uid_t *uid, uid_t *gid); uid_t *uid, uid_t *gid);
extern zfs_fuid_info_t *zfs_fuid_info_alloc(void); extern zfs_fuid_info_t *zfs_fuid_info_alloc(void);
extern void zfs_fuid_info_free(zfs_fuid_info_t *); extern void zfs_fuid_info_free(zfs_fuid_info_t *);
extern boolean_t zfs_groupmember(zfsvfs_t *, uint64_t, cred_t *); extern boolean_t zfs_groupmember(zfs_sb_t *, uint64_t, cred_t *);
void zfs_fuid_sync(zfsvfs_t *, dmu_tx_t *); void zfs_fuid_sync(zfs_sb_t *, dmu_tx_t *);
extern int zfs_fuid_find_by_domain(zfsvfs_t *, const char *domain, extern int zfs_fuid_find_by_domain(zfs_sb_t *, const char *domain,
char **retdomain, boolean_t addok); char **retdomain, boolean_t addok);
extern const char *zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx); extern const char *zfs_fuid_find_by_idx(zfs_sb_t *zsb, uint32_t idx);
extern void zfs_fuid_txhold(zfsvfs_t *zfsvfs, dmu_tx_t *tx); extern void zfs_fuid_txhold(zfs_sb_t *zsb, dmu_tx_t *tx);
#endif #endif
char *zfs_fuid_idx_domain(avl_tree_t *, uint32_t); char *zfs_fuid_idx_domain(avl_tree_t *, uint32_t);

View File

@ -38,13 +38,15 @@
extern "C" { extern "C" {
#endif #endif
typedef struct zfsvfs zfsvfs_t; struct zfs_sb;
struct znode; struct znode;
struct zfsvfs { typedef struct zfs_sb {
vfs_t *z_vfs; /* generic fs struct */ struct vfsmount *z_vfs; /* generic vfs struct */
zfsvfs_t *z_parent; /* parent fs */ struct super_block *z_sb; /* generic super_block */
struct zfs_sb *z_parent; /* parent fs */
objset_t *z_os; /* objset reference */ objset_t *z_os; /* objset reference */
uint64_t z_flags; /* super_block flags */
uint64_t z_root; /* id of root znode */ uint64_t z_root; /* id of root znode */
uint64_t z_unlinkedobj; /* id of unlinked zapobj */ uint64_t z_unlinkedobj; /* id of unlinked zapobj */
uint64_t z_max_blksz; /* maximum block size for files */ uint64_t z_max_blksz; /* maximum block size for files */
@ -87,6 +89,8 @@ struct zfsvfs {
#define ZFS_SUPER_MAGIC 0x2fc12fc1 #define ZFS_SUPER_MAGIC 0x2fc12fc1
#define ZSB_XATTR_USER 0x0001 /* Enable user xattrs */
/* /*
* Minimal snapshot helpers, the bulk of the Linux snapshot implementation * Minimal snapshot helpers, the bulk of the Linux snapshot implementation
@ -162,30 +166,30 @@ typedef struct zfid_long {
extern uint_t zfs_fsyncer_key; extern uint_t zfs_fsyncer_key;
extern int zfs_suspend_fs(zfsvfs_t *zfsvfs); extern int zfs_suspend_fs(zfs_sb_t *zsb);
extern int zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname); extern int zfs_resume_fs(zfs_sb_t *zsb, const char *osname);
extern int zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, extern int zfs_userspace_one(zfs_sb_t *zsb, zfs_userquota_prop_t type,
const char *domain, uint64_t rid, uint64_t *valuep); const char *domain, uint64_t rid, uint64_t *valuep);
extern int zfs_userspace_many(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, extern int zfs_userspace_many(zfs_sb_t *zsb, zfs_userquota_prop_t type,
uint64_t *cookiep, void *vbuf, uint64_t *bufsizep); uint64_t *cookiep, void *vbuf, uint64_t *bufsizep);
extern int zfs_set_userquota(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type, extern int zfs_set_userquota(zfs_sb_t *zsb, zfs_userquota_prop_t type,
const char *domain, uint64_t rid, uint64_t quota); const char *domain, uint64_t rid, uint64_t quota);
extern boolean_t zfs_owner_overquota(zfsvfs_t *zfsvfs, struct znode *, extern boolean_t zfs_owner_overquota(zfs_sb_t *zsb, struct znode *,
boolean_t isgroup); boolean_t isgroup);
extern boolean_t zfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, extern boolean_t zfs_fuid_overquota(zfs_sb_t *zsb, boolean_t isgroup,
uint64_t fuid); uint64_t fuid);
extern int zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers); extern int zfs_set_version(zfs_sb_t *zsb, uint64_t newvers);
extern int zfsvfs_create(const char *name, zfsvfs_t **zfvp); extern int zfs_sb_create(const char *name, zfs_sb_t **zsbp);
extern void zfsvfs_free(zfsvfs_t *zfsvfs); extern void zfs_sb_free(zfs_sb_t *zsb);
extern int zfs_check_global_label(const char *dsname, const char *hexsl); extern int zfs_check_global_label(const char *dsname, const char *hexsl);
extern int zfs_register_callbacks(vfs_t *vfsp); extern int zfs_register_callbacks(zfs_sb_t *zsb);
extern void zfs_unregister_callbacks(zfsvfs_t *zfsvfs); extern void zfs_unregister_callbacks(zfs_sb_t *zsb);
extern int zfs_domount(vfs_t *vfsp, char *osname); extern int zfs_domount(struct super_block *sb, void *data, int silent);
extern int zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr); extern int zfs_umount(struct super_block *sb);
extern int zfs_root(vfs_t *vfsp, vnode_t **vpp); extern int zfs_root(zfs_sb_t *zsb, struct inode **ipp);
extern int zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp); extern int zfs_statvfs(struct dentry *dentry, struct kstatfs *statp);
extern int zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp); extern int zfs_vget(struct vfsmount *vfsp, struct inode **ipp, fid_t *fidp);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -28,50 +28,48 @@
#include <sys/vnode.h> #include <sys/vnode.h>
#include <sys/uio.h> #include <sys/uio.h>
#include <sys/cred.h> #include <sys/cred.h>
#include <sys/fcntl.h>
#include <sys/pathname.h>
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
extern int zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, extern int zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
caller_context_t *ct); extern int zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
extern int zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr, extern int zfs_access(struct inode *ip, int mode, int flag, cred_t *cr);
caller_context_t *ct); extern int zfs_lookup(struct inode *dip, char *nm, struct inode **ipp,
extern int zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp, int flags, cred_t *cr, int *direntflags, pathname_t *realpnp);
struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr, extern int zfs_create(struct inode *dip, char *name, vattr_t *vap, int excl,
caller_context_t *ct, int *direntflags, pathname_t *realpnp); int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp);
extern int zfs_create(vnode_t *dvp, char *name, vattr_t *vap, extern int zfs_remove(struct inode *dip, char *name, cred_t *cr);
int excl, int mode, vnode_t **vpp, cred_t *cr, int flag, extern int zfs_mkdir(struct inode *dip, char *dirname, vattr_t *vap,
caller_context_t *ct, vsecattr_t *vsecp); struct inode **ipp, cred_t *cr, int flags, vsecattr_t *vsecp);
extern int zfs_remove(vnode_t *dvp, char *name, cred_t *cr, extern int zfs_rmdir(struct inode *dip, char *name, struct inode *cwd,
caller_context_t *ct, int flags); cred_t *cr, int flags);
extern int zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap, extern int zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir,
vnode_t **vpp, cred_t *cr, caller_context_t *ct, int flags, loff_t *pos, cred_t *cr);
vsecattr_t *vsecp); extern int zfs_fsync(struct inode *ip, int syncflag, cred_t *cr);
extern int zfs_rmdir(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr, extern int zfs_getattr(struct inode *ip, struct kstat *stat, int flag,
caller_context_t *ct, int flags); cred_t *cr);
extern int zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr, extern int zfs_setattr(struct inode *ip, struct iattr *attr, int flag,
caller_context_t *ct); cred_t *cr);
extern int zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, extern int zfs_rename(struct inode *sdip, char *snm, struct inode *tdip,
caller_context_t *ct); char *tnm, cred_t *cr, int flags);
extern int zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr, extern int zfs_symlink(struct inode *dip, char *name, vattr_t *vap,
caller_context_t *ct); char *link, struct inode **ipp, cred_t *cr, int flags);
extern int zfs_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm, extern int zfs_follow_link(struct dentry *dentry, struct nameidata *nd);
cred_t *cr, caller_context_t *ct, int flags); extern int zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr);
extern int zfs_symlink(vnode_t *dvp, char *name, vattr_t *vap, char *link, extern int zfs_link(struct inode *tdip, struct inode *sip,
cred_t *cr, caller_context_t *ct, int flags); char *name, cred_t *cr);
extern int zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr, extern void zfs_inactive(struct inode *ip);
caller_context_t *ct); extern int zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag,
extern int zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr, offset_t offset, cred_t *cr);
caller_context_t *ct, int flags); extern int zfs_fid(struct inode *ip, fid_t *fidp);
extern void zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct); extern int zfs_getsecattr(struct inode *ip, vsecattr_t *vsecp, int flag,
extern int zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag, cred_t *cr);
offset_t offset, cred_t *cr, caller_context_t *ct); extern int zfs_setsecattr(struct inode *ip, vsecattr_t *vsecp, int flag,
extern int zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct); cred_t *cr);
extern int zfs_getsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag,
cred_t *cr, caller_context_t *ct);
extern int zfs_setsecattr(vnode_t *vp, vsecattr_t *vsecp, int flag,
cred_t *cr, caller_context_t *ct);
#ifdef __cplusplus #ifdef __cplusplus
} }

View File

@ -69,7 +69,7 @@ extern "C" {
pflags |= attr; \ pflags |= attr; \
else \ else \
pflags &= ~attr; \ pflags &= ~attr; \
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zp->z_zfsvfs), \ VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zp->z_sb), \
&pflags, sizeof (pflags), tx)); \ &pflags, sizeof (pflags), tx)); \
} }
@ -181,8 +181,6 @@ typedef struct zfs_dirlock {
} zfs_dirlock_t; } zfs_dirlock_t;
typedef struct znode { typedef struct znode {
struct zfsvfs *z_zfsvfs;
vnode_t *z_vnode;
uint64_t z_id; /* object ID for this znode */ uint64_t z_id; /* object ID for this znode */
kmutex_t z_lock; /* znode modification lock */ kmutex_t z_lock; /* znode modification lock */
krwlock_t z_parent_lock; /* parent lock for directories */ krwlock_t z_parent_lock; /* parent lock for directories */
@ -235,48 +233,52 @@ typedef struct znode {
/* /*
* Convert between znode pointers and inode pointers * Convert between znode pointers and inode pointers
*/ */
#define ZTOI(ZP) (&((ZP)->z_inode)) #define ZTOI(znode) (&((znode)->z_inode))
#define ITOZ(IP) (container_of((IP), znode_t, z_inode)) #define ITOZ(inode) (container_of((inode), znode_t, z_inode))
#define VTOZSB(vfs) ((zfs_sb_t *)((vfs)->mnt_sb->s_fs_info))
/* XXX - REMOVE ME ONCE THE OTHER BUILD ISSUES ARE RESOLVED */ #define ZTOZSB(znode) ((zfs_sb_t *)(ZTOI(znode)->i_sb->s_fs_info))
#define ZTOV(ZP) ((ZP)->z_vnode) #define ITOZSB(inode) ((zfs_sb_t *)((inode)->i_sb->s_fs_info))
#define VTOZ(VP) ((znode_t *)(VP)->v_data)
#define S_ISDEV(mode) (S_ISCHR(mode) || S_ISBLK(mode) || S_ISFIFO(mode))
/* /*
* ZFS_ENTER() is called on entry to each ZFS inode 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_EXIT() must be called before exitting the vop.
* ZFS_VERIFY_ZP() verifies the znode is valid. * ZFS_VERIFY_ZP() verifies the znode is valid.
*/ */
#define ZFS_ENTER(zfsvfs) \ #define ZFS_ENTER(zsb) \
{ \ { \
rrw_enter(&(zfsvfs)->z_teardown_lock, RW_READER, FTAG); \ rrw_enter(&(zsb)->z_teardown_lock, RW_READER, FTAG); \
if ((zfsvfs)->z_unmounted) { \ if ((zsb)->z_unmounted) { \
ZFS_EXIT(zfsvfs); \ ZFS_EXIT(zsb); \
return (EIO); \ return (EIO); \
} \ } \
} }
#define ZFS_EXIT(zfsvfs) rrw_exit(&(zfsvfs)->z_teardown_lock, FTAG) #define ZFS_EXIT(zsb) \
{ \
rrw_exit(&(zsb)->z_teardown_lock, FTAG); \
tsd_exit(); \
}
#define ZFS_VERIFY_ZP(zp) \ #define ZFS_VERIFY_ZP(zp) \
if ((zp)->z_sa_hdl == NULL) { \ if ((zp)->z_sa_hdl == NULL) { \
ZFS_EXIT((zp)->z_zfsvfs); \ ZFS_EXIT(ZTOZSB(zp)); \
return (EIO); \ return (EIO); \
} \ }
/* /*
* Macros for dealing with dmu_buf_hold * Macros for dealing with dmu_buf_hold
*/ */
#define ZFS_OBJ_HASH(obj_num) ((obj_num) & (ZFS_OBJ_MTX_SZ - 1)) #define ZFS_OBJ_HASH(obj_num) ((obj_num) & (ZFS_OBJ_MTX_SZ - 1))
#define ZFS_OBJ_MUTEX(zfsvfs, obj_num) \ #define ZFS_OBJ_MUTEX(zsb, obj_num) \
(&(zfsvfs)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)]) (&(zsb)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)])
#define ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num) \ #define ZFS_OBJ_HOLD_ENTER(zsb, obj_num) \
mutex_enter(ZFS_OBJ_MUTEX((zfsvfs), (obj_num))) mutex_enter(ZFS_OBJ_MUTEX((zsb), (obj_num)))
#define ZFS_OBJ_HOLD_TRYENTER(zfsvfs, obj_num) \ #define ZFS_OBJ_HOLD_TRYENTER(zsb, obj_num) \
mutex_tryenter(ZFS_OBJ_MUTEX((zfsvfs), (obj_num))) mutex_tryenter(ZFS_OBJ_MUTEX((zsb), (obj_num)))
#define ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num) \ #define ZFS_OBJ_HOLD_EXIT(zsb, obj_num) \
mutex_exit(ZFS_OBJ_MUTEX((zfsvfs), (obj_num))) mutex_exit(ZFS_OBJ_MUTEX((zsb), (obj_num)))
/* /*
* Macros to encode/decode ZFS stored time values from/to struct timespec * Macros to encode/decode ZFS stored time values from/to struct timespec
@ -296,15 +298,15 @@ typedef struct znode {
/* /*
* Timestamp defines * Timestamp defines
*/ */
#define ACCESSED (AT_ATIME) #define ACCESSED (ATTR_ATIME)
#define STATE_CHANGED (AT_CTIME) #define STATE_CHANGED (ATTR_CTIME)
#define CONTENT_MODIFIED (AT_MTIME | AT_CTIME) #define CONTENT_MODIFIED (ATTR_MTIME | ATTR_CTIME)
#define ZFS_ACCESSTIME_STAMP(zfsvfs, zp) \ #define ZFS_ACCESSTIME_STAMP(zsb, zp) \
if ((zfsvfs)->z_atime && !((zfsvfs)->z_vfs->vfs_flag & VFS_RDONLY)) \ if ((zsb)->z_atime && !((zsb)->z_vfs->mnt_flags & MNT_READONLY)) \
zfs_tstamp_update_setup(zp, ACCESSED, NULL, NULL, B_FALSE); zfs_tstamp_update_setup(zp, ACCESSED, NULL, NULL, B_FALSE);
extern int zfs_init_fs(zfsvfs_t *, znode_t **); extern int zfs_init_fs(zfs_sb_t *, znode_t **);
extern void zfs_set_dataprop(objset_t *); extern void zfs_set_dataprop(objset_t *);
extern void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *, extern void zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *,
dmu_tx_t *tx); dmu_tx_t *tx);
@ -314,18 +316,19 @@ extern void zfs_grow_blocksize(znode_t *, uint64_t, dmu_tx_t *);
extern int zfs_freesp(znode_t *, uint64_t, uint64_t, int, boolean_t); extern int zfs_freesp(znode_t *, uint64_t, uint64_t, int, boolean_t);
extern void zfs_znode_init(void); extern void zfs_znode_init(void);
extern void zfs_znode_fini(void); extern void zfs_znode_fini(void);
extern int zfs_zget(zfsvfs_t *, uint64_t, znode_t **); extern int zfs_zget(zfs_sb_t *, uint64_t, znode_t **);
extern int zfs_rezget(znode_t *); extern int zfs_rezget(znode_t *);
extern void zfs_zinactive(znode_t *); extern void zfs_zinactive(znode_t *);
extern void zfs_znode_delete(znode_t *, dmu_tx_t *); extern void zfs_znode_delete(znode_t *, dmu_tx_t *);
extern void zfs_znode_free(znode_t *);
extern void zfs_remove_op_tables(void); extern void zfs_remove_op_tables(void);
extern int zfs_create_op_tables(void); extern int zfs_create_op_tables(void);
extern int zfs_sync(vfs_t *vfsp, short flag, cred_t *cr); extern int zfs_sync(zfs_sb_t *, short, cred_t *);
extern dev_t zfs_cmpldev(uint64_t); 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_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value);
extern int zfs_get_stats(objset_t *os, nvlist_t *nv); extern int zfs_get_stats(objset_t *os, nvlist_t *nv);
extern void zfs_znode_dmu_fini(znode_t *); extern void zfs_znode_dmu_fini(znode_t *);
extern int zfs_inode_alloc(struct super_block *, struct inode **ip);
extern void zfs_inode_destroy(struct inode *);
extern void zfs_inode_update(znode_t *); extern void zfs_inode_update(znode_t *);
extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype, extern void zfs_log_create(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
@ -347,12 +350,13 @@ extern void zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
extern void zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype, extern void zfs_log_truncate(zilog_t *zilog, dmu_tx_t *tx, int txtype,
znode_t *zp, uint64_t off, uint64_t len); znode_t *zp, uint64_t off, uint64_t len);
extern void zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype, extern void zfs_log_setattr(zilog_t *zilog, dmu_tx_t *tx, int txtype,
znode_t *zp, vattr_t *vap, uint_t mask_applied, zfs_fuid_info_t *fuidp); znode_t *zp, struct iattr *attr, uint_t mask_applied,
zfs_fuid_info_t *fuidp);
extern void zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp, extern void zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
vsecattr_t *vsecp, zfs_fuid_info_t *fuidp); vsecattr_t *vsecp, zfs_fuid_info_t *fuidp);
extern void zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx); extern void zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx);
extern void zfs_upgrade(zfsvfs_t *zfsvfs, dmu_tx_t *tx); extern void zfs_upgrade(zfs_sb_t *zsb, dmu_tx_t *tx);
extern int zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx); extern int zfs_create_share_dir(zfs_sb_t *zsb, dmu_tx_t *tx);
#if defined(HAVE_UIO_RW) #if defined(HAVE_UIO_RW)
extern caddr_t zfs_map_page(page_t *, enum seg_rw); extern caddr_t zfs_map_page(page_t *, enum seg_rw);

View File

@ -910,10 +910,8 @@ dmu_objset_snapshot_one(const char *name, void *arg)
* permission checks for the starting dataset have already been * permission checks for the starting dataset have already been
* performed in zfs_secpolicy_snapshot() * performed in zfs_secpolicy_snapshot()
*/ */
#ifdef HAVE_ZPL
if (sn->recursive && (err = zfs_secpolicy_snapshot_perms(name, CRED()))) if (sn->recursive && (err = zfs_secpolicy_snapshot_perms(name, CRED())))
return (err); return (err);
#endif
err = dmu_objset_hold(name, sn, &os); err = dmu_objset_hold(name, sn, &os);
if (err != 0) if (err != 0)

View File

@ -2364,13 +2364,11 @@ dsl_snapshot_rename_one(const char *name, void *arg)
* For recursive snapshot renames the parent won't be changing * For recursive snapshot renames the parent won't be changing
* so we just pass name for both the to/from argument. * so we just pass name for both the to/from argument.
*/ */
#ifdef HAVE_ZPL
err = zfs_secpolicy_rename_perms(snapname, snapname, CRED()); err = zfs_secpolicy_rename_perms(snapname, snapname, CRED());
if (err != 0) { if (err != 0) {
strfree(snapname); strfree(snapname);
return (err == ENOENT ? 0 : err); return (err == ENOENT ? 0 : err);
} }
#endif
/* XXX: Ignore for SPL version until mounting the FS is supported */ /* XXX: Ignore for SPL version until mounting the FS is supported */
#if defined(_KERNEL) && !defined(HAVE_SPL) #if defined(_KERNEL) && !defined(HAVE_SPL)

View File

@ -92,7 +92,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);
dp->dp_vnrele_taskq = taskq_create("zfs_vn_rele_taskq", 1, minclsyspri, dp->dp_iput_taskq = taskq_create("zfs_iput_taskq", 1, minclsyspri,
1, 4, 0); 1, 4, 0);
return (dp); return (dp);
@ -214,7 +214,7 @@ dsl_pool_close(dsl_pool_t *dp)
dsl_scan_fini(dp); dsl_scan_fini(dp);
rw_destroy(&dp->dp_config_rwlock); rw_destroy(&dp->dp_config_rwlock);
mutex_destroy(&dp->dp_lock); mutex_destroy(&dp->dp_lock);
taskq_destroy(dp->dp_vnrele_taskq); taskq_destroy(dp->dp_iput_taskq);
if (dp->dp_blkstats) if (dp->dp_blkstats)
kmem_free(dp->dp_blkstats, sizeof (zfs_all_blkstats_t)); kmem_free(dp->dp_blkstats, sizeof (zfs_all_blkstats_t));
kmem_free(dp, sizeof (dsl_pool_t)); kmem_free(dp, sizeof (dsl_pool_t));
@ -738,9 +738,9 @@ dsl_pool_create_origin(dsl_pool_t *dp, dmu_tx_t *tx)
} }
taskq_t * taskq_t *
dsl_pool_vnrele_taskq(dsl_pool_t *dp) dsl_pool_iput_taskq(dsl_pool_t *dp)
{ {
return (dp->dp_vnrele_taskq); return (dp->dp_iput_taskq);
} }
/* /*

View File

@ -179,7 +179,6 @@ spa_config_write(spa_config_dirent_t *dp, nvlist_t *nvl)
(void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE); (void) vn_rename(temp, dp->scd_path, UIO_SYSSPACE);
} }
(void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL); (void) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
VN_RELE(vp);
} }
(void) vn_remove(temp, UIO_SYSSPACE, RMFILE); (void) vn_remove(temp, UIO_SYSSPACE, RMFILE);

View File

@ -130,7 +130,6 @@ vdev_file_close(vdev_t *vd)
(void) VOP_PUTPAGE(vf->vf_vnode, 0, 0, B_INVAL, kcred, NULL); (void) VOP_PUTPAGE(vf->vf_vnode, 0, 0, B_INVAL, kcred, NULL);
(void) VOP_CLOSE(vf->vf_vnode, spa_mode(vd->vdev_spa), 1, 0, (void) VOP_CLOSE(vf->vf_vnode, spa_mode(vd->vdev_spa), 1, 0,
kcred, NULL); kcred, NULL);
VN_RELE(vf->vf_vnode);
} }
vd->vdev_delayed_close = B_FALSE; vd->vdev_delayed_close = B_FALSE;

View File

@ -345,7 +345,7 @@ zfs_external_acl(znode_t *zp)
* changed. * changed.
*/ */
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zp->z_zfsvfs), if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(ZTOZSB(zp)),
&acl_phys, sizeof (acl_phys))) == 0) &acl_phys, sizeof (acl_phys))) == 0)
return (acl_phys.z_acl_extern_obj); return (acl_phys.z_acl_extern_obj);
else { else {
@ -368,23 +368,23 @@ static int
zfs_acl_znode_info(znode_t *zp, int *aclsize, int *aclcount, zfs_acl_znode_info(znode_t *zp, int *aclsize, int *aclcount,
zfs_acl_phys_t *aclphys) zfs_acl_phys_t *aclphys)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
uint64_t acl_count; uint64_t acl_count;
int size; int size;
int error; int error;
ASSERT(MUTEX_HELD(&zp->z_acl_lock)); ASSERT(MUTEX_HELD(&zp->z_acl_lock));
if (zp->z_is_sa) { if (zp->z_is_sa) {
if ((error = sa_size(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zfsvfs), if ((error = sa_size(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zsb),
&size)) != 0) &size)) != 0)
return (error); return (error);
*aclsize = size; *aclsize = size;
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_COUNT(zfsvfs), if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_COUNT(zsb),
&acl_count, sizeof (acl_count))) != 0) &acl_count, sizeof (acl_count))) != 0)
return (error); return (error);
*aclcount = acl_count; *aclcount = acl_count;
} else { } else {
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zfsvfs), if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb),
aclphys, sizeof (*aclphys))) != 0) aclphys, sizeof (*aclphys))) != 0)
return (error); return (error);
@ -418,7 +418,7 @@ zfs_znode_acl_version(znode_t *zp)
* changed. * changed.
*/ */
if ((error = sa_lookup(zp->z_sa_hdl, if ((error = sa_lookup(zp->z_sa_hdl,
SA_ZPL_ZNODE_ACL(zp->z_zfsvfs), SA_ZPL_ZNODE_ACL(ZTOZSB(zp)),
&acl_phys, sizeof (acl_phys))) == 0) &acl_phys, sizeof (acl_phys))) == 0)
return (acl_phys.z_acl_version); return (acl_phys.z_acl_version);
else { else {
@ -444,7 +444,7 @@ zfs_acl_version(int version)
static int static int
zfs_acl_version_zp(znode_t *zp) zfs_acl_version_zp(znode_t *zp)
{ {
return (zfs_acl_version(zp->z_zfsvfs->z_version)); return (zfs_acl_version(ZTOZSB(zp)->z_version));
} }
zfs_acl_t * zfs_acl_t *
@ -531,7 +531,7 @@ zfs_acl_valid_ace_type(uint_t type, uint_t flags)
} }
static boolean_t static boolean_t
zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) zfs_ace_valid(umode_t obj_mode, zfs_acl_t *aclp, uint16_t type, uint16_t iflags)
{ {
/* /*
* first check type of entry * first check type of entry
@ -554,7 +554,7 @@ zfs_ace_valid(vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags)
* next check inheritance level flags * next check inheritance level flags
*/ */
if (obj_type == VDIR && if (S_ISDIR(obj_mode) &&
(iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE))) (iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_INHERIT_ACE)))
aclp->z_hints |= ZFS_INHERIT_ACE; aclp->z_hints |= ZFS_INHERIT_ACE;
@ -648,7 +648,7 @@ zfs_ace_walk(void *datap, uint64_t cookie, int aclcnt,
* ACE FUIDs will be created later. * ACE FUIDs will be created later.
*/ */
int int
zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp, zfs_copy_ace_2_fuid(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *aclp,
void *datap, zfs_ace_t *z_acl, uint64_t aclcnt, size_t *size, void *datap, zfs_ace_t *z_acl, uint64_t aclcnt, size_t *size,
zfs_fuid_info_t **fuidp, cred_t *cr) zfs_fuid_info_t **fuidp, cred_t *cr)
{ {
@ -666,7 +666,7 @@ zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp,
entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS; entry_type = aceptr->z_hdr.z_flags & ACE_TYPE_FLAGS;
if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP && if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP &&
entry_type != ACE_EVERYONE) { entry_type != ACE_EVERYONE) {
aceptr->z_fuid = zfs_fuid_create(zfsvfs, acep->a_who, aceptr->z_fuid = zfs_fuid_create(zsb, acep->a_who,
cr, (entry_type == 0) ? cr, (entry_type == 0) ?
ZFS_ACE_USER : ZFS_ACE_GROUP, fuidp); ZFS_ACE_USER : ZFS_ACE_GROUP, fuidp);
} }
@ -674,7 +674,7 @@ zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp,
/* /*
* Make sure ACE is valid * Make sure ACE is valid
*/ */
if (zfs_ace_valid(obj_type, aclp, aceptr->z_hdr.z_type, if (zfs_ace_valid(obj_mode, aclp, aceptr->z_hdr.z_type,
aceptr->z_hdr.z_flags) != B_TRUE) aceptr->z_hdr.z_flags) != B_TRUE)
return (EINVAL); return (EINVAL);
@ -710,7 +710,7 @@ zfs_copy_ace_2_fuid(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp,
* Copy ZFS ACEs to fixed size ace_t layout * Copy ZFS ACEs to fixed size ace_t layout
*/ */
static void static void
zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr, zfs_copy_fuid_2_ace(zfs_sb_t *zsb, zfs_acl_t *aclp, cred_t *cr,
void *datap, int filter) void *datap, int filter)
{ {
uint64_t who; uint64_t who;
@ -753,7 +753,7 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr,
if ((entry_type != ACE_OWNER && if ((entry_type != ACE_OWNER &&
entry_type != OWNING_GROUP && entry_type != OWNING_GROUP &&
entry_type != ACE_EVERYONE)) { entry_type != ACE_EVERYONE)) {
acep->a_who = zfs_fuid_map_id(zfsvfs, who, acep->a_who = zfs_fuid_map_id(zsb, who,
cr, (entry_type & ACE_IDENTIFIER_GROUP) ? cr, (entry_type & ACE_IDENTIFIER_GROUP) ?
ZFS_ACE_GROUP : ZFS_ACE_USER); ZFS_ACE_GROUP : ZFS_ACE_USER);
} else { } else {
@ -767,7 +767,7 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr,
} }
static int static int
zfs_copy_ace_2_oldace(vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep, zfs_copy_ace_2_oldace(umode_t obj_mode, zfs_acl_t *aclp, ace_t *acep,
zfs_oldace_t *z_acl, int aclcnt, size_t *size) zfs_oldace_t *z_acl, int aclcnt, size_t *size)
{ {
int i; int i;
@ -781,7 +781,7 @@ zfs_copy_ace_2_oldace(vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep,
/* /*
* Make sure ACE is valid * Make sure ACE is valid
*/ */
if (zfs_ace_valid(obj_type, aclp, aceptr->z_type, if (zfs_ace_valid(obj_mode, aclp, aceptr->z_type,
aceptr->z_flags) != B_TRUE) aceptr->z_flags) != B_TRUE)
return (EINVAL); return (EINVAL);
} }
@ -825,8 +825,8 @@ zfs_acl_xform(znode_t *zp, zfs_acl_t *aclp, cred_t *cr)
newaclnode = zfs_acl_node_alloc(aclp->z_acl_count * newaclnode = zfs_acl_node_alloc(aclp->z_acl_count *
sizeof (zfs_object_ace_t)); sizeof (zfs_object_ace_t));
aclp->z_ops = zfs_acl_fuid_ops; aclp->z_ops = zfs_acl_fuid_ops;
VERIFY(zfs_copy_ace_2_fuid(zp->z_zfsvfs, ZTOV(zp)->v_type, aclp, VERIFY(zfs_copy_ace_2_fuid(ZTOZSB(zp), ZTOI(zp)->i_mode,
oldaclp, newaclnode->z_acldata, aclp->z_acl_count, aclp, oldaclp, newaclnode->z_acldata, aclp->z_acl_count,
&newaclnode->z_size, NULL, cr) == 0); &newaclnode->z_size, NULL, cr) == 0);
newaclnode->z_ace_count = aclp->z_acl_count; newaclnode->z_ace_count = aclp->z_acl_count;
aclp->z_version = ZFS_ACL_VERSION; aclp->z_version = ZFS_ACL_VERSION;
@ -1100,7 +1100,7 @@ zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp,
if (!zp->z_is_sa) { if (!zp->z_is_sa) {
if (znode_acl.z_acl_extern_obj) { if (znode_acl.z_acl_extern_obj) {
error = dmu_read(zp->z_zfsvfs->z_os, error = dmu_read(ZTOZSB(zp)->z_os,
znode_acl.z_acl_extern_obj, 0, aclnode->z_size, znode_acl.z_acl_extern_obj, 0, aclnode->z_size,
aclnode->z_acldata, DMU_READ_PREFETCH); aclnode->z_acldata, DMU_READ_PREFETCH);
} else { } else {
@ -1108,7 +1108,7 @@ zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp,
aclnode->z_size); aclnode->z_size);
} }
} else { } else {
error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_ACES(zp->z_zfsvfs), error = sa_lookup(zp->z_sa_hdl, SA_ZPL_DACL_ACES(ZTOZSB(zp)),
aclnode->z_acldata, aclnode->z_size); aclnode->z_acldata, aclnode->z_size);
} }
@ -1295,7 +1295,7 @@ int
zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
{ {
int error; int error;
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
dmu_object_type_t otype; dmu_object_type_t otype;
zfs_acl_locator_cb_t locate = { 0 }; zfs_acl_locator_cb_t locate = { 0 };
uint64_t mode; uint64_t mode;
@ -1309,11 +1309,11 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
zp->z_uid, zp->z_gid); zp->z_uid, zp->z_gid);
zp->z_mode = mode; zp->z_mode = mode;
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL,
&mode, sizeof (mode)); &mode, sizeof (mode));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
&zp->z_pflags, sizeof (zp->z_pflags)); &zp->z_pflags, sizeof (zp->z_pflags));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
&ctime, sizeof (ctime)); &ctime, sizeof (ctime));
if (zp->z_acl_cached) { if (zp->z_acl_cached) {
@ -1324,11 +1324,11 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
/* /*
* Upgrade needed? * Upgrade needed?
*/ */
if (!zfsvfs->z_use_fuids) { if (!zsb->z_use_fuids) {
otype = DMU_OT_OLDACL; otype = DMU_OT_OLDACL;
} else { } else {
if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) && if ((aclp->z_version == ZFS_ACL_VERSION_INITIAL) &&
(zfsvfs->z_version >= ZPL_VERSION_FUID)) (zsb->z_version >= ZPL_VERSION_FUID))
zfs_acl_xform(zp, aclp, cr); zfs_acl_xform(zp, aclp, cr);
ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID); ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID);
otype = DMU_OT_ACL; otype = DMU_OT_ACL;
@ -1341,9 +1341,9 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
if (zp->z_is_sa) { /* the easy case, just update the ACL attribute */ if (zp->z_is_sa) { /* the easy case, just update the ACL attribute */
locate.cb_aclp = aclp; locate.cb_aclp = aclp;
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_ACES(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_ACES(zsb),
zfs_acl_data_locator, &locate, aclp->z_acl_bytes); zfs_acl_data_locator, &locate, aclp->z_acl_bytes);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_COUNT(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_DACL_COUNT(zsb),
NULL, &aclp->z_acl_count, sizeof (uint64_t)); NULL, &aclp->z_acl_count, sizeof (uint64_t));
} else { /* Painful legacy way */ } else { /* Painful legacy way */
zfs_acl_node_t *aclnode; zfs_acl_node_t *aclnode;
@ -1351,7 +1351,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
zfs_acl_phys_t acl_phys; zfs_acl_phys_t acl_phys;
uint64_t aoid; uint64_t aoid;
if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zfsvfs), if ((error = sa_lookup(zp->z_sa_hdl, SA_ZPL_ZNODE_ACL(zsb),
&acl_phys, sizeof (acl_phys))) != 0) &acl_phys, sizeof (acl_phys))) != 0)
return (error); return (error);
@ -1365,20 +1365,20 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
*/ */
if (aoid && if (aoid &&
aclp->z_version != acl_phys.z_acl_version) { aclp->z_version != acl_phys.z_acl_version) {
error = dmu_object_free(zfsvfs->z_os, aoid, tx); error = dmu_object_free(zsb->z_os, aoid, tx);
if (error) if (error)
return (error); return (error);
aoid = 0; aoid = 0;
} }
if (aoid == 0) { if (aoid == 0) {
aoid = dmu_object_alloc(zfsvfs->z_os, aoid = dmu_object_alloc(zsb->z_os,
otype, aclp->z_acl_bytes, otype, aclp->z_acl_bytes,
otype == DMU_OT_ACL ? otype == DMU_OT_ACL ?
DMU_OT_SYSACL : DMU_OT_NONE, DMU_OT_SYSACL : DMU_OT_NONE,
otype == DMU_OT_ACL ? otype == DMU_OT_ACL ?
DN_MAX_BONUSLEN : 0, tx); DN_MAX_BONUSLEN : 0, tx);
} else { } else {
(void) dmu_object_set_blocksize(zfsvfs->z_os, (void) dmu_object_set_blocksize(zsb->z_os,
aoid, aclp->z_acl_bytes, 0, tx); aoid, aclp->z_acl_bytes, 0, tx);
} }
acl_phys.z_acl_extern_obj = aoid; acl_phys.z_acl_extern_obj = aoid;
@ -1386,7 +1386,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
aclnode = list_next(&aclp->z_acl, aclnode)) { aclnode = list_next(&aclp->z_acl, aclnode)) {
if (aclnode->z_ace_count == 0) if (aclnode->z_ace_count == 0)
continue; continue;
dmu_write(zfsvfs->z_os, aoid, off, dmu_write(zsb->z_os, aoid, off,
aclnode->z_size, aclnode->z_acldata, tx); aclnode->z_size, aclnode->z_acldata, tx);
off += aclnode->z_size; off += aclnode->z_size;
} }
@ -1396,7 +1396,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
* Migrating back embedded? * Migrating back embedded?
*/ */
if (acl_phys.z_acl_extern_obj) { if (acl_phys.z_acl_extern_obj) {
error = dmu_object_free(zfsvfs->z_os, error = dmu_object_free(zsb->z_os,
acl_phys.z_acl_extern_obj, tx); acl_phys.z_acl_extern_obj, tx);
if (error) if (error)
return (error); return (error);
@ -1425,7 +1425,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
} }
acl_phys.z_acl_version = aclp->z_version; acl_phys.z_acl_version = aclp->z_version;
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL,
&acl_phys, sizeof (acl_phys)); &acl_phys, sizeof (acl_phys));
} }
@ -1444,7 +1444,7 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
} }
static void static void
zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp) zfs_acl_chmod(zfs_sb_t *zsb, uint64_t mode, zfs_acl_t *aclp)
{ {
void *acep = NULL; void *acep = NULL;
uint64_t who; uint64_t who;
@ -1516,7 +1516,7 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
* Limit permissions to be no greater than * Limit permissions to be no greater than
* group permissions * group permissions
*/ */
if (zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) { if (zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) {
if (!(mode & S_IRGRP)) if (!(mode & S_IRGRP))
access_mask &= ~ACE_READ_DATA; access_mask &= ~ACE_READ_DATA;
if (!(mode & S_IWGRP)) if (!(mode & S_IWGRP))
@ -1558,7 +1558,7 @@ zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
mutex_enter(&zp->z_lock); mutex_enter(&zp->z_lock);
*aclp = zfs_acl_alloc(zfs_acl_version_zp(zp)); *aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
(*aclp)->z_hints = zp->z_pflags & V4_ACL_WIDE_FLAGS; (*aclp)->z_hints = zp->z_pflags & V4_ACL_WIDE_FLAGS;
zfs_acl_chmod(zp->z_zfsvfs, mode, *aclp); zfs_acl_chmod(ZTOZSB(zp), mode, *aclp);
mutex_exit(&zp->z_lock); mutex_exit(&zp->z_lock);
mutex_exit(&zp->z_acl_lock); mutex_exit(&zp->z_acl_lock);
ASSERT(*aclp); ASSERT(*aclp);
@ -1568,11 +1568,11 @@ zfs_acl_chmod_setattr(znode_t *zp, zfs_acl_t **aclp, uint64_t mode)
* strip off write_owner and write_acl * strip off write_owner and write_acl
*/ */
static void static void
zfs_restricted_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep) zfs_restricted_update(zfs_sb_t *zsb, zfs_acl_t *aclp, void *acep)
{ {
uint32_t mask = aclp->z_ops.ace_mask_get(acep); uint32_t mask = aclp->z_ops.ace_mask_get(acep);
if ((zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) && if ((zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) &&
(aclp->z_ops.ace_type_get(acep) == ALLOW)) { (aclp->z_ops.ace_type_get(acep) == ALLOW)) {
mask &= ~RESTRICTED_CLEAR; mask &= ~RESTRICTED_CLEAR;
aclp->z_ops.ace_mask_set(acep, mask); aclp->z_ops.ace_mask_set(acep, mask);
@ -1583,14 +1583,14 @@ zfs_restricted_update(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep)
* Should ACE be inherited? * Should ACE be inherited?
*/ */
static int static int
zfs_ace_can_use(vtype_t vtype, uint16_t acep_flags) zfs_ace_can_use(umode_t obj_mode, uint16_t acep_flags)
{ {
int iflags = (acep_flags & 0xf); int iflags = (acep_flags & 0xf);
if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE)) if (S_ISDIR(obj_mode) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
return (1); return (1);
else if (iflags & ACE_FILE_INHERIT_ACE) else if (iflags & ACE_FILE_INHERIT_ACE)
return (!((vtype == VDIR) && return (!(S_ISDIR(obj_mode) &&
(iflags & ACE_NO_PROPAGATE_INHERIT_ACE))); (iflags & ACE_NO_PROPAGATE_INHERIT_ACE)));
return (0); return (0);
} }
@ -1599,7 +1599,7 @@ zfs_ace_can_use(vtype_t vtype, uint16_t acep_flags)
* inherit inheritable ACEs from parent * inherit inheritable ACEs from parent
*/ */
static zfs_acl_t * static zfs_acl_t *
zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp, zfs_acl_inherit(zfs_sb_t *zsb, umode_t obj_mode, zfs_acl_t *paclp,
uint64_t mode, boolean_t *need_chmod) uint64_t mode, boolean_t *need_chmod)
{ {
void *pacep; void *pacep;
@ -1612,21 +1612,21 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
size_t ace_size; size_t ace_size;
void *data1, *data2; void *data1, *data2;
size_t data1sz, data2sz; size_t data1sz, data2sz;
boolean_t vdir = vtype == VDIR; boolean_t vdir = S_ISDIR(obj_mode);
boolean_t vreg = vtype == VREG; boolean_t vreg = S_ISREG(obj_mode);
boolean_t passthrough, passthrough_x, noallow; boolean_t passthrough, passthrough_x, noallow;
passthrough_x = passthrough_x =
zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X; zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X;
passthrough = passthrough_x || passthrough = passthrough_x ||
zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH; zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH;
noallow = noallow =
zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW; zsb->z_acl_inherit == ZFS_ACL_NOALLOW;
*need_chmod = B_TRUE; *need_chmod = B_TRUE;
pacep = NULL; pacep = NULL;
aclp = zfs_acl_alloc(paclp->z_version); aclp = zfs_acl_alloc(paclp->z_version);
if (zfsvfs->z_acl_inherit == ZFS_ACL_DISCARD || vtype == VLNK) if (zsb->z_acl_inherit == ZFS_ACL_DISCARD || S_ISLNK(obj_mode))
return (aclp); return (aclp);
while ((pacep = zfs_acl_next_ace(paclp, pacep, &who, while ((pacep = zfs_acl_next_ace(paclp, pacep, &who,
&access_mask, &iflags, &type))) { &access_mask, &iflags, &type))) {
@ -1642,7 +1642,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
ace_size = aclp->z_ops.ace_size(pacep); ace_size = aclp->z_ops.ace_size(pacep);
if (!zfs_ace_can_use(vtype, iflags)) if (!zfs_ace_can_use(obj_mode, iflags))
continue; continue;
/* /*
@ -1690,7 +1690,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
newflags &= ~ALL_INHERIT; newflags &= ~ALL_INHERIT;
aclp->z_ops.ace_flags_set(acep, aclp->z_ops.ace_flags_set(acep,
newflags|ACE_INHERITED_ACE); newflags|ACE_INHERITED_ACE);
zfs_restricted_update(zfsvfs, aclp, acep); zfs_restricted_update(zsb, aclp, acep);
continue; continue;
} }
@ -1723,7 +1723,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids) vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids)
{ {
int error; int error;
zfsvfs_t *zfsvfs = dzp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(dzp);
zfs_acl_t *paclp; zfs_acl_t *paclp;
#ifdef HAVE_KSID #ifdef HAVE_KSID
gid_t gid; gid_t gid;
@ -1732,11 +1732,11 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
boolean_t inherited = B_FALSE; boolean_t inherited = B_FALSE;
bzero(acl_ids, sizeof (zfs_acl_ids_t)); bzero(acl_ids, sizeof (zfs_acl_ids_t));
acl_ids->z_mode = MAKEIMODE(vap->va_type, vap->va_mode); acl_ids->z_mode = vap->va_mode;
if (vsecp) if (vsecp)
if ((error = zfs_vsec_2_aclp(zfsvfs, vap->va_type, vsecp, cr, if ((error = zfs_vsec_2_aclp(zsb, vap->va_mode, vsecp,
&acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0) cr, &acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0)
return (error); return (error);
acl_ids->z_fuid = vap->va_uid; acl_ids->z_fuid = vap->va_uid;
@ -1745,21 +1745,19 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
/* /*
* Determine uid and gid. * Determine uid and gid.
*/ */
if ((flag & IS_ROOT_NODE) || zfsvfs->z_replay || if ((flag & IS_ROOT_NODE) || zsb->z_replay ||
((flag & IS_XATTR) && (vap->va_type == VDIR))) { ((flag & IS_XATTR) && (S_ISDIR(vap->va_mode)))) {
acl_ids->z_fuid = zfs_fuid_create(zfsvfs, acl_ids->z_fuid = zfs_fuid_create(zsb, (uint64_t)vap->va_uid,
(uint64_t)vap->va_uid, cr, cr, ZFS_OWNER, &acl_ids->z_fuidp);
ZFS_OWNER, &acl_ids->z_fuidp); acl_ids->z_fgid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid,
acl_ids->z_fgid = zfs_fuid_create(zfsvfs, cr, ZFS_GROUP, &acl_ids->z_fuidp);
(uint64_t)vap->va_gid, cr,
ZFS_GROUP, &acl_ids->z_fuidp);
gid = vap->va_gid; gid = vap->va_gid;
} else { } else {
acl_ids->z_fuid = zfs_fuid_create_cred(zfsvfs, ZFS_OWNER, acl_ids->z_fuid = zfs_fuid_create_cred(zsb, ZFS_OWNER,
cr, &acl_ids->z_fuidp); cr, &acl_ids->z_fuidp);
acl_ids->z_fgid = 0; acl_ids->z_fgid = 0;
if (vap->va_mask & AT_GID) { if (vap->va_mask & AT_GID) {
acl_ids->z_fgid = zfs_fuid_create(zfsvfs, acl_ids->z_fgid = zfs_fuid_create(zsb,
(uint64_t)vap->va_gid, (uint64_t)vap->va_gid,
cr, ZFS_GROUP, &acl_ids->z_fuidp); cr, ZFS_GROUP, &acl_ids->z_fuidp);
gid = vap->va_gid; gid = vap->va_gid;
@ -1774,13 +1772,13 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
uint32_t rid; uint32_t rid;
acl_ids->z_fgid = dzp->z_gid; acl_ids->z_fgid = dzp->z_gid;
gid = zfs_fuid_map_id(zfsvfs, acl_ids->z_fgid, gid = zfs_fuid_map_id(zsb, acl_ids->z_fgid,
cr, ZFS_GROUP); cr, ZFS_GROUP);
if (zfsvfs->z_use_fuids && if (zsb->z_use_fuids &&
IS_EPHEMERAL(acl_ids->z_fgid)) { IS_EPHEMERAL(acl_ids->z_fgid)) {
domain = zfs_fuid_idx_domain( domain = zfs_fuid_idx_domain(
&zfsvfs->z_fuid_idx, &zsb->z_fuid_idx,
FUID_INDEX(acl_ids->z_fgid)); FUID_INDEX(acl_ids->z_fgid));
rid = FUID_RID(acl_ids->z_fgid); rid = FUID_RID(acl_ids->z_fgid);
zfs_fuid_node_add(&acl_ids->z_fuidp, zfs_fuid_node_add(&acl_ids->z_fuidp,
@ -1789,7 +1787,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
acl_ids->z_fgid, ZFS_GROUP); acl_ids->z_fgid, ZFS_GROUP);
} }
} else { } else {
acl_ids->z_fgid = zfs_fuid_create_cred(zfsvfs, acl_ids->z_fgid = zfs_fuid_create_cred(zsb,
ZFS_GROUP, cr, &acl_ids->z_fuidp); ZFS_GROUP, cr, &acl_ids->z_fuidp);
gid = crgetgid(cr); gid = crgetgid(cr);
} }
@ -1805,7 +1803,7 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
*/ */
if (!(flag & IS_ROOT_NODE) && (dzp->z_mode & S_ISGID) && if (!(flag & IS_ROOT_NODE) && (dzp->z_mode & S_ISGID) &&
(vap->va_type == VDIR)) { (S_ISDIR(vap->va_mode))) {
acl_ids->z_mode |= S_ISGID; acl_ids->z_mode |= S_ISGID;
} else { } else {
if ((acl_ids->z_mode & S_ISGID) && if ((acl_ids->z_mode & S_ISGID) &&
@ -1816,13 +1814,13 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
if (acl_ids->z_aclp == NULL) { if (acl_ids->z_aclp == NULL) {
mutex_enter(&dzp->z_acl_lock); mutex_enter(&dzp->z_acl_lock);
mutex_enter(&dzp->z_lock); mutex_enter(&dzp->z_lock);
if (!(flag & IS_ROOT_NODE) && (ZTOV(dzp)->v_type == VDIR && if (!(flag & IS_ROOT_NODE) && (S_ISDIR(ZTOI(dzp)->i_mode) &&
(dzp->z_pflags & ZFS_INHERIT_ACE)) && (dzp->z_pflags & ZFS_INHERIT_ACE)) &&
!(dzp->z_pflags & ZFS_XATTR)) { !(dzp->z_pflags & ZFS_XATTR)) {
VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE, VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE,
&paclp, B_FALSE)); &paclp, B_FALSE));
acl_ids->z_aclp = zfs_acl_inherit(zfsvfs, acl_ids->z_aclp = zfs_acl_inherit(zsb,
vap->va_type, paclp, acl_ids->z_mode, &need_chmod); vap->va_mode, paclp, acl_ids->z_mode, &need_chmod);
inherited = B_TRUE; inherited = B_TRUE;
} else { } else {
acl_ids->z_aclp = acl_ids->z_aclp =
@ -1832,9 +1830,9 @@ zfs_acl_ids_create(znode_t *dzp, int flag, vattr_t *vap, cred_t *cr,
mutex_exit(&dzp->z_lock); mutex_exit(&dzp->z_lock);
mutex_exit(&dzp->z_acl_lock); mutex_exit(&dzp->z_acl_lock);
if (need_chmod) { if (need_chmod) {
acl_ids->z_aclp->z_hints |= (vap->va_type == VDIR) ? acl_ids->z_aclp->z_hints |= S_ISDIR(vap->va_mode) ?
ZFS_ACL_AUTO_INHERIT : 0; ZFS_ACL_AUTO_INHERIT : 0;
zfs_acl_chmod(zfsvfs, acl_ids->z_mode, acl_ids->z_aclp); zfs_acl_chmod(zsb, acl_ids->z_mode, acl_ids->z_aclp);
} }
} }
@ -1864,10 +1862,10 @@ zfs_acl_ids_free(zfs_acl_ids_t *acl_ids)
} }
boolean_t boolean_t
zfs_acl_ids_overquota(zfsvfs_t *zfsvfs, zfs_acl_ids_t *acl_ids) zfs_acl_ids_overquota(zfs_sb_t *zsb, zfs_acl_ids_t *acl_ids)
{ {
return (zfs_fuid_overquota(zfsvfs, B_FALSE, acl_ids->z_fuid) || return (zfs_fuid_overquota(zsb, B_FALSE, acl_ids->z_fuid) ||
zfs_fuid_overquota(zfsvfs, B_TRUE, acl_ids->z_fgid)); zfs_fuid_overquota(zsb, B_TRUE, acl_ids->z_fgid));
} }
/* /*
@ -1939,7 +1937,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
vsecp->vsa_aclentsz = aclsz; vsecp->vsa_aclentsz = aclsz;
if (aclp->z_version == ZFS_ACL_VERSION_FUID) if (aclp->z_version == ZFS_ACL_VERSION_FUID)
zfs_copy_fuid_2_ace(zp->z_zfsvfs, aclp, cr, zfs_copy_fuid_2_ace(ZTOZSB(zp), aclp, cr,
vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES)); vsecp->vsa_aclentp, !(mask & VSA_ACE_ALLTYPES));
else { else {
zfs_acl_node_t *aclnode; zfs_acl_node_t *aclnode;
@ -1971,7 +1969,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
} }
int int
zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_vsec_2_aclp(zfs_sb_t *zsb, umode_t obj_mode,
vsecattr_t *vsecp, cred_t *cr, zfs_fuid_info_t **fuidp, zfs_acl_t **zaclp) vsecattr_t *vsecp, cred_t *cr, zfs_fuid_info_t **fuidp, zfs_acl_t **zaclp)
{ {
zfs_acl_t *aclp; zfs_acl_t *aclp;
@ -1982,12 +1980,12 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
if (vsecp->vsa_aclcnt > MAX_ACL_ENTRIES || vsecp->vsa_aclcnt <= 0) if (vsecp->vsa_aclcnt > MAX_ACL_ENTRIES || vsecp->vsa_aclcnt <= 0)
return (EINVAL); return (EINVAL);
aclp = zfs_acl_alloc(zfs_acl_version(zfsvfs->z_version)); aclp = zfs_acl_alloc(zfs_acl_version(zsb->z_version));
aclp->z_hints = 0; aclp->z_hints = 0;
aclnode = zfs_acl_node_alloc(aclcnt * sizeof (zfs_object_ace_t)); aclnode = zfs_acl_node_alloc(aclcnt * sizeof (zfs_object_ace_t));
if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) { if (aclp->z_version == ZFS_ACL_VERSION_INITIAL) {
if ((error = zfs_copy_ace_2_oldace(obj_type, aclp, if ((error = zfs_copy_ace_2_oldace(obj_mode, aclp,
(ace_t *)vsecp->vsa_aclentp, aclnode->z_acldata, (ace_t *)vsecp->vsa_aclentp, aclnode->z_acldata,
aclcnt, &aclnode->z_size)) != 0) { aclcnt, &aclnode->z_size)) != 0) {
zfs_acl_free(aclp); zfs_acl_free(aclp);
@ -1995,7 +1993,7 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
return (error); return (error);
} }
} else { } else {
if ((error = zfs_copy_ace_2_fuid(zfsvfs, obj_type, aclp, if ((error = zfs_copy_ace_2_fuid(zsb, obj_mode, aclp,
vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt, vsecp->vsa_aclentp, aclnode->z_acldata, aclcnt,
&aclnode->z_size, fuidp, cr)) != 0) { &aclnode->z_size, fuidp, cr)) != 0) {
zfs_acl_free(aclp); zfs_acl_free(aclp);
@ -2031,8 +2029,8 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
int int
zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
zilog_t *zilog = zfsvfs->z_log; zilog_t *zilog = zsb->z_log;
ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT); ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
dmu_tx_t *tx; dmu_tx_t *tx;
int error; int error;
@ -2050,7 +2048,7 @@ zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr))) if ((error = zfs_zaccess(zp, ACE_WRITE_ACL, 0, skipaclchk, cr)))
return (error); return (error);
error = zfs_vsec_2_aclp(zfsvfs, ZTOV(zp)->v_type, vsecp, cr, &fuidp, error = zfs_vsec_2_aclp(zsb, ZTOI(zp)->i_mode, vsecp, cr, &fuidp,
&aclp); &aclp);
if (error) if (error)
return (error); return (error);
@ -2067,13 +2065,13 @@ top:
mutex_enter(&zp->z_acl_lock); mutex_enter(&zp->z_acl_lock);
mutex_enter(&zp->z_lock); mutex_enter(&zp->z_lock);
tx = dmu_tx_create(zfsvfs->z_os); tx = dmu_tx_create(zsb->z_os);
dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
fuid_dirtied = zfsvfs->z_fuid_dirty; fuid_dirtied = zsb->z_fuid_dirty;
if (fuid_dirtied) if (fuid_dirtied)
zfs_fuid_txhold(zfsvfs, tx); zfs_fuid_txhold(zsb, tx);
/* /*
* If old version and ACL won't fit in bonus and we aren't * If old version and ACL won't fit in bonus and we aren't
@ -2081,7 +2079,7 @@ top:
*/ */
if ((acl_obj = zfs_external_acl(zp)) != 0) { if ((acl_obj = zfs_external_acl(zp)) != 0) {
if (zfsvfs->z_version >= ZPL_VERSION_FUID && if (zsb->z_version >= ZPL_VERSION_FUID &&
zfs_znode_acl_version(zp) <= ZFS_ACL_VERSION_INITIAL) { zfs_znode_acl_version(zp) <= ZFS_ACL_VERSION_INITIAL) {
dmu_tx_hold_free(tx, acl_obj, 0, dmu_tx_hold_free(tx, acl_obj, 0,
DMU_OBJECT_END); DMU_OBJECT_END);
@ -2116,7 +2114,7 @@ top:
zp->z_acl_cached = aclp; zp->z_acl_cached = aclp;
if (fuid_dirtied) if (fuid_dirtied)
zfs_fuid_sync(zfsvfs, tx); zfs_fuid_sync(zsb, tx);
zfs_log_acl(zilog, tx, zp, vsecp, fuidp); zfs_log_acl(zilog, tx, zp, vsecp, fuidp);
@ -2139,9 +2137,9 @@ static int
zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode) zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
{ {
if ((v4_mode & WRITE_MASK) && if ((v4_mode & WRITE_MASK) &&
(zp->z_zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) && (ZTOZSB(zp)->z_vfs->mnt_flags & MNT_READONLY) &&
(!IS_DEVVP(ZTOV(zp)) || (!S_ISDEV(ZTOI(zp)->i_mode) ||
(IS_DEVVP(ZTOV(zp)) && (v4_mode & WRITE_MASK_ATTRS)))) { (S_ISDEV(ZTOI(zp)->i_mode) && (v4_mode & WRITE_MASK_ATTRS)))) {
return (EROFS); return (EROFS);
} }
@ -2149,9 +2147,9 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
* Only check for READONLY on non-directories. * Only check for READONLY on non-directories.
*/ */
if ((v4_mode & WRITE_MASK_DATA) && if ((v4_mode & WRITE_MASK_DATA) &&
(((ZTOV(zp)->v_type != VDIR) && ((!S_ISDIR(ZTOI(zp)->i_mode) &&
(zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) || (zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) ||
(ZTOV(zp)->v_type == VDIR && (S_ISDIR(ZTOI(zp)->i_mode) &&
(zp->z_pflags & ZFS_IMMUTABLE)))) { (zp->z_pflags & ZFS_IMMUTABLE)))) {
return (EPERM); return (EPERM);
} }
@ -2198,7 +2196,7 @@ static int
zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode, zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
boolean_t anyaccess, cred_t *cr) boolean_t anyaccess, cred_t *cr)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
zfs_acl_t *aclp; zfs_acl_t *aclp;
int error; int error;
uid_t uid = crgetuid(cr); uid_t uid = crgetuid(cr);
@ -2231,7 +2229,8 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
if (!zfs_acl_valid_ace_type(type, iflags)) if (!zfs_acl_valid_ace_type(type, iflags))
continue; continue;
if (ZTOV(zp)->v_type == VDIR && (iflags & ACE_INHERIT_ONLY_ACE)) if (S_ISDIR(ZTOI(zp)->i_mode) &&
(iflags & ACE_INHERIT_ONLY_ACE))
continue; continue;
/* Skip ACE if it does not affect any AoI */ /* Skip ACE if it does not affect any AoI */
@ -2252,7 +2251,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
who = gowner; who = gowner;
/*FALLTHROUGH*/ /*FALLTHROUGH*/
case ACE_IDENTIFIER_GROUP: case ACE_IDENTIFIER_GROUP:
checkit = zfs_groupmember(zfsvfs, who, cr); checkit = zfs_groupmember(zsb, who, cr);
break; break;
case ACE_EVERYONE: case ACE_EVERYONE:
checkit = B_TRUE; checkit = B_TRUE;
@ -2263,7 +2262,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
if (entry_type == 0) { if (entry_type == 0) {
uid_t newid; uid_t newid;
newid = zfs_fuid_map_id(zfsvfs, who, cr, newid = zfs_fuid_map_id(zsb, who, cr,
ZFS_ACE_USER); ZFS_ACE_USER);
if (newid != IDMAP_WK_CREATOR_OWNER_UID && if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
uid == newid) uid == newid)
@ -2325,8 +2324,8 @@ zfs_has_access(znode_t *zp, cred_t *cr)
if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) { if (zfs_zaccess_aces_check(zp, &have, B_TRUE, cr) != 0) {
uid_t owner; uid_t owner;
owner = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER); owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
return (secpolicy_vnode_any_access(cr, ZTOV(zp), owner) == 0); return (secpolicy_vnode_any_access(cr, ZTOI(zp), owner) == 0);
} }
return (B_TRUE); return (B_TRUE);
} }
@ -2335,7 +2334,7 @@ static int
zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr) boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
int err; int err;
*working_mode = v4_mode; *working_mode = v4_mode;
@ -2344,7 +2343,7 @@ zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
/* /*
* Short circuit empty requests * Short circuit empty requests
*/ */
if (v4_mode == 0 || zfsvfs->z_replay) { if (v4_mode == 0 || zsb->z_replay) {
*working_mode = 0; *working_mode = 0;
return (0); return (0);
} }
@ -2391,7 +2390,7 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
return (EACCES); return (EACCES);
is_attr = ((zdp->z_pflags & ZFS_XATTR) && is_attr = ((zdp->z_pflags & ZFS_XATTR) &&
(ZTOV(zdp)->v_type == VDIR)); (S_ISDIR(ZTOI(zdp)->i_mode)));
if (is_attr) if (is_attr)
goto slow; goto slow;
@ -2439,9 +2438,9 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
slow: slow:
DTRACE_PROBE(zfs__fastpath__execute__access__miss); DTRACE_PROBE(zfs__fastpath__execute__access__miss);
ZFS_ENTER(zdp->z_zfsvfs); ZFS_ENTER(ZTOZSB(zdp));
error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr); error = zfs_zaccess(zdp, ACE_EXECUTE, 0, B_FALSE, cr);
ZFS_EXIT(zdp->z_zfsvfs); ZFS_EXIT(ZTOZSB(zdp));
return (error); return (error);
} }
@ -2462,7 +2461,7 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
mode_t needed_bits; mode_t needed_bits;
uid_t owner; uid_t owner;
is_attr = ((zp->z_pflags & ZFS_XATTR) && (ZTOV(zp)->v_type == VDIR)); is_attr = ((zp->z_pflags & ZFS_XATTR) && S_ISDIR(ZTOI(zp)->i_mode));
/* /*
* If attribute then validate against base file * If attribute then validate against base file
@ -2471,11 +2470,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
uint64_t parent; uint64_t parent;
if ((error = sa_lookup(zp->z_sa_hdl, if ((error = sa_lookup(zp->z_sa_hdl,
SA_ZPL_PARENT(zp->z_zfsvfs), &parent, SA_ZPL_PARENT(ZTOZSB(zp)), &parent,
sizeof (parent))) != 0) sizeof (parent))) != 0)
return (error); return (error);
if ((error = zfs_zget(zp->z_zfsvfs, if ((error = zfs_zget(ZTOZSB(zp),
parent, &xzp)) != 0) { parent, &xzp)) != 0) {
return (error); return (error);
} }
@ -2497,11 +2496,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
} }
} }
owner = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER); owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
/* /*
* Map the bits required to the standard vnode flags VREAD|VWRITE|VEXEC * Map the bits required to the standard inode flags
* in needed_bits. Map the bits mapped by working_mode (currently * S_IRUSR|S_IWUSR|S_IXUSR in the needed_bits. Map the bits
* missing) in missing_bits. * mapped by working_mode (currently missing) in missing_bits.
* Call secpolicy_vnode_access2() with (needed_bits & ~checkmode), * Call secpolicy_vnode_access2() with (needed_bits & ~checkmode),
* needed_bits. * needed_bits.
*/ */
@ -2514,24 +2513,24 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS| if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS|
ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE)) ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE))
needed_bits |= VREAD; needed_bits |= S_IRUSR;
if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS| if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE)) ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
needed_bits |= VWRITE; needed_bits |= S_IWUSR;
if (working_mode & ACE_EXECUTE) if (working_mode & ACE_EXECUTE)
needed_bits |= VEXEC; needed_bits |= S_IXUSR;
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)
VN_RELE(ZTOV(xzp)); iput(ZTOI(xzp));
return (secpolicy_vnode_access2(cr, ZTOV(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)
VN_RELE(ZTOV(xzp)); iput(ZTOI(xzp));
return (error); return (error);
} }
@ -2556,14 +2555,14 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS| if (working_mode & (ACE_READ_DATA|ACE_READ_NAMED_ATTRS|
ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE)) ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE))
checkmode |= VREAD; checkmode |= S_IRUSR;
if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS| if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE)) ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
checkmode |= VWRITE; checkmode |= S_IWUSR;
if (working_mode & ACE_EXECUTE) if (working_mode & ACE_EXECUTE)
checkmode |= VEXEC; checkmode |= S_IXUSR;
error = secpolicy_vnode_access2(cr, ZTOV(check_zp), owner, error = secpolicy_vnode_access2(cr, ZTOI(check_zp), owner,
needed_bits & ~checkmode, needed_bits); needed_bits & ~checkmode, needed_bits);
if (error == 0 && (working_mode & ACE_WRITE_OWNER)) if (error == 0 && (working_mode & ACE_WRITE_OWNER))
@ -2588,19 +2587,19 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
} }
} }
} else if (error == 0) { } else if (error == 0) {
error = secpolicy_vnode_access2(cr, ZTOV(zp), owner, error = secpolicy_vnode_access2(cr, ZTOI(zp), owner,
needed_bits, needed_bits); needed_bits, needed_bits);
} }
if (is_attr) if (is_attr)
VN_RELE(ZTOV(xzp)); iput(ZTOI(xzp));
return (error); return (error);
} }
/* /*
* Translate traditional unix VREAD/VWRITE/VEXEC mode into * Translate traditional unix S_IRUSR/S_IWUSR/S_IXUSR mode into
* native ACL format and call zfs_zaccess() * native ACL format and call zfs_zaccess()
*/ */
int int
@ -2627,10 +2626,10 @@ zfs_delete_final_check(znode_t *zp, znode_t *dzp,
int error; int error;
uid_t downer; uid_t downer;
downer = zfs_fuid_map_id(dzp->z_zfsvfs, dzp->z_uid, cr, ZFS_OWNER); downer = zfs_fuid_map_id(ZTOZSB(dzp), dzp->z_uid, cr, ZFS_OWNER);
error = secpolicy_vnode_access2(cr, ZTOV(dzp), error = secpolicy_vnode_access2(cr, ZTOI(dzp),
downer, available_perms, VWRITE|VEXEC); downer, available_perms, S_IWUSR|S_IXUSR);
if (error == 0) if (error == 0)
error = zfs_sticky_remove_access(dzp, zp, cr); error = zfs_sticky_remove_access(dzp, zp, cr);
@ -2750,8 +2749,8 @@ zfs_zaccess_delete(znode_t *dzp, znode_t *zp, cred_t *cr)
* Fourth row * Fourth row
*/ */
available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : VWRITE; available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : S_IWUSR;
available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : VEXEC; available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : S_IXUSR;
return (zfs_delete_final_check(zp, dzp, available_perms, cr)); return (zfs_delete_final_check(zp, dzp, available_perms, cr));
@ -2767,7 +2766,7 @@ zfs_zaccess_rename(znode_t *sdzp, znode_t *szp, znode_t *tdzp,
if (szp->z_pflags & ZFS_AV_QUARANTINED) if (szp->z_pflags & ZFS_AV_QUARANTINED)
return (EACCES); return (EACCES);
add_perm = (ZTOV(szp)->v_type == VDIR) ? add_perm = S_ISDIR(ZTOI(szp)->i_mode) ?
ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE; ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE;
/* /*

View File

@ -22,7 +22,6 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/ */
#ifdef HAVE_ZPL
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
@ -62,12 +61,12 @@
* of names after deciding which is the appropriate lookup interface. * of names after deciding which is the appropriate lookup interface.
*/ */
static int static int
zfs_match_find(zfsvfs_t *zfsvfs, znode_t *dzp, char *name, boolean_t exact, zfs_match_find(zfs_sb_t *zsb, znode_t *dzp, char *name, boolean_t exact,
boolean_t update, int *deflags, pathname_t *rpnp, uint64_t *zoid) boolean_t update, int *deflags, pathname_t *rpnp, uint64_t *zoid)
{ {
int error; int error;
if (zfsvfs->z_norm) { if (zsb->z_norm) {
matchtype_t mt = MT_FIRST; matchtype_t mt = MT_FIRST;
boolean_t conflict = B_FALSE; boolean_t conflict = B_FALSE;
size_t bufsz = 0; size_t bufsz = 0;
@ -83,17 +82,19 @@ zfs_match_find(zfsvfs_t *zfsvfs, znode_t *dzp, char *name, boolean_t exact,
* In the non-mixed case we only expect there would ever * In the non-mixed case we only expect there would ever
* be one match, but we need to use the normalizing lookup. * be one match, but we need to use the normalizing lookup.
*/ */
error = zap_lookup_norm(zfsvfs->z_os, dzp->z_id, name, 8, 1, error = zap_lookup_norm(zsb->z_os, dzp->z_id, name, 8, 1,
zoid, mt, buf, bufsz, &conflict); zoid, mt, buf, bufsz, &conflict);
if (!error && deflags) if (!error && deflags)
*deflags = conflict ? ED_CASE_CONFLICT : 0; *deflags = conflict ? ED_CASE_CONFLICT : 0;
} else { } else {
error = zap_lookup(zfsvfs->z_os, dzp->z_id, name, 8, 1, zoid); error = zap_lookup(zsb->z_os, dzp->z_id, name, 8, 1, zoid);
} }
*zoid = ZFS_DIRENT_OBJ(*zoid); *zoid = ZFS_DIRENT_OBJ(*zoid);
#ifdef HAVE_DNLC
if (error == ENOENT && update) if (error == ENOENT && update)
dnlc_update(ZTOV(dzp), name, DNLC_NO_VNODE); dnlc_update(ZTOI(dzp), name, DNLC_NO_VNODE);
#endif /* HAVE_DNLC */
return (error); return (error);
} }
@ -137,12 +138,14 @@ int
zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp, zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
int flag, int *direntflags, pathname_t *realpnp) int flag, int *direntflags, pathname_t *realpnp)
{ {
zfsvfs_t *zfsvfs = dzp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(dzp);
zfs_dirlock_t *dl; zfs_dirlock_t *dl;
boolean_t update; boolean_t update;
boolean_t exact; boolean_t exact;
uint64_t zoid; uint64_t zoid;
#ifdef HAVE_DNLC
vnode_t *vp = NULL; vnode_t *vp = NULL;
#endif /* HAVE_DNLC */
int error = 0; int error = 0;
int cmpflags; int cmpflags;
@ -160,7 +163,7 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
/* /*
* Case sensitivity and normalization preferences are set when * Case sensitivity and normalization preferences are set when
* the file system is created. These are stored in the * the file system is created. These are stored in the
* zfsvfs->z_case and zfsvfs->z_norm fields. These choices * zsb->z_case and zsb->z_norm fields. These choices
* affect what vnodes can be cached in the DNLC, how we * affect what vnodes can be cached in the DNLC, how we
* perform zap lookups, and the "width" of our dirlocks. * perform zap lookups, and the "width" of our dirlocks.
* *
@ -180,8 +183,8 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
* access. * access.
*/ */
exact = exact =
((zfsvfs->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) || ((zsb->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) ||
((zfsvfs->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK)); ((zsb->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK));
/* /*
* Only look in or update the DNLC if we are looking for the * Only look in or update the DNLC if we are looking for the
@ -193,9 +196,9 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
* Maybe can add TO-UPPERed version of name to dnlc in ci-only * Maybe can add TO-UPPERed version of name to dnlc in ci-only
* case for performance improvement? * case for performance improvement?
*/ */
update = !zfsvfs->z_norm || update = !zsb->z_norm ||
((zfsvfs->z_case == ZFS_CASE_MIXED) && ((zsb->z_case == ZFS_CASE_MIXED) &&
!(zfsvfs->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK)); !(zsb->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK));
/* /*
* ZRENAMING indicates we are in a situation where we should * ZRENAMING indicates we are in a situation where we should
@ -208,7 +211,7 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
if (flag & ZRENAMING) if (flag & ZRENAMING)
cmpflags = 0; cmpflags = 0;
else else
cmpflags = zfsvfs->z_norm; cmpflags = zsb->z_norm;
/* /*
* Wait until there are no locks on this name. * Wait until there are no locks on this name.
@ -288,29 +291,34 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
* See if there's an object by this name; if so, put a hold on it. * See if there's an object by this name; if so, put a hold on it.
*/ */
if (flag & ZXATTR) { if (flag & ZXATTR) {
error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &zoid, error = sa_lookup(dzp->z_sa_hdl, SA_ZPL_XATTR(zsb), &zoid,
sizeof (zoid)); sizeof (zoid));
if (error == 0) if (error == 0)
error = (zoid == 0 ? ENOENT : 0); error = (zoid == 0 ? ENOENT : 0);
} else { } else {
#ifdef HAVE_DNLC
if (update) if (update)
vp = dnlc_lookup(ZTOV(dzp), name); vp = dnlc_lookup(ZTOI(dzp), name);
if (vp == DNLC_NO_VNODE) { if (vp == DNLC_NO_VNODE) {
VN_RELE(vp); iput(vp);
error = ENOENT; error = ENOENT;
} else if (vp) { } else if (vp) {
if (flag & ZNEW) { if (flag & ZNEW) {
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
VN_RELE(vp); iput(vp);
return (EEXIST); return (EEXIST);
} }
*dlpp = dl; *dlpp = dl;
*zpp = VTOZ(vp); *zpp = VTOZ(vp);
return (0); return (0);
} else { } else {
error = zfs_match_find(zfsvfs, dzp, name, exact, error = zfs_match_find(zsb, dzp, name, exact,
update, direntflags, realpnp, &zoid); update, direntflags, realpnp, &zoid);
} }
#else
error = zfs_match_find(zsb, dzp, name, exact,
update, direntflags, realpnp, &zoid);
#endif /* HAVE_DNLC */
} }
if (error) { if (error) {
if (error != ENOENT || (flag & ZEXISTS)) { if (error != ENOENT || (flag & ZEXISTS)) {
@ -322,13 +330,15 @@ zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
return (EEXIST); return (EEXIST);
} }
error = zfs_zget(zfsvfs, zoid, zpp); error = zfs_zget(zsb, zoid, zpp);
if (error) { if (error) {
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
return (error); return (error);
} }
#ifdef HAVE_DNLC
if (!(flag & ZXATTR) && update) if (!(flag & ZXATTR) && update)
dnlc_update(ZTOV(dzp), name, ZTOV(*zpp)); dnlc_update(ZTOI(dzp), name, ZTOI(*zpp));
#endif /* HAVE_DNLC */
} }
*dlpp = dl; *dlpp = dl;
@ -377,7 +387,7 @@ zfs_dirent_unlock(zfs_dirlock_t *dl)
* special pseudo-directory. * special pseudo-directory.
*/ */
int int
zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags, zfs_dirlook(znode_t *dzp, char *name, struct inode **ipp, int flags,
int *deflg, pathname_t *rpnp) int *deflg, pathname_t *rpnp)
{ {
zfs_dirlock_t *dl; zfs_dirlock_t *dl;
@ -386,31 +396,35 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags,
uint64_t parent; uint64_t parent;
if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) { if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) {
*vpp = ZTOV(dzp); *ipp = ZTOI(dzp);
VN_HOLD(*vpp); igrab(*ipp);
} else if (name[0] == '.' && name[1] == '.' && name[2] == 0) { } else if (name[0] == '.' && name[1] == '.' && name[2] == 0) {
zfsvfs_t *zfsvfs = dzp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(dzp);
/* /*
* If we are a snapshot mounted under .zfs, return * If we are a snapshot mounted under .zfs, return
* the vp for the snapshot directory. * the vp for the snapshot directory.
*/ */
if ((error = sa_lookup(dzp->z_sa_hdl, if ((error = sa_lookup(dzp->z_sa_hdl,
SA_ZPL_PARENT(zfsvfs), &parent, sizeof (parent))) != 0) SA_ZPL_PARENT(zsb), &parent, sizeof (parent))) != 0)
return (error); return (error);
if (parent == dzp->z_id && zfsvfs->z_parent != zfsvfs) { #ifdef HAVE_SNAPSHOT
error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir, if (parent == dzp->z_id && zsb->z_parent != zsb) {
"snapshot", vpp, NULL, 0, NULL, kcred, error = zfsctl_root_lookup(zsb->z_parent->z_ctldir,
"snapshot", ipp, NULL, 0, NULL, kcred,
NULL, NULL, NULL); NULL, NULL, NULL);
return (error); return (error);
} }
#endif /* HAVE_SNAPSHOT */
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(zsb, parent, &zp);
if (error == 0) if (error == 0)
*vpp = ZTOV(zp); *ipp = ZTOI(zp);
rw_exit(&dzp->z_parent_lock); rw_exit(&dzp->z_parent_lock);
#ifdef HAVE_SNAPSHOT
} else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) { } else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) {
*vpp = zfsctl_root(dzp); *ipp = zfsctl_root(dzp);
#endif /* HAVE_SNAPSHOT */
} else { } else {
int zf; int zf;
@ -420,7 +434,7 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, 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) {
*vpp = ZTOV(zp); *ipp = ZTOI(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 */
} }
@ -450,13 +464,13 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags,
void void
zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx) zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
ASSERT(zp->z_unlinked); ASSERT(zp->z_unlinked);
ASSERT(zp->z_links == 0); ASSERT(zp->z_links == 0);
VERIFY3U(0, ==, VERIFY3U(0, ==,
zap_add_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx)); zap_add_int(zsb->z_os, zsb->z_unlinkedobj, zp->z_id, tx));
} }
/* /*
@ -464,7 +478,7 @@ zfs_unlinked_add(znode_t *zp, dmu_tx_t *tx)
* (force) umounted the file system. * (force) umounted the file system.
*/ */
void void
zfs_unlinked_drain(zfsvfs_t *zfsvfs) zfs_unlinked_drain(zfs_sb_t *zsb)
{ {
zap_cursor_t zc; zap_cursor_t zc;
zap_attribute_t zap; zap_attribute_t zap;
@ -475,7 +489,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
/* /*
* Interate over the contents of the unlinked set. * Interate over the contents of the unlinked set.
*/ */
for (zap_cursor_init(&zc, zfsvfs->z_os, zfsvfs->z_unlinkedobj); for (zap_cursor_init(&zc, zsb->z_os, zsb->z_unlinkedobj);
zap_cursor_retrieve(&zc, &zap) == 0; zap_cursor_retrieve(&zc, &zap) == 0;
zap_cursor_advance(&zc)) { zap_cursor_advance(&zc)) {
@ -483,8 +497,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
* See what kind of object we have in list * See what kind of object we have in list
*/ */
error = dmu_object_info(zfsvfs->z_os, error = dmu_object_info(zsb->z_os, zap.za_first_integer, &doi);
zap.za_first_integer, &doi);
if (error != 0) if (error != 0)
continue; continue;
@ -494,7 +507,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
* We need to re-mark these list entries for deletion, * We need to re-mark these list entries for deletion,
* so we pull them back into core and set zp->z_unlinked. * so we pull them back into core and set zp->z_unlinked.
*/ */
error = zfs_zget(zfsvfs, zap.za_first_integer, &zp); error = zfs_zget(zsb, zap.za_first_integer, &zp);
/* /*
* We may pick up znodes that are already marked for deletion. * We may pick up znodes that are already marked for deletion.
@ -506,7 +519,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
continue; continue;
zp->z_unlinked = B_TRUE; zp->z_unlinked = B_TRUE;
VN_RELE(ZTOV(zp)); iput(ZTOI(zp));
} }
zap_cursor_fini(&zc); zap_cursor_fini(&zc);
} }
@ -529,35 +542,34 @@ zfs_purgedir(znode_t *dzp)
zap_attribute_t zap; zap_attribute_t zap;
znode_t *xzp; znode_t *xzp;
dmu_tx_t *tx; dmu_tx_t *tx;
zfsvfs_t *zfsvfs = dzp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(dzp);
zfs_dirlock_t dl; zfs_dirlock_t dl;
int skipped = 0; int skipped = 0;
int error; int error;
for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id); for (zap_cursor_init(&zc, zsb->z_os, dzp->z_id);
(error = zap_cursor_retrieve(&zc, &zap)) == 0; (error = zap_cursor_retrieve(&zc, &zap)) == 0;
zap_cursor_advance(&zc)) { zap_cursor_advance(&zc)) {
error = zfs_zget(zfsvfs, error = zfs_zget(zsb,
ZFS_DIRENT_OBJ(zap.za_first_integer), &xzp); ZFS_DIRENT_OBJ(zap.za_first_integer), &xzp);
if (error) { if (error) {
skipped += 1; skipped += 1;
continue; continue;
} }
ASSERT((ZTOV(xzp)->v_type == VREG) || ASSERT(S_ISREG(ZTOI(xzp)->i_mode)||S_ISLNK(ZTOI(xzp)->i_mode));
(ZTOV(xzp)->v_type == VLNK));
tx = dmu_tx_create(zfsvfs->z_os); tx = dmu_tx_create(zsb->z_os);
dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE); dmu_tx_hold_sa(tx, dzp->z_sa_hdl, B_FALSE);
dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap.za_name); dmu_tx_hold_zap(tx, dzp->z_id, FALSE, zap.za_name);
dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE); dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL); dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL);
/* Is this really needed ? */ /* Is this really needed ? */
zfs_sa_upgrade_txholds(tx, xzp); zfs_sa_upgrade_txholds(tx, xzp);
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);
VN_RELE(ZTOV(xzp)); iput(ZTOI(xzp));
skipped += 1; skipped += 1;
continue; continue;
} }
@ -570,7 +582,7 @@ zfs_purgedir(znode_t *dzp)
skipped += 1; skipped += 1;
dmu_tx_commit(tx); dmu_tx_commit(tx);
VN_RELE(ZTOV(xzp)); iput(ZTOI(xzp));
} }
zap_cursor_fini(&zc); zap_cursor_fini(&zc);
if (error != ENOENT) if (error != ENOENT)
@ -581,8 +593,8 @@ zfs_purgedir(znode_t *dzp)
void void
zfs_rmnode(znode_t *zp) zfs_rmnode(znode_t *zp)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
objset_t *os = zfsvfs->z_os; objset_t *os = zsb->z_os;
znode_t *xzp = NULL; znode_t *xzp = NULL;
dmu_tx_t *tx; dmu_tx_t *tx;
uint64_t acl_obj; uint64_t acl_obj;
@ -590,19 +602,20 @@ zfs_rmnode(znode_t *zp)
int error; int error;
ASSERT(zp->z_links == 0); ASSERT(zp->z_links == 0);
ASSERT(ZTOV(zp)->v_count == 0); ASSERT(atomic_read(&ZTOI(zp)->i_count) == 0);
/* /*
* If this is an attribute directory, purge its contents. * If this is an attribute directory, purge its contents.
*/ */
if (ZTOV(zp)->v_type == VDIR && (zp->z_pflags & ZFS_XATTR)) { if (S_ISDIR(ZTOI(zp)->i_mode) && (zp->z_pflags & ZFS_XATTR)) {
if (zfs_purgedir(zp) != 0) { if (zfs_purgedir(zp) != 0) {
/* /*
* Not enough space to delete some xattrs. * Not enough space to delete some xattrs.
* Leave it in the unlinked set. * Leave it in the unlinked set.
*/ */
zfs_znode_dmu_fini(zp); zfs_znode_dmu_fini(zp);
zfs_znode_free(zp); zfs_inode_destroy(ZTOI(zp));
return; return;
} }
} }
@ -616,7 +629,7 @@ zfs_rmnode(znode_t *zp)
* Not enough space. Leave the file in the unlinked set. * Not enough space. Leave the file in the unlinked set.
*/ */
zfs_znode_dmu_fini(zp); zfs_znode_dmu_fini(zp);
zfs_znode_free(zp); zfs_inode_destroy(ZTOI(zp));
return; return;
} }
@ -624,10 +637,10 @@ zfs_rmnode(znode_t *zp)
* If the file has extended attributes, we're going to unlink * If the file has extended attributes, we're going to unlink
* the xattr dir. * the xattr dir.
*/ */
error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), error = sa_lookup(zp->z_sa_hdl, SA_ZPL_XATTR(zsb),
&xattr_obj, sizeof (xattr_obj)); &xattr_obj, sizeof (xattr_obj));
if (error == 0 && xattr_obj) { if (error == 0 && xattr_obj) {
error = zfs_zget(zfsvfs, xattr_obj, &xzp); error = zfs_zget(zsb, xattr_obj, &xzp);
ASSERT(error == 0); ASSERT(error == 0);
} }
@ -638,9 +651,9 @@ zfs_rmnode(znode_t *zp)
*/ */
tx = dmu_tx_create(os); tx = dmu_tx_create(os);
dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END); dmu_tx_hold_free(tx, zp->z_id, 0, DMU_OBJECT_END);
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, FALSE, NULL); dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, FALSE, NULL);
if (xzp) { if (xzp) {
dmu_tx_hold_zap(tx, zfsvfs->z_unlinkedobj, TRUE, NULL); dmu_tx_hold_zap(tx, zsb->z_unlinkedobj, TRUE, NULL);
dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE); dmu_tx_hold_sa(tx, xzp->z_sa_hdl, B_FALSE);
} }
if (acl_obj) if (acl_obj)
@ -656,7 +669,7 @@ zfs_rmnode(znode_t *zp)
*/ */
dmu_tx_abort(tx); dmu_tx_abort(tx);
zfs_znode_dmu_fini(zp); zfs_znode_dmu_fini(zp);
zfs_znode_free(zp); zfs_inode_destroy(ZTOI(zp));
goto out; goto out;
} }
@ -665,7 +678,7 @@ zfs_rmnode(znode_t *zp)
mutex_enter(&xzp->z_lock); mutex_enter(&xzp->z_lock);
xzp->z_unlinked = B_TRUE; /* mark xzp for deletion */ xzp->z_unlinked = B_TRUE; /* mark xzp for deletion */
xzp->z_links = 0; /* no more links to it */ xzp->z_links = 0; /* no more links to it */
VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zfsvfs), VERIFY(0 == sa_update(xzp->z_sa_hdl, SA_ZPL_LINKS(zsb),
&xzp->z_links, sizeof (xzp->z_links), tx)); &xzp->z_links, sizeof (xzp->z_links), tx));
mutex_exit(&xzp->z_lock); mutex_exit(&xzp->z_lock);
zfs_unlinked_add(xzp, tx); zfs_unlinked_add(xzp, tx);
@ -673,14 +686,14 @@ zfs_rmnode(znode_t *zp)
/* Remove this znode from the unlinked set */ /* Remove this znode from the unlinked set */
VERIFY3U(0, ==, VERIFY3U(0, ==,
zap_remove_int(zfsvfs->z_os, zfsvfs->z_unlinkedobj, zp->z_id, tx)); zap_remove_int(zsb->z_os, zsb->z_unlinkedobj, zp->z_id, tx));
zfs_znode_delete(zp, tx); zfs_znode_delete(zp, tx);
dmu_tx_commit(tx); dmu_tx_commit(tx);
out: out:
if (xzp) if (xzp)
VN_RELE(ZTOV(xzp)); iput(ZTOI(xzp));
} }
static uint64_t static uint64_t
@ -688,7 +701,7 @@ zfs_dirent(znode_t *zp, uint64_t mode)
{ {
uint64_t de = zp->z_id; uint64_t de = zp->z_id;
if (zp->z_zfsvfs->z_version >= ZPL_VERSION_DIRENT_TYPE) if (ZTOZSB(zp)->z_version >= ZPL_VERSION_DIRENT_TYPE)
de |= IFTODT(mode) << 60; de |= IFTODT(mode) << 60;
return (de); return (de);
} }
@ -700,10 +713,9 @@ int
zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag) zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
{ {
znode_t *dzp = dl->dl_dzp; znode_t *dzp = dl->dl_dzp;
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
vnode_t *vp = ZTOV(zp);
uint64_t value; uint64_t value;
int zp_is_dir = (vp->v_type == VDIR); int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode);
sa_bulk_attr_t bulk[5]; sa_bulk_attr_t bulk[5];
uint64_t mtime[2], ctime[2]; uint64_t mtime[2], ctime[2];
int count = 0; int count = 0;
@ -718,17 +730,17 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
return (ENOENT); return (ENOENT);
} }
zp->z_links++; zp->z_links++;
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL,
&zp->z_links, sizeof (zp->z_links)); &zp->z_links, sizeof (zp->z_links));
} }
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL,
&dzp->z_id, sizeof (dzp->z_id)); &dzp->z_id, sizeof (dzp->z_id));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
&zp->z_pflags, sizeof (zp->z_pflags)); &zp->z_pflags, sizeof (zp->z_pflags));
if (!(flag & ZNEW)) { if (!(flag & ZNEW)) {
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
ctime, sizeof (ctime)); ctime, sizeof (ctime));
zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime,
ctime, B_TRUE); ctime, B_TRUE);
@ -742,15 +754,15 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
dzp->z_size++; dzp->z_size++;
dzp->z_links += zp_is_dir; dzp->z_links += zp_is_dir;
count = 0; count = 0;
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb), NULL,
&dzp->z_size, sizeof (dzp->z_size)); &dzp->z_size, sizeof (dzp->z_size));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb), NULL,
&dzp->z_links, sizeof (dzp->z_links)); &dzp->z_links, sizeof (dzp->z_links));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL,
mtime, sizeof (mtime)); mtime, sizeof (mtime));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL,
ctime, sizeof (ctime)); ctime, sizeof (ctime));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb), NULL,
&dzp->z_pflags, sizeof (dzp->z_pflags)); &dzp->z_pflags, sizeof (dzp->z_pflags));
zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE); zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE);
error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx); error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx);
@ -758,11 +770,13 @@ zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
mutex_exit(&dzp->z_lock); mutex_exit(&dzp->z_lock);
value = zfs_dirent(zp, zp->z_mode); value = zfs_dirent(zp, zp->z_mode);
error = zap_add(zp->z_zfsvfs->z_os, dzp->z_id, dl->dl_name, error = zap_add(ZTOZSB(zp)->z_os, dzp->z_id, dl->dl_name,
8, 1, &value, tx); 8, 1, &value, tx);
ASSERT(error == 0); ASSERT(error == 0);
dnlc_update(ZTOV(dzp), dl->dl_name, vp); #ifdef HAVE_DNLC
dnlc_update(ZTOI(dzp), dl->dl_name, vp);
#endif /* HAVE_DNLC */
return (0); return (0);
} }
@ -773,18 +787,18 @@ zfs_dropname(zfs_dirlock_t *dl, znode_t *zp, znode_t *dzp, dmu_tx_t *tx,
{ {
int error; int error;
if (zp->z_zfsvfs->z_norm) { if (ZTOZSB(zp)->z_norm) {
if (((zp->z_zfsvfs->z_case == ZFS_CASE_INSENSITIVE) && if (((ZTOZSB(zp)->z_case == ZFS_CASE_INSENSITIVE) &&
(flag & ZCIEXACT)) || (flag & ZCIEXACT)) ||
((zp->z_zfsvfs->z_case == ZFS_CASE_MIXED) && ((ZTOZSB(zp)->z_case == ZFS_CASE_MIXED) &&
!(flag & ZCILOOK))) !(flag & ZCILOOK)))
error = zap_remove_norm(zp->z_zfsvfs->z_os, error = zap_remove_norm(ZTOZSB(zp)->z_os,
dzp->z_id, dl->dl_name, MT_EXACT, tx); dzp->z_id, dl->dl_name, MT_EXACT, tx);
else else
error = zap_remove_norm(zp->z_zfsvfs->z_os, error = zap_remove_norm(ZTOZSB(zp)->z_os,
dzp->z_id, dl->dl_name, MT_FIRST, tx); dzp->z_id, dl->dl_name, MT_FIRST, tx);
} else { } else {
error = zap_remove(zp->z_zfsvfs->z_os, error = zap_remove(ZTOZSB(zp)->z_os,
dzp->z_id, dl->dl_name, tx); dzp->z_id, dl->dl_name, tx);
} }
@ -803,31 +817,23 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
boolean_t *unlinkedp) boolean_t *unlinkedp)
{ {
znode_t *dzp = dl->dl_dzp; znode_t *dzp = dl->dl_dzp;
zfsvfs_t *zfsvfs = dzp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(dzp);
vnode_t *vp = ZTOV(zp); int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode);
int zp_is_dir = (vp->v_type == VDIR);
boolean_t unlinked = B_FALSE; boolean_t unlinked = B_FALSE;
sa_bulk_attr_t bulk[5]; sa_bulk_attr_t bulk[5];
uint64_t mtime[2], ctime[2]; uint64_t mtime[2], ctime[2];
int count = 0; int count = 0;
int error; int error;
dnlc_remove(ZTOV(dzp), dl->dl_name); #ifdef HAVE_DNLC
dnlc_remove(ZTOI(dzp), dl->dl_name);
#endif /* HAVE_DNLC */
if (!(flag & ZRENAMING)) { if (!(flag & ZRENAMING)) {
if (vn_vfswlock(vp)) /* prevent new mounts on zp */
return (EBUSY);
if (vn_ismntpt(vp)) { /* don't remove mount point */
vn_vfsunlock(vp);
return (EBUSY);
}
mutex_enter(&zp->z_lock); mutex_enter(&zp->z_lock);
if (zp_is_dir && !zfs_dirempty(zp)) { if (zp_is_dir && !zfs_dirempty(zp)) {
mutex_exit(&zp->z_lock); mutex_exit(&zp->z_lock);
vn_vfsunlock(vp);
return (EEXIST); return (EEXIST);
} }
@ -839,16 +845,13 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
error = zfs_dropname(dl, zp, dzp, tx, flag); error = zfs_dropname(dl, zp, dzp, tx, flag);
if (error != 0) { if (error != 0) {
mutex_exit(&zp->z_lock); mutex_exit(&zp->z_lock);
vn_vfsunlock(vp);
return (error); return (error);
} }
if (zp->z_links <= zp_is_dir) { if (zp->z_links <= zp_is_dir) {
zfs_panic_recover("zfs: link count on %s is %u, " zfs_panic_recover("zfs: link count on %lu is %u, "
"should be at least %u", "should be at least %u", zp->z_id,
zp->z_vnode->v_path ? zp->z_vnode->v_path : (int)zp->z_links, zp_is_dir + 1);
"<unknown>", (int)zp->z_links,
zp_is_dir + 1);
zp->z_links = zp_is_dir + 1; zp->z_links = zp_is_dir + 1;
} }
if (--zp->z_links == zp_is_dir) { if (--zp->z_links == zp_is_dir) {
@ -856,20 +859,19 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
zp->z_links = 0; zp->z_links = 0;
unlinked = B_TRUE; unlinked = B_TRUE;
} else { } else {
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb),
NULL, &ctime, sizeof (ctime)); NULL, &ctime, sizeof (ctime));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb),
NULL, &zp->z_pflags, sizeof (zp->z_pflags)); NULL, &zp->z_pflags, sizeof (zp->z_pflags));
zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime, zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime,
B_TRUE); B_TRUE);
} }
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb),
NULL, &zp->z_links, sizeof (zp->z_links)); NULL, &zp->z_links, sizeof (zp->z_links));
error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx); error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
count = 0; count = 0;
ASSERT(error == 0); ASSERT(error == 0);
mutex_exit(&zp->z_lock); mutex_exit(&zp->z_lock);
vn_vfsunlock(vp);
} else { } else {
error = zfs_dropname(dl, zp, dzp, tx, flag); error = zfs_dropname(dl, zp, dzp, tx, flag);
if (error != 0) if (error != 0)
@ -879,15 +881,15 @@ zfs_link_destroy(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag,
mutex_enter(&dzp->z_lock); mutex_enter(&dzp->z_lock);
dzp->z_size--; /* one dirent removed */ dzp->z_size--; /* one dirent removed */
dzp->z_links -= zp_is_dir; /* ".." link from zp */ dzp->z_links -= zp_is_dir; /* ".." link from zp */
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_LINKS(zsb),
NULL, &dzp->z_links, sizeof (dzp->z_links)); NULL, &dzp->z_links, sizeof (dzp->z_links));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_SIZE(zsb),
NULL, &dzp->z_size, sizeof (dzp->z_size)); NULL, &dzp->z_size, sizeof (dzp->z_size));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb),
NULL, ctime, sizeof (ctime)); NULL, ctime, sizeof (ctime));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb),
NULL, mtime, sizeof (mtime)); NULL, mtime, sizeof (mtime));
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zfsvfs), SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_FLAGS(zsb),
NULL, &dzp->z_pflags, sizeof (dzp->z_pflags)); NULL, &dzp->z_pflags, sizeof (dzp->z_pflags));
zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE); zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE);
error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx); error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx);
@ -914,38 +916,40 @@ zfs_dirempty(znode_t *dzp)
} }
int int
zfs_make_xattrdir(znode_t *zp, vattr_t *vap, vnode_t **xvpp, cred_t *cr) zfs_make_xattrdir(znode_t *zp, vattr_t *vap, struct inode **xipp, cred_t *cr)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
znode_t *xzp; znode_t *xzp;
dmu_tx_t *tx; dmu_tx_t *tx;
int error; int error;
zfs_acl_ids_t acl_ids; zfs_acl_ids_t acl_ids;
boolean_t fuid_dirtied; boolean_t fuid_dirtied;
#ifdef DEBUG
uint64_t parent; uint64_t parent;
#endif
*xvpp = NULL; *xipp = 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);
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL, if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
&acl_ids)) != 0) &acl_ids)) != 0)
return (error); return (error);
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) { if (zfs_acl_ids_overquota(zsb, &acl_ids)) {
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
return (EDQUOT); return (EDQUOT);
} }
top: top:
tx = dmu_tx_create(zfsvfs->z_os); tx = dmu_tx_create(zsb->z_os);
dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes + dmu_tx_hold_sa_create(tx, acl_ids.z_aclp->z_acl_bytes +
ZFS_SA_BASE_ATTR_SIZE); ZFS_SA_BASE_ATTR_SIZE);
dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE); dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
fuid_dirtied = zfsvfs->z_fuid_dirty; fuid_dirtied = zsb->z_fuid_dirty;
if (fuid_dirtied) if (fuid_dirtied)
zfs_fuid_txhold(zfsvfs, tx); zfs_fuid_txhold(zsb, tx);
error = dmu_tx_assign(tx, TXG_NOWAIT); error = dmu_tx_assign(tx, TXG_NOWAIT);
if (error) { if (error) {
if (error == ERESTART) { if (error == ERESTART) {
@ -960,24 +964,24 @@ top:
zfs_mknode(zp, vap, tx, cr, IS_XATTR, &xzp, &acl_ids); zfs_mknode(zp, vap, tx, cr, IS_XATTR, &xzp, &acl_ids);
if (fuid_dirtied) if (fuid_dirtied)
zfs_fuid_sync(zfsvfs, tx); zfs_fuid_sync(zsb, tx);
#ifdef DEBUG #ifdef DEBUG
error = sa_lookup(xzp->z_sa_hdl, SA_ZPL_PARENT(zfsvfs), error = sa_lookup(xzp->z_sa_hdl, SA_ZPL_PARENT(zsb),
&parent, sizeof (parent)); &parent, sizeof (parent));
ASSERT(error == 0 && parent == zp->z_id); ASSERT(error == 0 && parent == zp->z_id);
#endif #endif
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zfsvfs), &xzp->z_id, VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_XATTR(zsb), &xzp->z_id,
sizeof (xzp->z_id), tx)); sizeof (xzp->z_id), tx));
(void) zfs_log_create(zfsvfs->z_log, tx, TX_MKXATTR, zp, (void) zfs_log_create(zsb->z_log, tx, TX_MKXATTR, zp,
xzp, "", NULL, acl_ids.z_fuidp, vap); xzp, "", NULL, acl_ids.z_fuidp, vap);
zfs_acl_ids_free(&acl_ids); zfs_acl_ids_free(&acl_ids);
dmu_tx_commit(tx); dmu_tx_commit(tx);
*xvpp = ZTOV(xzp); *xipp = ZTOI(xzp);
return (0); return (0);
} }
@ -990,15 +994,15 @@ top:
* cr - credentials of caller * cr - credentials of caller
* flags - flags from the VOP_LOOKUP call * flags - flags from the VOP_LOOKUP call
* *
* OUT: xzpp - pointer to extended attribute znode * OUT: xipp - pointer to extended attribute znode
* *
* RETURN: 0 on success * RETURN: 0 on success
* error number on failure * error number on failure
*/ */
int int
zfs_get_xattrdir(znode_t *zp, vnode_t **xvpp, cred_t *cr, int flags) zfs_get_xattrdir(znode_t *zp, struct inode **xipp, cred_t *cr, int flags)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
znode_t *xzp; znode_t *xzp;
zfs_dirlock_t *dl; zfs_dirlock_t *dl;
vattr_t va; vattr_t va;
@ -1009,18 +1013,17 @@ top:
return (error); return (error);
if (xzp != NULL) { if (xzp != NULL) {
*xvpp = ZTOV(xzp); *xipp = ZTOI(xzp);
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
return (0); return (0);
} }
if (!(flags & CREATE_XATTR_DIR)) { if (!(flags & CREATE_XATTR_DIR)) {
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
return (ENOENT); return (ENOENT);
} }
if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) { if (zsb->z_vfs->mnt_flags & MNT_READONLY) {
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
return (EROFS); return (EROFS);
} }
@ -1035,12 +1038,11 @@ top:
* Once in a directory the ability to read/write attributes * Once in a directory the ability to read/write attributes
* is controlled by the permissions on the attribute file. * is controlled by the permissions on the attribute file.
*/ */
va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID; va.va_mask = ATTR_MODE | ATTR_UID | ATTR_GID;
va.va_type = VDIR;
va.va_mode = S_IFDIR | S_ISVTX | 0777; va.va_mode = S_IFDIR | S_ISVTX | 0777;
zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid); zfs_fuid_map_ids(zp, cr, &va.va_uid, &va.va_gid);
error = zfs_make_xattrdir(zp, &va, xvpp, cr); error = zfs_make_xattrdir(zp, &va, xipp, cr);
zfs_dirent_unlock(dl); zfs_dirent_unlock(dl);
if (error == ERESTART) { if (error == ERESTART) {
@ -1070,22 +1072,21 @@ zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
uid_t uid; uid_t uid;
uid_t downer; uid_t downer;
uid_t fowner; uid_t fowner;
zfsvfs_t *zfsvfs = zdp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zdp);
if (zdp->z_zfsvfs->z_replay) if (zsb->z_replay)
return (0); return (0);
if ((zdp->z_mode & S_ISVTX) == 0) if ((zdp->z_mode & S_ISVTX) == 0)
return (0); return (0);
downer = zfs_fuid_map_id(zfsvfs, zdp->z_uid, cr, ZFS_OWNER); downer = zfs_fuid_map_id(zsb, zdp->z_uid, cr, ZFS_OWNER);
fowner = zfs_fuid_map_id(zfsvfs, zp->z_uid, cr, ZFS_OWNER); fowner = zfs_fuid_map_id(zsb, zp->z_uid, cr, ZFS_OWNER);
if ((uid = crgetuid(cr)) == downer || uid == fowner || if ((uid = crgetuid(cr)) == downer || uid == fowner ||
(ZTOV(zp)->v_type == VREG && (S_ISDIR(ZTOI(zp)->i_mode) &&
zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0)) zfs_zaccess(zp, ACE_WRITE_DATA, 0, B_FALSE, cr) == 0))
return (0); return (0);
else else
return (secpolicy_vnode_remove(cr)); return (secpolicy_vnode_remove(cr));
} }
#endif /* HAVE_ZPL */

View File

@ -46,7 +46,7 @@
* two AVL trees are created. One tree is keyed by the index number * two AVL trees are created. One tree is keyed by the index number
* and the other by the domain string. Nodes are never removed from * and the other by the domain string. Nodes are never removed from
* trees, but new entries may be added. If a new entry is added then * trees, but new entries may be added. If a new entry is added then
* the zfsvfs->z_fuid_dirty flag is set to true and the caller will then * the zsb->z_fuid_dirty flag is set to true and the caller will then
* be responsible for calling zfs_fuid_sync() to sync the changes to disk. * be responsible for calling zfs_fuid_sync() to sync the changes to disk.
* *
*/ */
@ -196,34 +196,34 @@ zfs_fuid_idx_domain(avl_tree_t *idx_tree, uint32_t idx)
* Load the fuid table(s) into memory. * Load the fuid table(s) into memory.
*/ */
static void static void
zfs_fuid_init(zfsvfs_t *zfsvfs) zfs_fuid_init(zfs_sb_t *zsb)
{ {
rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER); rw_enter(&zsb->z_fuid_lock, RW_WRITER);
if (zfsvfs->z_fuid_loaded) { if (zsb->z_fuid_loaded) {
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
return; return;
} }
zfs_fuid_avl_tree_create(&zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain); zfs_fuid_avl_tree_create(&zsb->z_fuid_idx, &zsb->z_fuid_domain);
(void) zap_lookup(zfsvfs->z_os, MASTER_NODE_OBJ, (void) zap_lookup(zsb->z_os, MASTER_NODE_OBJ,
ZFS_FUID_TABLES, 8, 1, &zfsvfs->z_fuid_obj); ZFS_FUID_TABLES, 8, 1, &zsb->z_fuid_obj);
if (zfsvfs->z_fuid_obj != 0) { if (zsb->z_fuid_obj != 0) {
zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os, zsb->z_fuid_size = zfs_fuid_table_load(zsb->z_os,
zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx, zsb->z_fuid_obj, &zsb->z_fuid_idx,
&zfsvfs->z_fuid_domain); &zsb->z_fuid_domain);
} }
zfsvfs->z_fuid_loaded = B_TRUE; zsb->z_fuid_loaded = B_TRUE;
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
} }
/* /*
* sync out AVL trees to persistent storage. * sync out AVL trees to persistent storage.
*/ */
void void
zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx) zfs_fuid_sync(zfs_sb_t *zsb, dmu_tx_t *tx)
{ {
nvlist_t *nvp; nvlist_t *nvp;
nvlist_t **fuids; nvlist_t **fuids;
@ -234,30 +234,30 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
int numnodes; int numnodes;
int i; int i;
if (!zfsvfs->z_fuid_dirty) { if (!zsb->z_fuid_dirty) {
return; return;
} }
rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER); rw_enter(&zsb->z_fuid_lock, RW_WRITER);
/* /*
* First see if table needs to be created? * First see if table needs to be created?
*/ */
if (zfsvfs->z_fuid_obj == 0) { if (zsb->z_fuid_obj == 0) {
zfsvfs->z_fuid_obj = dmu_object_alloc(zfsvfs->z_os, zsb->z_fuid_obj = dmu_object_alloc(zsb->z_os,
DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE, DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE,
sizeof (uint64_t), tx); sizeof (uint64_t), tx);
VERIFY(zap_add(zfsvfs->z_os, MASTER_NODE_OBJ, VERIFY(zap_add(zsb->z_os, MASTER_NODE_OBJ,
ZFS_FUID_TABLES, sizeof (uint64_t), 1, ZFS_FUID_TABLES, sizeof (uint64_t), 1,
&zfsvfs->z_fuid_obj, tx) == 0); &zsb->z_fuid_obj, tx) == 0);
} }
VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0); VERIFY(nvlist_alloc(&nvp, NV_UNIQUE_NAME, KM_SLEEP) == 0);
numnodes = avl_numnodes(&zfsvfs->z_fuid_idx); numnodes = avl_numnodes(&zsb->z_fuid_idx);
fuids = kmem_alloc(numnodes * sizeof (void *), KM_SLEEP); fuids = kmem_alloc(numnodes * sizeof (void *), KM_SLEEP);
for (i = 0, domnode = avl_first(&zfsvfs->z_fuid_domain); domnode; i++, for (i = 0, domnode = avl_first(&zsb->z_fuid_domain); domnode; i++,
domnode = AVL_NEXT(&zfsvfs->z_fuid_domain, domnode)) { domnode = AVL_NEXT(&zsb->z_fuid_domain, domnode)) {
VERIFY(nvlist_alloc(&fuids[i], NV_UNIQUE_NAME, KM_SLEEP) == 0); VERIFY(nvlist_alloc(&fuids[i], NV_UNIQUE_NAME, KM_SLEEP) == 0);
VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX, VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX,
domnode->f_idx) == 0); domnode->f_idx) == 0);
@ -275,30 +275,29 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
VERIFY(nvlist_pack(nvp, &packed, &nvsize, VERIFY(nvlist_pack(nvp, &packed, &nvsize,
NV_ENCODE_XDR, KM_SLEEP) == 0); NV_ENCODE_XDR, KM_SLEEP) == 0);
nvlist_free(nvp); nvlist_free(nvp);
zfsvfs->z_fuid_size = nvsize; zsb->z_fuid_size = nvsize;
dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0, dmu_write(zsb->z_os, zsb->z_fuid_obj, 0, zsb->z_fuid_size, packed, tx);
zfsvfs->z_fuid_size, packed, tx); kmem_free(packed, zsb->z_fuid_size);
kmem_free(packed, zfsvfs->z_fuid_size); VERIFY(0 == dmu_bonus_hold(zsb->z_os, zsb->z_fuid_obj,
VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj,
FTAG, &db)); FTAG, &db));
dmu_buf_will_dirty(db, tx); dmu_buf_will_dirty(db, tx);
*(uint64_t *)db->db_data = zfsvfs->z_fuid_size; *(uint64_t *)db->db_data = zsb->z_fuid_size;
dmu_buf_rele(db, FTAG); dmu_buf_rele(db, FTAG);
zfsvfs->z_fuid_dirty = B_FALSE; zsb->z_fuid_dirty = B_FALSE;
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
} }
/* /*
* Query domain table for a given domain. * Query domain table for a given domain.
* *
* If domain isn't found and addok is set, it is added to AVL trees and * If domain isn't found and addok is set, it is added to AVL trees and
* the zfsvfs->z_fuid_dirty flag will be set to TRUE. It will then be * the zsb->z_fuid_dirty flag will be set to TRUE. It will then be
* necessary for the caller or another thread to detect the dirty table * necessary for the caller or another thread to detect the dirty table
* and sync out the changes. * and sync out the changes.
*/ */
int int
zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain, zfs_fuid_find_by_domain(zfs_sb_t *zsb, const char *domain,
char **retdomain, boolean_t addok) char **retdomain, boolean_t addok)
{ {
fuid_domain_t searchnode, *findnode; fuid_domain_t searchnode, *findnode;
@ -319,23 +318,23 @@ zfs_fuid_find_by_domain(zfsvfs_t *zfsvfs, const char *domain,
searchnode.f_ksid = ksid_lookupdomain(domain); searchnode.f_ksid = ksid_lookupdomain(domain);
if (retdomain) if (retdomain)
*retdomain = searchnode.f_ksid->kd_name; *retdomain = searchnode.f_ksid->kd_name;
if (!zfsvfs->z_fuid_loaded) if (!zsb->z_fuid_loaded)
zfs_fuid_init(zfsvfs); zfs_fuid_init(zsb);
retry: retry:
rw_enter(&zfsvfs->z_fuid_lock, rw); rw_enter(&zsb->z_fuid_lock, rw);
findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc); findnode = avl_find(&zsb->z_fuid_domain, &searchnode, &loc);
if (findnode) { if (findnode) {
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
ksiddomain_rele(searchnode.f_ksid); ksiddomain_rele(searchnode.f_ksid);
return (findnode->f_idx); return (findnode->f_idx);
} else if (addok) { } else if (addok) {
fuid_domain_t *domnode; fuid_domain_t *domnode;
uint64_t retidx; uint64_t retidx;
if (rw == RW_READER && !rw_tryupgrade(&zfsvfs->z_fuid_lock)) { if (rw == RW_READER && !rw_tryupgrade(&zsb->z_fuid_lock)) {
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
rw = RW_WRITER; rw = RW_WRITER;
goto retry; goto retry;
} }
@ -343,15 +342,15 @@ retry:
domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP); domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
domnode->f_ksid = searchnode.f_ksid; domnode->f_ksid = searchnode.f_ksid;
retidx = domnode->f_idx = avl_numnodes(&zfsvfs->z_fuid_idx) + 1; retidx = domnode->f_idx = avl_numnodes(&zsb->z_fuid_idx) + 1;
avl_add(&zfsvfs->z_fuid_domain, domnode); avl_add(&zsb->z_fuid_domain, domnode);
avl_add(&zfsvfs->z_fuid_idx, domnode); avl_add(&zsb->z_fuid_idx, domnode);
zfsvfs->z_fuid_dirty = B_TRUE; zsb->z_fuid_dirty = B_TRUE;
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
return (retidx); return (retidx);
} else { } else {
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
return (-1); return (-1);
} }
} }
@ -363,23 +362,23 @@ retry:
* *
*/ */
const char * const char *
zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx) zfs_fuid_find_by_idx(zfs_sb_t *zsb, uint32_t idx)
{ {
char *domain; char *domain;
if (idx == 0 || !zfsvfs->z_use_fuids) if (idx == 0 || !zsb->z_use_fuids)
return (NULL); return (NULL);
if (!zfsvfs->z_fuid_loaded) if (!zsb->z_fuid_loaded)
zfs_fuid_init(zfsvfs); zfs_fuid_init(zsb);
rw_enter(&zfsvfs->z_fuid_lock, RW_READER); rw_enter(&zsb->z_fuid_lock, RW_READER);
if (zfsvfs->z_fuid_obj || zfsvfs->z_fuid_dirty) if (zsb->z_fuid_obj || zsb->z_fuid_dirty)
domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx); domain = zfs_fuid_idx_domain(&zsb->z_fuid_idx, idx);
else else
domain = nulldomain; domain = nulldomain;
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
ASSERT(domain); ASSERT(domain);
return (domain); return (domain);
@ -388,12 +387,12 @@ zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx)
void void
zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp) zfs_fuid_map_ids(znode_t *zp, cred_t *cr, uid_t *uidp, uid_t *gidp)
{ {
*uidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER); *uidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
*gidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_gid, cr, ZFS_GROUP); *gidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_gid, cr, ZFS_GROUP);
} }
uid_t uid_t
zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid, zfs_fuid_map_id(zfs_sb_t *zsb, uint64_t fuid,
cred_t *cr, zfs_fuid_type_t type) cred_t *cr, zfs_fuid_type_t type)
{ {
#ifdef HAVE_KSID #ifdef HAVE_KSID
@ -404,7 +403,7 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
if (index == 0) if (index == 0)
return (fuid); return (fuid);
domain = zfs_fuid_find_by_idx(zfsvfs, index); domain = zfs_fuid_find_by_idx(zsb, index);
ASSERT(domain != NULL); ASSERT(domain != NULL);
if (type == ZFS_OWNER || type == ZFS_ACE_USER) { if (type == ZFS_OWNER || type == ZFS_ACE_USER) {
@ -499,7 +498,7 @@ zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid,
* be used if it exists. * be used if it exists.
*/ */
uint64_t uint64_t
zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type, zfs_fuid_create_cred(zfs_sb_t *zsb, zfs_fuid_type_t type,
cred_t *cr, zfs_fuid_info_t **fuidp) cred_t *cr, zfs_fuid_info_t **fuidp)
{ {
uint64_t idx; uint64_t idx;
@ -513,7 +512,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP); ksid = crgetsid(cr, (type == ZFS_OWNER) ? KSID_OWNER : KSID_GROUP);
if (!zfsvfs->z_use_fuids || (ksid == NULL)) { if (!zsb->z_use_fuids || (ksid == NULL)) {
id = (type == ZFS_OWNER) ? crgetuid(cr) : crgetgid(cr); id = (type == ZFS_OWNER) ? crgetuid(cr) : crgetgid(cr);
if (IS_EPHEMERAL(id)) if (IS_EPHEMERAL(id))
@ -536,7 +535,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
rid = ksid_getrid(ksid); rid = ksid_getrid(ksid);
domain = ksid_getdomain(ksid); domain = ksid_getdomain(ksid);
idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, B_TRUE); idx = zfs_fuid_find_by_domain(zsb, domain, &kdomain, B_TRUE);
zfs_fuid_node_add(fuidp, kdomain, rid, idx, id, type); zfs_fuid_node_add(fuidp, kdomain, rid, idx, id, type);
@ -554,10 +553,10 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
* *
* During replay operations the domain+rid information is * During replay operations the domain+rid information is
* found in the zfs_fuid_info_t that the replay code has * found in the zfs_fuid_info_t that the replay code has
* attached to the zfsvfs of the file system. * attached to the zsb of the file system.
*/ */
uint64_t uint64_t
zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr, zfs_fuid_create(zfs_sb_t *zsb, uint64_t id, cred_t *cr,
zfs_fuid_type_t type, zfs_fuid_info_t **fuidpp) zfs_fuid_type_t type, zfs_fuid_info_t **fuidpp)
{ {
#ifdef HAVE_KSID #ifdef HAVE_KSID
@ -578,11 +577,11 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
* chmod. * chmod.
*/ */
if (!zfsvfs->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0) if (!zsb->z_use_fuids || !IS_EPHEMERAL(id) || fuid_idx != 0)
return (id); return (id);
if (zfsvfs->z_replay) { if (zsb->z_replay) {
fuidp = zfsvfs->z_fuid_replay; fuidp = zsb->z_fuid_replay;
/* /*
* If we are passed an ephemeral id, but no * If we are passed an ephemeral id, but no
@ -629,9 +628,9 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
} }
} }
idx = zfs_fuid_find_by_domain(zfsvfs, domain, &kdomain, B_TRUE); idx = zfs_fuid_find_by_domain(zsb, domain, &kdomain, B_TRUE);
if (!zfsvfs->z_replay) if (!zsb->z_replay)
zfs_fuid_node_add(fuidpp, kdomain, zfs_fuid_node_add(fuidpp, kdomain,
rid, idx, id, type); rid, idx, id, type);
else if (zfuid != NULL) { else if (zfuid != NULL) {
@ -648,15 +647,15 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
} }
void void
zfs_fuid_destroy(zfsvfs_t *zfsvfs) zfs_fuid_destroy(zfs_sb_t *zsb)
{ {
rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER); rw_enter(&zsb->z_fuid_lock, RW_WRITER);
if (!zfsvfs->z_fuid_loaded) { if (!zsb->z_fuid_loaded) {
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
return; return;
} }
zfs_fuid_table_destroy(&zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain); zfs_fuid_table_destroy(&zsb->z_fuid_idx, &zsb->z_fuid_domain);
rw_exit(&zfsvfs->z_fuid_lock); rw_exit(&zsb->z_fuid_lock);
} }
/* /*
@ -710,7 +709,7 @@ zfs_fuid_info_free(zfs_fuid_info_t *fuidp)
* Will use a straight FUID compare when possible. * Will use a straight FUID compare when possible.
*/ */
boolean_t boolean_t
zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr) zfs_groupmember(zfs_sb_t *zsb, uint64_t id, cred_t *cr)
{ {
#ifdef HAVE_KSID #ifdef HAVE_KSID
ksid_t *ksid = crgetsid(cr, KSID_GROUP); ksid_t *ksid = crgetsid(cr, KSID_GROUP);
@ -734,7 +733,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
} else { } else {
const char *domain; const char *domain;
domain = zfs_fuid_find_by_idx(zfsvfs, idx); domain = zfs_fuid_find_by_idx(zsb, idx);
ASSERT(domain != NULL); ASSERT(domain != NULL);
if (strcmp(domain, if (strcmp(domain,
@ -752,7 +751,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
/* /*
* Not found in ksidlist, check posix groups * Not found in ksidlist, check posix groups
*/ */
gid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP); gid = zfs_fuid_map_id(zsb, id, cr, ZFS_GROUP);
return (groupmember(gid, cr)); return (groupmember(gid, cr));
#else #else
return (B_TRUE); return (B_TRUE);
@ -760,17 +759,17 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
} }
void void
zfs_fuid_txhold(zfsvfs_t *zfsvfs, dmu_tx_t *tx) zfs_fuid_txhold(zfs_sb_t *zsb, dmu_tx_t *tx)
{ {
if (zfsvfs->z_fuid_obj == 0) { if (zsb->z_fuid_obj == 0) {
dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT); dmu_tx_hold_bonus(tx, DMU_NEW_OBJECT);
dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0, dmu_tx_hold_write(tx, DMU_NEW_OBJECT, 0,
FUID_SIZE_ESTIMATE(zfsvfs)); FUID_SIZE_ESTIMATE(zsb));
dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL); dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL);
} else { } else {
dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj); dmu_tx_hold_bonus(tx, zsb->z_fuid_obj);
dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0, dmu_tx_hold_write(tx, zsb->z_fuid_obj, 0,
FUID_SIZE_ESTIMATE(zfsvfs)); FUID_SIZE_ESTIMATE(zsb));
} }
} }
#endif #endif

View File

@ -432,7 +432,7 @@ zfs_set_slabel_policy(const char *name, char *strval, cred_t *cr)
/* /*
* If the existing dataset label is nondefault, check if the * If the existing dataset label is nondefault, check if the
* dataset is mounted (label cannot be changed while mounted). * dataset is mounted (label cannot be changed while mounted).
* Get the zfsvfs; if there isn't one, then the dataset isn't * Get the zfs_sb_t; if there isn't one, then the dataset isn't
* mounted (or isn't a dataset, doesn't exist, ...). * mounted (or isn't a dataset, doesn't exist, ...).
*/ */
if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) { if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) {
@ -849,20 +849,6 @@ zfs_secpolicy_create(zfs_cmd_t *zc, cred_t *cr)
return (error); return (error);
} }
#ifdef HAVE_ZPL
static int
zfs_secpolicy_umount(zfs_cmd_t *zc, cred_t *cr)
{
int error;
error = secpolicy_fs_unmount(cr, NULL);
if (error) {
error = dsl_deleg_access(zc->zc_name, ZFS_DELEG_PERM_MOUNT, cr);
}
return (error);
}
#endif /* HAVE_ZPL */
/* /*
* Policy for pool operations - create/destroy pools, add vdevs, etc. Requires * Policy for pool operations - create/destroy pools, add vdevs, etc. Requires
* SYS_CONFIG privilege, which is not available in a local zone. * SYS_CONFIG privilege, which is not available in a local zone.
@ -1105,9 +1091,8 @@ put_nvlist(zfs_cmd_t *zc, nvlist_t *nvl)
return (error); return (error);
} }
#ifdef HAVE_ZPL
static int static int
getzfsvfs(const char *dsname, zfsvfs_t **zfvp) get_zfs_sb(const char *dsname, zfs_sb_t **zsbp)
{ {
objset_t *os; objset_t *os;
int error; int error;
@ -1121,9 +1106,9 @@ getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
} }
mutex_enter(&os->os_user_ptr_lock); mutex_enter(&os->os_user_ptr_lock);
*zfvp = dmu_objset_get_user(os); *zsbp = dmu_objset_get_user(os);
if (*zfvp) { if (*zsbp) {
VFS_HOLD((*zfvp)->z_vfs); mntget((*zsbp)->z_vfs);
} else { } else {
error = ESRCH; error = ESRCH;
} }
@ -1131,52 +1116,45 @@ getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
dmu_objset_rele(os, FTAG); dmu_objset_rele(os, FTAG);
return (error); return (error);
} }
#endif
/* /*
* Find a zfsvfs_t for a mounted filesystem, or create our own, in which * Find a zfs_sb_t for a mounted filesystem, or create our own, in which
* case its z_vfs will be NULL, and it will be opened as the owner. * case its z_vfs will be NULL, and it will be opened as the owner.
*/ */
static int static int
zfsvfs_hold(const char *name, void *tag, zfsvfs_t **zfvp, boolean_t writer) zfs_sb_hold(const char *name, void *tag, zfs_sb_t **zsbp, boolean_t writer)
{ {
#ifdef HAVE_ZPL
int error = 0; int error = 0;
if (getzfsvfs(name, zfvp) != 0) if (get_zfs_sb(name, zsbp) != 0)
error = zfsvfs_create(name, zfvp); error = zfs_sb_create(name, zsbp);
if (error == 0) { if (error == 0) {
rrw_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER : rrw_enter(&(*zsbp)->z_teardown_lock, (writer) ? RW_WRITER :
RW_READER, tag); RW_READER, tag);
if ((*zfvp)->z_unmounted) { if ((*zsbp)->z_unmounted) {
/* /*
* XXX we could probably try again, since the unmounting * XXX we could probably try again, since the unmounting
* thread should be just about to disassociate the * thread should be just about to disassociate the
* objset from the zfsvfs. * objset from the zfsvfs.
*/ */
rrw_exit(&(*zfvp)->z_teardown_lock, tag); rrw_exit(&(*zsbp)->z_teardown_lock, tag);
return (EBUSY); return (EBUSY);
} }
} }
return (error); return (error);
#else
return ENOTSUP;
#endif
} }
static void static void
zfsvfs_rele(zfsvfs_t *zfsvfs, void *tag) zfs_sb_rele(zfs_sb_t *zsb, void *tag)
{ {
#ifdef HAVE_ZPL rrw_exit(&zsb->z_teardown_lock, tag);
rrw_exit(&zfsvfs->z_teardown_lock, tag);
if (zfsvfs->z_vfs) { if (zsb->z_vfs) {
VFS_RELE(zfsvfs->z_vfs); mntput(zsb->z_vfs);
} else { } else {
dmu_objset_disown(zfsvfs->z_os, zfsvfs); dmu_objset_disown(zsb->z_os, zsb);
zfsvfs_free(zfsvfs); zfs_sb_free(zsb);
} }
#endif
} }
static int static int
@ -2086,7 +2064,6 @@ top:
static int static int
zfs_prop_set_userquota(const char *dsname, nvpair_t *pair) zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
{ {
#ifdef HAVE_ZPL
const char *propname = nvpair_name(pair); const char *propname = nvpair_name(pair);
uint64_t *valary; uint64_t *valary;
unsigned int vallen; unsigned int vallen;
@ -2095,7 +2072,7 @@ zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
zfs_userquota_prop_t type; zfs_userquota_prop_t type;
uint64_t rid; uint64_t rid;
uint64_t quota; uint64_t quota;
zfsvfs_t *zfsvfs; zfs_sb_t *zsb;
int err; int err;
if (nvpair_type(pair) == DATA_TYPE_NVLIST) { if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
@ -2120,16 +2097,13 @@ zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
rid = valary[1]; rid = valary[1];
quota = valary[2]; quota = valary[2];
err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_FALSE); err = zfs_sb_hold(dsname, FTAG, &zsb, B_FALSE);
if (err == 0) { if (err == 0) {
err = zfs_set_userquota(zfsvfs, type, domain, rid, quota); err = zfs_set_userquota(zsb, type, domain, rid, quota);
zfsvfs_rele(zfsvfs, FTAG); zfs_sb_rele(zsb, FTAG);
} }
return (err); return (err);
#else
return ENOTSUP;
#endif
} }
/* /*
@ -2185,15 +2159,13 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
break; break;
case ZFS_PROP_VERSION: case ZFS_PROP_VERSION:
{ {
zfsvfs_t *zfsvfs; zfs_sb_t *zsb;
if ((err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_TRUE)) != 0) if ((err = zfs_sb_hold(dsname, FTAG, &zsb, B_TRUE)) != 0)
break; break;
#ifdef HAVE_ZPL err = zfs_set_version(zsb, intval);
err = zfs_set_version(zfsvfs, intval); zfs_sb_rele(zsb, FTAG);
#endif
zfsvfs_rele(zfsvfs, FTAG);
if (err == 0 && intval >= ZPL_VERSION_USERSPACE) { if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
zfs_cmd_t *zc; zfs_cmd_t *zc;
@ -2748,7 +2720,7 @@ zfs_ioc_get_fsacl(zfs_cmd_t *zc)
return (error); return (error);
} }
#ifdef HAVE_ZPL #ifdef HAVE_SNAPSHOT
/* /*
* Search the vfs list for a specified resource. Returns a pointer to it * Search the vfs list for a specified resource. Returns a pointer to it
* or NULL if no suitable entry is found. The caller of this routine * or NULL if no suitable entry is found. The caller of this routine
@ -2764,7 +2736,7 @@ zfs_get_vfs(const char *resource)
vfsp = rootvfs; vfsp = rootvfs;
do { do {
if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) { if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) {
VFS_HOLD(vfsp); mntget(vfsp);
vfs_found = vfsp; vfs_found = vfsp;
break; break;
} }
@ -2773,7 +2745,7 @@ zfs_get_vfs(const char *resource)
vfs_list_unlock(); vfs_list_unlock();
return (vfs_found); return (vfs_found);
} }
#endif /* HAVE_ZPL */ #endif /* HAVE_SNAPSHOT */
/* ARGSUSED */ /* ARGSUSED */
static void static void
@ -3128,7 +3100,7 @@ out:
int int
zfs_unmount_snap(const char *name, void *arg) zfs_unmount_snap(const char *name, void *arg)
{ {
#ifdef HAVE_ZPL #ifdef HAVE_SNAPSHOT
vfs_t *vfsp = NULL; vfs_t *vfsp = NULL;
if (arg) { if (arg) {
@ -3148,14 +3120,14 @@ zfs_unmount_snap(const char *name, void *arg)
int err; int err;
if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) { if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) {
VFS_RELE(vfsp); mntput(vfsp);
return (err); return (err);
} }
VFS_RELE(vfsp); mntput(vfsp);
if ((err = dounmount(vfsp, flag, kcred)) != 0) if ((err = dounmount(vfsp, flag, kcred)) != 0)
return (err); return (err);
} }
#endif /* HAVE_ZPL */ #endif /* HAVE_SNAPSHOT */
return (0); return (0);
} }
@ -3215,10 +3187,9 @@ zfs_ioc_destroy(zfs_cmd_t *zc)
static int static int
zfs_ioc_rollback(zfs_cmd_t *zc) zfs_ioc_rollback(zfs_cmd_t *zc)
{ {
#ifdef HAVE_ZPL
dsl_dataset_t *ds, *clone; dsl_dataset_t *ds, *clone;
int error; int error;
zfsvfs_t *zfsvfs; zfs_sb_t *zsb;
char *clone_name; char *clone_name;
error = dsl_dataset_hold(zc->zc_name, FTAG, &ds); error = dsl_dataset_hold(zc->zc_name, FTAG, &ds);
@ -3252,8 +3223,8 @@ zfs_ioc_rollback(zfs_cmd_t *zc)
/* /*
* Do clone swap. * Do clone swap.
*/ */
if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) { if (get_zfs_sb(zc->zc_name, &zsb) == 0) {
error = zfs_suspend_fs(zfsvfs); error = zfs_suspend_fs(zsb);
if (error == 0) { if (error == 0) {
int resume_err; int resume_err;
@ -3265,10 +3236,10 @@ zfs_ioc_rollback(zfs_cmd_t *zc)
} else { } else {
error = EBUSY; error = EBUSY;
} }
resume_err = zfs_resume_fs(zfsvfs, zc->zc_name); resume_err = zfs_resume_fs(zsb, zc->zc_name);
error = error ? error : resume_err; error = error ? error : resume_err;
} }
VFS_RELE(zfsvfs->z_vfs); mntput(zsb->z_vfs);
} else { } else {
if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) { if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
error = dsl_dataset_clone_swap(clone, ds, B_TRUE); error = dsl_dataset_clone_swap(clone, ds, B_TRUE);
@ -3289,9 +3260,6 @@ out:
if (ds) if (ds)
dsl_dataset_rele(ds, FTAG); dsl_dataset_rele(ds, FTAG);
return (error); return (error);
#else
return (ENOTSUP);
#endif /* HAVE_ZPL */
} }
/* /*
@ -3741,29 +3709,25 @@ zfs_ioc_recv(zfs_cmd_t *zc)
&zc->zc_action_handle); &zc->zc_action_handle);
if (error == 0) { if (error == 0) {
#ifdef HAVE_ZPL zfs_sb_t *zsb = NULL;
zfsvfs_t *zfsvfs = NULL;
if (getzfsvfs(tofs, &zfsvfs) == 0) { if (get_zfs_sb(tofs, &zsb) == 0) {
/* online recv */ /* online recv */
int end_err; int end_err;
error = zfs_suspend_fs(zfsvfs); error = zfs_suspend_fs(zsb);
/* /*
* If the suspend fails, then the recv_end will * If the suspend fails, then the recv_end will
* likely also fail, and clean up after itself. * likely also fail, and clean up after itself.
*/ */
end_err = dmu_recv_end(&drc); end_err = dmu_recv_end(&drc);
if (error == 0) if (error == 0)
error = zfs_resume_fs(zfsvfs, tofs); error = zfs_resume_fs(zsb, tofs);
error = error ? error : end_err; error = error ? error : end_err;
VFS_RELE(zfsvfs->z_vfs); mntput(zsb->z_vfs);
} else { } else {
error = dmu_recv_end(&drc); error = dmu_recv_end(&drc);
} }
#else
error = dmu_recv_end(&drc);
#endif /* HAVE_ZPL */
} }
zc->zc_cookie = off - fp->f_offset; zc->zc_cookie = off - fp->f_offset;
@ -4087,25 +4051,21 @@ zfs_ioc_promote(zfs_cmd_t *zc)
static int static int
zfs_ioc_userspace_one(zfs_cmd_t *zc) zfs_ioc_userspace_one(zfs_cmd_t *zc)
{ {
#ifdef HAVE_ZPL zfs_sb_t *zsb;
zfsvfs_t *zfsvfs;
int error; int error;
if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS) if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
return (EINVAL); return (EINVAL);
error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
if (error) if (error)
return (error); return (error);
error = zfs_userspace_one(zfsvfs, error = zfs_userspace_one(zsb,
zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie); zc->zc_objset_type, zc->zc_value, zc->zc_guid, &zc->zc_cookie);
zfsvfs_rele(zfsvfs, FTAG); zfs_sb_rele(zsb, FTAG);
return (error); return (error);
#else
return (ENOTSUP);
#endif /* HAVE_ZPL */
} }
/* /*
@ -4122,20 +4082,21 @@ zfs_ioc_userspace_one(zfs_cmd_t *zc)
static int static int
zfs_ioc_userspace_many(zfs_cmd_t *zc) zfs_ioc_userspace_many(zfs_cmd_t *zc)
{ {
#ifdef HAVE_ZPL zfs_sb_t *zsb;
zfsvfs_t *zfsvfs;
int bufsize = zc->zc_nvlist_dst_size; int bufsize = zc->zc_nvlist_dst_size;
int error;
void *buf;
if (bufsize <= 0) if (bufsize <= 0)
return (ENOMEM); return (ENOMEM);
int error = zfsvfs_hold(zc->zc_name, FTAG, &zfsvfs, B_FALSE); error = zfs_sb_hold(zc->zc_name, FTAG, &zsb, B_FALSE);
if (error) if (error)
return (error); return (error);
void *buf = kmem_alloc(bufsize, KM_SLEEP); buf = kmem_alloc(bufsize, KM_SLEEP);
error = zfs_userspace_many(zfsvfs, zc->zc_objset_type, &zc->zc_cookie, error = zfs_userspace_many(zsb, zc->zc_objset_type, &zc->zc_cookie,
buf, &zc->zc_nvlist_dst_size); buf, &zc->zc_nvlist_dst_size);
if (error == 0) { if (error == 0) {
@ -4144,12 +4105,9 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
zc->zc_nvlist_dst_size); zc->zc_nvlist_dst_size);
} }
kmem_free(buf, bufsize); kmem_free(buf, bufsize);
zfsvfs_rele(zfsvfs, FTAG); zfs_sb_rele(zsb, FTAG);
return (error); return (error);
#else
return (ENOTSUP);
#endif /* HAVE_ZPL */
} }
/* /*
@ -4162,25 +4120,24 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
static int static int
zfs_ioc_userspace_upgrade(zfs_cmd_t *zc) zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
{ {
#ifdef HAVE_ZPL
objset_t *os; objset_t *os;
int error = 0; int error = 0;
zfsvfs_t *zfsvfs; zfs_sb_t *zsb;
if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) { if (get_zfs_sb(zc->zc_name, &zsb) == 0) {
if (!dmu_objset_userused_enabled(zfsvfs->z_os)) { if (!dmu_objset_userused_enabled(zsb->z_os)) {
/* /*
* If userused is not enabled, it may be because the * If userused is not enabled, it may be because the
* objset needs to be closed & reopened (to grow the * objset needs to be closed & reopened (to grow the
* objset_phys_t). Suspend/resume the fs will do that. * objset_phys_t). Suspend/resume the fs will do that.
*/ */
error = zfs_suspend_fs(zfsvfs); error = zfs_suspend_fs(zsb);
if (error == 0) if (error == 0)
error = zfs_resume_fs(zfsvfs, zc->zc_name); error = zfs_resume_fs(zsb, zc->zc_name);
} }
if (error == 0) if (error == 0)
error = dmu_objset_userspace_upgrade(zfsvfs->z_os); error = dmu_objset_userspace_upgrade(zsb->z_os);
VFS_RELE(zfsvfs->z_vfs); mntput(zsb->z_vfs);
} else { } else {
/* XXX kind of reading contents without owning */ /* XXX kind of reading contents without owning */
error = dmu_objset_hold(zc->zc_name, FTAG, &os); error = dmu_objset_hold(zc->zc_name, FTAG, &os);
@ -4192,9 +4149,6 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
} }
return (error); return (error);
#else
return (ENOTSUP);
#endif /* HAVE_ZPL */
} }
/* /*
@ -4456,10 +4410,10 @@ zfs_smb_acl_purge(znode_t *dzp)
{ {
zap_cursor_t zc; zap_cursor_t zc;
zap_attribute_t zap; zap_attribute_t zap;
zfsvfs_t *zfsvfs = dzp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(dzp);
int error; int error;
for (zap_cursor_init(&zc, zfsvfs->z_os, dzp->z_id); for (zap_cursor_init(&zc, zsb->z_os, dzp->z_id);
(error = zap_cursor_retrieve(&zc, &zap)) == 0; (error = zap_cursor_retrieve(&zc, &zap)) == 0;
zap_cursor_advance(&zc)) { zap_cursor_advance(&zc)) {
if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred, if ((error = VOP_REMOVE(ZTOV(dzp), zap.za_name, kcred,
@ -4479,7 +4433,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
znode_t *dzp; znode_t *dzp;
vnode_t *resourcevp = NULL; vnode_t *resourcevp = NULL;
znode_t *sharedir; znode_t *sharedir;
zfsvfs_t *zfsvfs; zfs_sb_t *zsb;
nvlist_t *nvlist; nvlist_t *nvlist;
char *src, *target; char *src, *target;
vattr_t vattr; vattr_t vattr;
@ -4500,17 +4454,17 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
} }
dzp = VTOZ(vp); dzp = VTOZ(vp);
zfsvfs = dzp->z_zfsvfs; zsb = ZTOZSB(dzp);
ZFS_ENTER(zfsvfs); ZFS_ENTER(zsb);
/* /*
* Create share dir if its missing. * Create share dir if its missing.
*/ */
mutex_enter(&zfsvfs->z_lock); mutex_enter(&zsb->z_lock);
if (zfsvfs->z_shares_dir == 0) { if (zsb->z_shares_dir == 0) {
dmu_tx_t *tx; dmu_tx_t *tx;
tx = dmu_tx_create(zfsvfs->z_os); tx = dmu_tx_create(zsb->z_os);
dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE, dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, TRUE,
ZFS_SHARES_DIR); ZFS_SHARES_DIR);
dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL); dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
@ -4518,29 +4472,28 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
if (error) { if (error) {
dmu_tx_abort(tx); dmu_tx_abort(tx);
} else { } else {
error = zfs_create_share_dir(zfsvfs, tx); error = zfs_create_share_dir(zsb, tx);
dmu_tx_commit(tx); dmu_tx_commit(tx);
} }
if (error) { if (error) {
mutex_exit(&zfsvfs->z_lock); mutex_exit(&zsb->z_lock);
VN_RELE(vp); VN_RELE(vp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zsb);
return (error); return (error);
} }
} }
mutex_exit(&zfsvfs->z_lock); mutex_exit(&zsb->z_lock);
ASSERT(zfsvfs->z_shares_dir); ASSERT(zsb->z_shares_dir);
if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &sharedir)) != 0) { if ((error = zfs_zget(zsb, zsb->z_shares_dir, &sharedir)) != 0) {
VN_RELE(vp); VN_RELE(vp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zsb);
return (error); return (error);
} }
switch (zc->zc_cookie) { switch (zc->zc_cookie) {
case ZFS_SMB_ACL_ADD: case ZFS_SMB_ACL_ADD:
vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE; vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
vattr.va_type = VREG;
vattr.va_mode = S_IFREG|0777; vattr.va_mode = S_IFREG|0777;
vattr.va_uid = 0; vattr.va_uid = 0;
vattr.va_gid = 0; vattr.va_gid = 0;
@ -4565,7 +4518,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
if ((error = get_nvlist(zc->zc_nvlist_src, if ((error = get_nvlist(zc->zc_nvlist_src,
zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) { zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) {
VN_RELE(vp); VN_RELE(vp);
ZFS_EXIT(zfsvfs); ZFS_EXIT(zsb);
return (error); return (error);
} }
if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) || if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
@ -4573,7 +4526,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
&target)) { &target)) {
VN_RELE(vp); VN_RELE(vp);
VN_RELE(ZTOV(sharedir)); VN_RELE(ZTOV(sharedir));
ZFS_EXIT(zfsvfs); ZFS_EXIT(zsb);
nvlist_free(nvlist); nvlist_free(nvlist);
return (error); return (error);
} }
@ -4594,7 +4547,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
VN_RELE(vp); VN_RELE(vp);
VN_RELE(ZTOV(sharedir)); VN_RELE(ZTOV(sharedir));
ZFS_EXIT(zfsvfs); ZFS_EXIT(zsb);
return (error); return (error);
#else #else

View File

@ -22,7 +22,6 @@
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
*/ */
#ifdef HAVE_ZPL
#include <sys/types.h> #include <sys/types.h>
#include <sys/param.h> #include <sys/param.h>
@ -411,9 +410,9 @@ zfs_log_symlink(zilog_t *zilog, dmu_tx_t *tx, uint64_t txtype,
lr->lr_uid = zp->z_uid; lr->lr_uid = zp->z_uid;
lr->lr_gid = zp->z_gid; lr->lr_gid = zp->z_gid;
lr->lr_mode = zp->z_mode; lr->lr_mode = zp->z_mode;
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(zp->z_zfsvfs), &lr->lr_gen, (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_GEN(ZTOZSB(zp)), &lr->lr_gen,
sizeof (uint64_t)); sizeof (uint64_t));
(void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(zp->z_zfsvfs), (void) sa_lookup(zp->z_sa_hdl, SA_ZPL_CRTIME(ZTOZSB(zp)),
lr->lr_crtime, sizeof (uint64_t) * 2); lr->lr_crtime, sizeof (uint64_t) * 2);
bcopy(name, (char *)(lr + 1), namesize); bcopy(name, (char *)(lr + 1), namesize);
bcopy(link, (char *)(lr + 1) + namesize, linksize); bcopy(link, (char *)(lr + 1) + namesize, linksize);
@ -496,7 +495,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
itx = zil_itx_create(txtype, sizeof (*lr) + itx = zil_itx_create(txtype, sizeof (*lr) +
(write_state == WR_COPIED ? len : 0)); (write_state == WR_COPIED ? len : 0));
lr = (lr_write_t *)&itx->itx_lr; lr = (lr_write_t *)&itx->itx_lr;
if (write_state == WR_COPIED && dmu_read(zp->z_zfsvfs->z_os, if (write_state == WR_COPIED && dmu_read(ZTOZSB(zp)->z_os,
zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) { zp->z_id, off, len, lr + 1, DMU_READ_NO_PREFETCH) != 0) {
zil_itx_destroy(itx); zil_itx_destroy(itx);
itx = zil_itx_create(txtype, sizeof (*lr)); itx = zil_itx_create(txtype, sizeof (*lr));
@ -513,7 +512,7 @@ zfs_log_write(zilog_t *zilog, dmu_tx_t *tx, int txtype,
lr->lr_blkoff = 0; lr->lr_blkoff = 0;
BP_ZERO(&lr->lr_blkptr); BP_ZERO(&lr->lr_blkptr);
itx->itx_private = zp->z_zfsvfs; itx->itx_private = ZTOZSB(zp);
if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) && if (!(ioflag & (FSYNC | FDSYNC)) && (zp->z_sync_cnt == 0) &&
(fsync_cnt == 0)) (fsync_cnt == 0))
@ -629,7 +628,7 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
if (zil_replaying(zilog, tx) || zp->z_unlinked) if (zil_replaying(zilog, tx) || zp->z_unlinked)
return; return;
txtype = (zp->z_zfsvfs->z_version < ZPL_VERSION_FUID) ? txtype = (ZTOZSB(zp)->z_version < ZPL_VERSION_FUID) ?
TX_ACL_V0 : TX_ACL; TX_ACL_V0 : TX_ACL;
if (txtype == TX_ACL) if (txtype == TX_ACL)
@ -667,14 +666,14 @@ zfs_log_acl(zilog_t *zilog, dmu_tx_t *tx, znode_t *zp,
start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes); start = (caddr_t)start + ZIL_ACE_LENGTH(aclbytes);
#ifdef HAVE_XVATTR
if (fuidp) { if (fuidp) {
start = zfs_log_fuid_ids(fuidp, start); start = zfs_log_fuid_ids(fuidp, start);
(void) zfs_log_fuid_domains(fuidp, start); (void) zfs_log_fuid_domains(fuidp, start);
} }
#endif /* HAVE_XVATTR */
} }
itx->itx_sync = (zp->z_sync_cnt != 0); itx->itx_sync = (zp->z_sync_cnt != 0);
zil_itx_assign(zilog, itx, tx); zil_itx_assign(zilog, itx, tx);
} }
#endif /* HAVE_ZPL */

View File

@ -134,7 +134,7 @@ zfs_range_lock_writer(znode_t *zp, rl_t *new)
*/ */
end_size = MAX(zp->z_size, new->r_off + len); end_size = MAX(zp->z_size, new->r_off + len);
if (end_size > zp->z_blksz && (!ISP2(zp->z_blksz) || if (end_size > zp->z_blksz && (!ISP2(zp->z_blksz) ||
zp->z_blksz < zp->z_zfsvfs->z_max_blksz)) { zp->z_blksz < ZTOZSB(zp)->z_max_blksz)) {
new->r_off = 0; new->r_off = 0;
new->r_len = UINT64_MAX; new->r_len = UINT64_MAX;
} }

View File

@ -81,7 +81,7 @@ zfs_sa_readlink(znode_t *zp, uio_t *uio)
MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio); MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio);
} else { } else {
dmu_buf_t *dbp; dmu_buf_t *dbp;
if ((error = dmu_buf_hold(zp->z_zfsvfs->z_os, zp->z_id, if ((error = dmu_buf_hold(ZTOZSB(zp)->z_os, zp->z_id,
0, FTAG, &dbp, DMU_READ_NO_PREFETCH)) == 0) { 0, FTAG, &dbp, DMU_READ_NO_PREFETCH)) == 0) {
error = uiomove(dbp->db_data, error = uiomove(dbp->db_data,
MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio); MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio);
@ -107,7 +107,7 @@ zfs_sa_symlink(znode_t *zp, char *link, int len, dmu_tx_t *tx)
dmu_buf_t *dbp; dmu_buf_t *dbp;
zfs_grow_blocksize(zp, len, tx); zfs_grow_blocksize(zp, len, tx);
VERIFY(0 == dmu_buf_hold(zp->z_zfsvfs->z_os, VERIFY(0 == dmu_buf_hold(ZTOZSB(zp)->z_os,
zp->z_id, 0, FTAG, &dbp, DMU_READ_NO_PREFETCH)); zp->z_id, 0, FTAG, &dbp, DMU_READ_NO_PREFETCH));
dmu_buf_will_dirty(dbp, tx); dmu_buf_will_dirty(dbp, tx);
@ -122,13 +122,13 @@ zfs_sa_symlink(znode_t *zp, char *link, int len, dmu_tx_t *tx)
void void
zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap) zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
xoptattr_t *xoap; xoptattr_t *xoap;
ASSERT(MUTEX_HELD(&zp->z_lock)); ASSERT(MUTEX_HELD(&zp->z_lock));
VERIFY((xoap = xva_getxoptattr(xvap)) != NULL); VERIFY((xoap = xva_getxoptattr(xvap)) != NULL);
if (zp->z_is_sa) { if (zp->z_is_sa) {
if (sa_lookup(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs), if (sa_lookup(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zsb),
&xoap->xoa_av_scanstamp, &xoap->xoa_av_scanstamp,
sizeof (xoap->xoa_av_scanstamp)) != 0) sizeof (xoap->xoa_av_scanstamp)) != 0)
return; return;
@ -156,13 +156,13 @@ zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap)
void void
zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx) zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
{ {
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
xoptattr_t *xoap; xoptattr_t *xoap;
ASSERT(MUTEX_HELD(&zp->z_lock)); ASSERT(MUTEX_HELD(&zp->z_lock));
VERIFY((xoap = xva_getxoptattr(xvap)) != NULL); VERIFY((xoap = xva_getxoptattr(xvap)) != NULL);
if (zp->z_is_sa) if (zp->z_is_sa)
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zfsvfs), VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_SCANSTAMP(zsb),
&xoap->xoa_av_scanstamp, &xoap->xoa_av_scanstamp,
sizeof (xoap->xoa_av_scanstamp), tx)); sizeof (xoap->xoa_av_scanstamp), tx));
else { else {
@ -179,7 +179,7 @@ zfs_sa_set_scanstamp(znode_t *zp, xvattr_t *xvap, dmu_tx_t *tx)
xoap->xoa_av_scanstamp, sizeof (xoap->xoa_av_scanstamp)); xoap->xoa_av_scanstamp, sizeof (xoap->xoa_av_scanstamp));
zp->z_pflags |= ZFS_BONUS_SCANSTAMP; zp->z_pflags |= ZFS_BONUS_SCANSTAMP;
VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zfsvfs), VERIFY(0 == sa_update(zp->z_sa_hdl, SA_ZPL_FLAGS(zsb),
&zp->z_pflags, sizeof (uint64_t), tx)); &zp->z_pflags, sizeof (uint64_t), tx));
} }
} }
@ -198,7 +198,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
{ {
dmu_buf_t *db = sa_get_db(hdl); dmu_buf_t *db = sa_get_db(hdl);
znode_t *zp = sa_get_userdata(hdl); znode_t *zp = sa_get_userdata(hdl);
zfsvfs_t *zfsvfs = zp->z_zfsvfs; zfs_sb_t *zsb = ZTOZSB(zp);
int count = 0; int count = 0;
sa_bulk_attr_t *bulk, *sa_attrs; sa_bulk_attr_t *bulk, *sa_attrs;
zfs_acl_locator_cb_t locate = { 0 }; zfs_acl_locator_cb_t locate = { 0 };
@ -216,7 +216,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
* and ready the ACL would require special "locked" * and ready the ACL would require special "locked"
* interfaces that would be messy * interfaces that would be messy
*/ */
if (zp->z_acl_cached == NULL || ZTOV(zp)->v_type == VLNK) if (zp->z_acl_cached == NULL || S_ISLNK(ZTOI(zp)->i_mode))
return; return;
/* /*
@ -237,16 +237,16 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
/* First do a bulk query of the attributes that aren't cached */ /* First do a bulk query of the attributes that aren't cached */
bulk = kmem_alloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP); bulk = kmem_alloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zfsvfs), NULL, &mtime, 16); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs), NULL, &ctime, 16); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &crtime, 16); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zsb), NULL, &crtime, 16);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, &parent, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL, &parent, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zfsvfs), NULL, &xattr, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zsb), NULL, &xattr, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zfsvfs), NULL, &rdev, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zsb), NULL, &rdev, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, &uid, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &uid, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), NULL, &gid, 8); SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &gid, 8);
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zfsvfs), NULL, SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL,
&znode_acl, 88); &znode_acl, 88);
if (sa_bulk_lookup_locked(hdl, bulk, count) != 0) { if (sa_bulk_lookup_locked(hdl, bulk, count) != 0) {
@ -260,42 +260,42 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
*/ */
count = 0; count = 0;
sa_attrs = kmem_zalloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP); sa_attrs = kmem_zalloc(sizeof(sa_bulk_attr_t) * 20, KM_SLEEP);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8); SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zfsvfs), NULL, SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zsb), NULL,
&zp->z_size, 8); &zp->z_size, 8);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GEN(zfsvfs), SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GEN(zsb),
NULL, &zp->z_gen, 8); NULL, &zp->z_gen, 8);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zfsvfs), NULL, &uid, 8); SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zsb), NULL, &uid, 8);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GID(zfsvfs), NULL, &gid, 8); SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_GID(zsb), NULL, &gid, 8);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_PARENT(zfsvfs), SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_PARENT(zsb),
NULL, &parent, 8); NULL, &parent, 8);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_FLAGS(zfsvfs), NULL, SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_FLAGS(zsb), NULL,
&zp->z_pflags, 8); &zp->z_pflags, 8);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_ATIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_ATIME(zsb), NULL,
zp->z_atime, 16); zp->z_atime, 16);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MTIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MTIME(zsb), NULL,
&mtime, 16); &mtime, 16);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CTIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CTIME(zsb), NULL,
&ctime, 16); &ctime, 16);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CRTIME(zfsvfs), NULL, SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_CRTIME(zsb), NULL,
&crtime, 16); &crtime, 16);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_LINKS(zfsvfs), NULL, SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_LINKS(zsb), NULL,
&zp->z_links, 8); &zp->z_links, 8);
if (zp->z_vnode->v_type == VBLK || zp->z_vnode->v_type == VCHR) if (S_ISBLK(ZTOI(zp)->i_mode) || S_ISCHR(ZTOI(zp)->i_mode))
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zfsvfs), NULL, SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zsb), NULL,
&rdev, 8); &rdev, 8);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_COUNT(zfsvfs), NULL, SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_COUNT(zsb), NULL,
&zp->z_acl_cached->z_acl_count, 8); &zp->z_acl_cached->z_acl_count, 8);
if (zp->z_acl_cached->z_version < ZFS_ACL_VERSION_FUID) if (zp->z_acl_cached->z_version < ZFS_ACL_VERSION_FUID)
zfs_acl_xform(zp, zp->z_acl_cached, CRED()); zfs_acl_xform(zp, zp->z_acl_cached, CRED());
locate.cb_aclp = zp->z_acl_cached; locate.cb_aclp = zp->z_acl_cached;
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_ACES(zfsvfs), SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_DACL_ACES(zsb),
zfs_acl_data_locator, &locate, zp->z_acl_cached->z_acl_bytes); zfs_acl_data_locator, &locate, zp->z_acl_cached->z_acl_bytes);
if (xattr) if (xattr)
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_XATTR(zfsvfs), SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_XATTR(zsb),
NULL, &xattr, 8); NULL, &xattr, 8);
#ifdef HAVE_SCANSTAMP #ifdef HAVE_SCANSTAMP
@ -304,7 +304,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
if (zp->z_pflags & ZFS_BONUS_SCANSTAMP) { if (zp->z_pflags & ZFS_BONUS_SCANSTAMP) {
bcopy((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE, bcopy((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE,
scanstamp, AV_SCANSTAMP_SZ); scanstamp, AV_SCANSTAMP_SZ);
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SCANSTAMP(zfsvfs), SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SCANSTAMP(zsb),
NULL, scanstamp, AV_SCANSTAMP_SZ); NULL, scanstamp, AV_SCANSTAMP_SZ);
zp->z_pflags &= ~ZFS_BONUS_SCANSTAMP; zp->z_pflags &= ~ZFS_BONUS_SCANSTAMP;
} }
@ -314,7 +314,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
VERIFY(sa_replace_all_by_template_locked(hdl, sa_attrs, VERIFY(sa_replace_all_by_template_locked(hdl, sa_attrs,
count, tx) == 0); count, tx) == 0);
if (znode_acl.z_acl_extern_obj) if (znode_acl.z_acl_extern_obj)
VERIFY(0 == dmu_object_free(zfsvfs->z_os, VERIFY(0 == dmu_object_free(zsb->z_os,
znode_acl.z_acl_extern_obj, tx)); znode_acl.z_acl_extern_obj, tx));
zp->z_is_sa = B_TRUE; zp->z_is_sa = B_TRUE;
@ -328,7 +328,7 @@ done:
void void
zfs_sa_upgrade_txholds(dmu_tx_t *tx, znode_t *zp) zfs_sa_upgrade_txholds(dmu_tx_t *tx, znode_t *zp)
{ {
if (!zp->z_zfsvfs->z_use_sa || zp->z_is_sa) if (!ZTOZSB(zp)->z_use_sa || zp->z_is_sa)
return; return;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff