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:
parent
6149f4c45f
commit
3558fd73b5
|
@ -75,7 +75,7 @@ typedef struct dsl_pool {
|
|||
struct dsl_dir *dp_free_dir;
|
||||
struct dsl_dataset *dp_origin_snap;
|
||||
uint64_t dp_root_dir_obj;
|
||||
struct taskq *dp_vnrele_taskq;
|
||||
struct taskq *dp_iput_taskq;
|
||||
|
||||
/* No lock needed - sync context only */
|
||||
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_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,
|
||||
const char *tag, uint64_t *now, dmu_tx_t *tx);
|
||||
|
|
|
@ -200,13 +200,13 @@ typedef struct zfs_acl_ids {
|
|||
#define ZFS_ACL_PASSTHROUGH_X 5
|
||||
|
||||
struct znode;
|
||||
struct zfsvfs;
|
||||
struct zfs_sb;
|
||||
|
||||
#ifdef _KERNEL
|
||||
int zfs_acl_ids_create(struct znode *, int, vattr_t *,
|
||||
cred_t *, vsecattr_t *, 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_setacl(struct znode *, vsecattr_t *, boolean_t, cred_t *);
|
||||
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 *,
|
||||
struct znode *, struct znode *, cred_t *cr);
|
||||
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 **);
|
||||
int zfs_aclset_common(struct znode *, zfs_acl_t *, cred_t *, dmu_tx_t *);
|
||||
uint64_t zfs_external_acl(struct znode *);
|
||||
|
|
|
@ -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_destroy(zfs_dirlock_t *, znode_t *, dmu_tx_t *, int,
|
||||
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 *);
|
||||
extern void zfs_mknode(znode_t *, vattr_t *, dmu_tx_t *, cred_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 boolean_t zfs_dirempty(znode_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_get_xattrdir(znode_t *, vnode_t **, cred_t *, int);
|
||||
extern int zfs_make_xattrdir(znode_t *, vattr_t *, vnode_t **, cred_t *);
|
||||
extern int zfs_get_xattrdir(znode_t *, struct inode **, cred_t *, int);
|
||||
extern int zfs_make_xattrdir(znode_t *, vattr_t *, struct inode **, cred_t *);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -100,24 +100,24 @@ typedef struct zfs_fuid_info {
|
|||
|
||||
#ifdef _KERNEL
|
||||
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,
|
||||
uint64_t, uint64_t, zfs_fuid_type_t);
|
||||
extern void zfs_fuid_destroy(zfsvfs_t *);
|
||||
extern uint64_t zfs_fuid_create_cred(zfsvfs_t *, zfs_fuid_type_t,
|
||||
extern void zfs_fuid_destroy(zfs_sb_t *);
|
||||
extern uint64_t zfs_fuid_create_cred(zfs_sb_t *, zfs_fuid_type_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 **);
|
||||
extern void zfs_fuid_map_ids(struct znode *zp, cred_t *cr,
|
||||
uid_t *uid, uid_t *gid);
|
||||
extern zfs_fuid_info_t *zfs_fuid_info_alloc(void);
|
||||
extern void zfs_fuid_info_free(zfs_fuid_info_t *);
|
||||
extern boolean_t zfs_groupmember(zfsvfs_t *, uint64_t, cred_t *);
|
||||
void zfs_fuid_sync(zfsvfs_t *, dmu_tx_t *);
|
||||
extern int zfs_fuid_find_by_domain(zfsvfs_t *, const char *domain,
|
||||
extern boolean_t zfs_groupmember(zfs_sb_t *, uint64_t, cred_t *);
|
||||
void zfs_fuid_sync(zfs_sb_t *, dmu_tx_t *);
|
||||
extern int zfs_fuid_find_by_domain(zfs_sb_t *, const char *domain,
|
||||
char **retdomain, boolean_t addok);
|
||||
extern const char *zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx);
|
||||
extern void zfs_fuid_txhold(zfsvfs_t *zfsvfs, dmu_tx_t *tx);
|
||||
extern const char *zfs_fuid_find_by_idx(zfs_sb_t *zsb, uint32_t idx);
|
||||
extern void zfs_fuid_txhold(zfs_sb_t *zsb, dmu_tx_t *tx);
|
||||
#endif
|
||||
|
||||
char *zfs_fuid_idx_domain(avl_tree_t *, uint32_t);
|
||||
|
|
|
@ -38,13 +38,15 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct zfsvfs zfsvfs_t;
|
||||
struct zfs_sb;
|
||||
struct znode;
|
||||
|
||||
struct zfsvfs {
|
||||
vfs_t *z_vfs; /* generic fs struct */
|
||||
zfsvfs_t *z_parent; /* parent fs */
|
||||
typedef struct zfs_sb {
|
||||
struct vfsmount *z_vfs; /* generic vfs struct */
|
||||
struct super_block *z_sb; /* generic super_block */
|
||||
struct zfs_sb *z_parent; /* parent fs */
|
||||
objset_t *z_os; /* objset reference */
|
||||
uint64_t z_flags; /* super_block flags */
|
||||
uint64_t z_root; /* id of root znode */
|
||||
uint64_t z_unlinkedobj; /* id of unlinked zapobj */
|
||||
uint64_t z_max_blksz; /* maximum block size for files */
|
||||
|
@ -87,6 +89,8 @@ struct zfsvfs {
|
|||
|
||||
#define ZFS_SUPER_MAGIC 0x2fc12fc1
|
||||
|
||||
#define ZSB_XATTR_USER 0x0001 /* Enable user xattrs */
|
||||
|
||||
|
||||
/*
|
||||
* 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 int zfs_suspend_fs(zfsvfs_t *zfsvfs);
|
||||
extern int zfs_resume_fs(zfsvfs_t *zfsvfs, const char *osname);
|
||||
extern int zfs_userspace_one(zfsvfs_t *zfsvfs, zfs_userquota_prop_t type,
|
||||
extern int zfs_suspend_fs(zfs_sb_t *zsb);
|
||||
extern int zfs_resume_fs(zfs_sb_t *zsb, const char *osname);
|
||||
extern int zfs_userspace_one(zfs_sb_t *zsb, zfs_userquota_prop_t type,
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
extern int zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers);
|
||||
extern int zfsvfs_create(const char *name, zfsvfs_t **zfvp);
|
||||
extern void zfsvfs_free(zfsvfs_t *zfsvfs);
|
||||
extern int zfs_set_version(zfs_sb_t *zsb, uint64_t newvers);
|
||||
extern int zfs_sb_create(const char *name, zfs_sb_t **zsbp);
|
||||
extern void zfs_sb_free(zfs_sb_t *zsb);
|
||||
extern int zfs_check_global_label(const char *dsname, const char *hexsl);
|
||||
|
||||
extern int zfs_register_callbacks(vfs_t *vfsp);
|
||||
extern void zfs_unregister_callbacks(zfsvfs_t *zfsvfs);
|
||||
extern int zfs_domount(vfs_t *vfsp, char *osname);
|
||||
extern int zfs_umount(vfs_t *vfsp, int fflag, cred_t *cr);
|
||||
extern int zfs_root(vfs_t *vfsp, vnode_t **vpp);
|
||||
extern int zfs_statvfs(vfs_t *vfsp, struct statvfs64 *statp);
|
||||
extern int zfs_vget(vfs_t *vfsp, vnode_t **vpp, fid_t *fidp);
|
||||
extern int zfs_register_callbacks(zfs_sb_t *zsb);
|
||||
extern void zfs_unregister_callbacks(zfs_sb_t *zsb);
|
||||
extern int zfs_domount(struct super_block *sb, void *data, int silent);
|
||||
extern int zfs_umount(struct super_block *sb);
|
||||
extern int zfs_root(zfs_sb_t *zsb, struct inode **ipp);
|
||||
extern int zfs_statvfs(struct dentry *dentry, struct kstatfs *statp);
|
||||
extern int zfs_vget(struct vfsmount *vfsp, struct inode **ipp, fid_t *fidp);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -28,50 +28,48 @@
|
|||
#include <sys/vnode.h>
|
||||
#include <sys/uio.h>
|
||||
#include <sys/cred.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <sys/pathname.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern int zfs_read(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr,
|
||||
caller_context_t *ct);
|
||||
extern int zfs_write(vnode_t *vp, uio_t *uio, int ioflag, cred_t *cr,
|
||||
caller_context_t *ct);
|
||||
extern int zfs_lookup(vnode_t *dvp, char *nm, vnode_t **vpp,
|
||||
struct pathname *pnp, int flags, vnode_t *rdir, cred_t *cr,
|
||||
caller_context_t *ct, int *direntflags, pathname_t *realpnp);
|
||||
extern int zfs_create(vnode_t *dvp, char *name, vattr_t *vap,
|
||||
int excl, int mode, vnode_t **vpp, cred_t *cr, int flag,
|
||||
caller_context_t *ct, vsecattr_t *vsecp);
|
||||
extern int zfs_remove(vnode_t *dvp, char *name, cred_t *cr,
|
||||
caller_context_t *ct, int flags);
|
||||
extern int zfs_mkdir(vnode_t *dvp, char *dirname, vattr_t *vap,
|
||||
vnode_t **vpp, cred_t *cr, caller_context_t *ct, int flags,
|
||||
vsecattr_t *vsecp);
|
||||
extern int zfs_rmdir(vnode_t *dvp, char *name, vnode_t *cwd, cred_t *cr,
|
||||
caller_context_t *ct, int flags);
|
||||
extern int zfs_fsync(vnode_t *vp, int syncflag, cred_t *cr,
|
||||
caller_context_t *ct);
|
||||
extern int zfs_getattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
|
||||
caller_context_t *ct);
|
||||
extern int zfs_setattr(vnode_t *vp, vattr_t *vap, int flags, cred_t *cr,
|
||||
caller_context_t *ct);
|
||||
extern int zfs_rename(vnode_t *sdvp, char *snm, vnode_t *tdvp, char *tnm,
|
||||
cred_t *cr, caller_context_t *ct, int flags);
|
||||
extern int zfs_symlink(vnode_t *dvp, char *name, vattr_t *vap, char *link,
|
||||
cred_t *cr, caller_context_t *ct, int flags);
|
||||
extern int zfs_readlink(vnode_t *vp, uio_t *uio, cred_t *cr,
|
||||
caller_context_t *ct);
|
||||
extern int zfs_link(vnode_t *tdvp, vnode_t *svp, char *name, cred_t *cr,
|
||||
caller_context_t *ct, int flags);
|
||||
extern void zfs_inactive(vnode_t *vp, cred_t *cr, caller_context_t *ct);
|
||||
extern int zfs_space(vnode_t *vp, int cmd, flock64_t *bfp, int flag,
|
||||
offset_t offset, cred_t *cr, caller_context_t *ct);
|
||||
extern int zfs_fid(vnode_t *vp, fid_t *fidp, caller_context_t *ct);
|
||||
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);
|
||||
extern int zfs_read(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
|
||||
extern int zfs_write(struct inode *ip, uio_t *uio, int ioflag, cred_t *cr);
|
||||
extern int zfs_access(struct inode *ip, int mode, int flag, cred_t *cr);
|
||||
extern int zfs_lookup(struct inode *dip, char *nm, struct inode **ipp,
|
||||
int flags, cred_t *cr, int *direntflags, pathname_t *realpnp);
|
||||
extern int zfs_create(struct inode *dip, char *name, vattr_t *vap, int excl,
|
||||
int mode, struct inode **ipp, cred_t *cr, int flag, vsecattr_t *vsecp);
|
||||
extern int zfs_remove(struct inode *dip, char *name, cred_t *cr);
|
||||
extern int zfs_mkdir(struct inode *dip, char *dirname, vattr_t *vap,
|
||||
struct inode **ipp, cred_t *cr, int flags, vsecattr_t *vsecp);
|
||||
extern int zfs_rmdir(struct inode *dip, char *name, struct inode *cwd,
|
||||
cred_t *cr, int flags);
|
||||
extern int zfs_readdir(struct inode *ip, void *dirent, filldir_t filldir,
|
||||
loff_t *pos, cred_t *cr);
|
||||
extern int zfs_fsync(struct inode *ip, int syncflag, cred_t *cr);
|
||||
extern int zfs_getattr(struct inode *ip, struct kstat *stat, int flag,
|
||||
cred_t *cr);
|
||||
extern int zfs_setattr(struct inode *ip, struct iattr *attr, int flag,
|
||||
cred_t *cr);
|
||||
extern int zfs_rename(struct inode *sdip, char *snm, struct inode *tdip,
|
||||
char *tnm, cred_t *cr, int flags);
|
||||
extern int zfs_symlink(struct inode *dip, char *name, vattr_t *vap,
|
||||
char *link, struct inode **ipp, cred_t *cr, int flags);
|
||||
extern int zfs_follow_link(struct dentry *dentry, struct nameidata *nd);
|
||||
extern int zfs_readlink(struct inode *ip, uio_t *uio, cred_t *cr);
|
||||
extern int zfs_link(struct inode *tdip, struct inode *sip,
|
||||
char *name, cred_t *cr);
|
||||
extern void zfs_inactive(struct inode *ip);
|
||||
extern int zfs_space(struct inode *ip, int cmd, flock64_t *bfp, int flag,
|
||||
offset_t offset, cred_t *cr);
|
||||
extern int zfs_fid(struct inode *ip, fid_t *fidp);
|
||||
extern int zfs_getsecattr(struct inode *ip, vsecattr_t *vsecp, int flag,
|
||||
cred_t *cr);
|
||||
extern int zfs_setsecattr(struct inode *ip, vsecattr_t *vsecp, int flag,
|
||||
cred_t *cr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -69,7 +69,7 @@ extern "C" {
|
|||
pflags |= attr; \
|
||||
else \
|
||||
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)); \
|
||||
}
|
||||
|
||||
|
@ -181,8 +181,6 @@ typedef struct zfs_dirlock {
|
|||
} zfs_dirlock_t;
|
||||
|
||||
typedef struct znode {
|
||||
struct zfsvfs *z_zfsvfs;
|
||||
vnode_t *z_vnode;
|
||||
uint64_t z_id; /* object ID for this znode */
|
||||
kmutex_t z_lock; /* znode modification lock */
|
||||
krwlock_t z_parent_lock; /* parent lock for directories */
|
||||
|
@ -235,48 +233,52 @@ typedef struct znode {
|
|||
/*
|
||||
* Convert between znode pointers and inode pointers
|
||||
*/
|
||||
#define ZTOI(ZP) (&((ZP)->z_inode))
|
||||
#define ITOZ(IP) (container_of((IP), znode_t, z_inode))
|
||||
|
||||
/* XXX - REMOVE ME ONCE THE OTHER BUILD ISSUES ARE RESOLVED */
|
||||
#define ZTOV(ZP) ((ZP)->z_vnode)
|
||||
#define VTOZ(VP) ((znode_t *)(VP)->v_data)
|
||||
#define ZTOI(znode) (&((znode)->z_inode))
|
||||
#define ITOZ(inode) (container_of((inode), znode_t, z_inode))
|
||||
#define VTOZSB(vfs) ((zfs_sb_t *)((vfs)->mnt_sb->s_fs_info))
|
||||
#define ZTOZSB(znode) ((zfs_sb_t *)(ZTOI(znode)->i_sb->s_fs_info))
|
||||
#define ITOZSB(inode) ((zfs_sb_t *)((inode)->i_sb->s_fs_info))
|
||||
|
||||
#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_EXIT() must be called before exitting the vop.
|
||||
* 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); \
|
||||
if ((zfsvfs)->z_unmounted) { \
|
||||
ZFS_EXIT(zfsvfs); \
|
||||
rrw_enter(&(zsb)->z_teardown_lock, RW_READER, FTAG); \
|
||||
if ((zsb)->z_unmounted) { \
|
||||
ZFS_EXIT(zsb); \
|
||||
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) \
|
||||
if ((zp)->z_sa_hdl == NULL) { \
|
||||
ZFS_EXIT((zp)->z_zfsvfs); \
|
||||
ZFS_EXIT(ZTOZSB(zp)); \
|
||||
return (EIO); \
|
||||
} \
|
||||
}
|
||||
|
||||
/*
|
||||
* Macros for dealing with dmu_buf_hold
|
||||
*/
|
||||
#define ZFS_OBJ_HASH(obj_num) ((obj_num) & (ZFS_OBJ_MTX_SZ - 1))
|
||||
#define ZFS_OBJ_MUTEX(zfsvfs, obj_num) \
|
||||
(&(zfsvfs)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)])
|
||||
#define ZFS_OBJ_HOLD_ENTER(zfsvfs, obj_num) \
|
||||
mutex_enter(ZFS_OBJ_MUTEX((zfsvfs), (obj_num)))
|
||||
#define ZFS_OBJ_HOLD_TRYENTER(zfsvfs, obj_num) \
|
||||
mutex_tryenter(ZFS_OBJ_MUTEX((zfsvfs), (obj_num)))
|
||||
#define ZFS_OBJ_HOLD_EXIT(zfsvfs, obj_num) \
|
||||
mutex_exit(ZFS_OBJ_MUTEX((zfsvfs), (obj_num)))
|
||||
#define ZFS_OBJ_MUTEX(zsb, obj_num) \
|
||||
(&(zsb)->z_hold_mtx[ZFS_OBJ_HASH(obj_num)])
|
||||
#define ZFS_OBJ_HOLD_ENTER(zsb, obj_num) \
|
||||
mutex_enter(ZFS_OBJ_MUTEX((zsb), (obj_num)))
|
||||
#define ZFS_OBJ_HOLD_TRYENTER(zsb, obj_num) \
|
||||
mutex_tryenter(ZFS_OBJ_MUTEX((zsb), (obj_num)))
|
||||
#define ZFS_OBJ_HOLD_EXIT(zsb, obj_num) \
|
||||
mutex_exit(ZFS_OBJ_MUTEX((zsb), (obj_num)))
|
||||
|
||||
/*
|
||||
* Macros to encode/decode ZFS stored time values from/to struct timespec
|
||||
|
@ -296,15 +298,15 @@ typedef struct znode {
|
|||
/*
|
||||
* Timestamp defines
|
||||
*/
|
||||
#define ACCESSED (AT_ATIME)
|
||||
#define STATE_CHANGED (AT_CTIME)
|
||||
#define CONTENT_MODIFIED (AT_MTIME | AT_CTIME)
|
||||
#define ACCESSED (ATTR_ATIME)
|
||||
#define STATE_CHANGED (ATTR_CTIME)
|
||||
#define CONTENT_MODIFIED (ATTR_MTIME | ATTR_CTIME)
|
||||
|
||||
#define ZFS_ACCESSTIME_STAMP(zfsvfs, zp) \
|
||||
if ((zfsvfs)->z_atime && !((zfsvfs)->z_vfs->vfs_flag & VFS_RDONLY)) \
|
||||
#define ZFS_ACCESSTIME_STAMP(zsb, zp) \
|
||||
if ((zsb)->z_atime && !((zsb)->z_vfs->mnt_flags & MNT_READONLY)) \
|
||||
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_create_fs(objset_t *os, cred_t *cr, nvlist_t *,
|
||||
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 void zfs_znode_init(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 void zfs_zinactive(znode_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 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 int zfs_get_zplprop(objset_t *os, zfs_prop_t prop, uint64_t *value);
|
||||
extern int zfs_get_stats(objset_t *os, nvlist_t *nv);
|
||||
extern void zfs_znode_dmu_fini(znode_t *);
|
||||
extern 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_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,
|
||||
znode_t *zp, uint64_t off, uint64_t len);
|
||||
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,
|
||||
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_upgrade(zfsvfs_t *zfsvfs, dmu_tx_t *tx);
|
||||
extern int zfs_create_share_dir(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(zfs_sb_t *zsb, dmu_tx_t *tx);
|
||||
|
||||
#if defined(HAVE_UIO_RW)
|
||||
extern caddr_t zfs_map_page(page_t *, enum seg_rw);
|
||||
|
|
|
@ -910,10 +910,8 @@ dmu_objset_snapshot_one(const char *name, void *arg)
|
|||
* permission checks for the starting dataset have already been
|
||||
* performed in zfs_secpolicy_snapshot()
|
||||
*/
|
||||
#ifdef HAVE_ZPL
|
||||
if (sn->recursive && (err = zfs_secpolicy_snapshot_perms(name, CRED())))
|
||||
return (err);
|
||||
#endif
|
||||
|
||||
err = dmu_objset_hold(name, sn, &os);
|
||||
if (err != 0)
|
||||
|
|
|
@ -2364,13 +2364,11 @@ dsl_snapshot_rename_one(const char *name, void *arg)
|
|||
* For recursive snapshot renames the parent won't be changing
|
||||
* so we just pass name for both the to/from argument.
|
||||
*/
|
||||
#ifdef HAVE_ZPL
|
||||
err = zfs_secpolicy_rename_perms(snapname, snapname, CRED());
|
||||
if (err != 0) {
|
||||
strfree(snapname);
|
||||
return (err == ENOENT ? 0 : err);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* XXX: Ignore for SPL version until mounting the FS is supported */
|
||||
#if defined(_KERNEL) && !defined(HAVE_SPL)
|
||||
|
|
|
@ -92,7 +92,7 @@ dsl_pool_open_impl(spa_t *spa, uint64_t txg)
|
|||
|
||||
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);
|
||||
|
||||
return (dp);
|
||||
|
@ -214,7 +214,7 @@ dsl_pool_close(dsl_pool_t *dp)
|
|||
dsl_scan_fini(dp);
|
||||
rw_destroy(&dp->dp_config_rwlock);
|
||||
mutex_destroy(&dp->dp_lock);
|
||||
taskq_destroy(dp->dp_vnrele_taskq);
|
||||
taskq_destroy(dp->dp_iput_taskq);
|
||||
if (dp->dp_blkstats)
|
||||
kmem_free(dp->dp_blkstats, sizeof (zfs_all_blkstats_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 *
|
||||
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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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) VOP_CLOSE(vp, oflags, 1, 0, kcred, NULL);
|
||||
VN_RELE(vp);
|
||||
}
|
||||
|
||||
(void) vn_remove(temp, UIO_SYSSPACE, RMFILE);
|
||||
|
|
|
@ -130,7 +130,6 @@ vdev_file_close(vdev_t *vd)
|
|||
(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,
|
||||
kcred, NULL);
|
||||
VN_RELE(vf->vf_vnode);
|
||||
}
|
||||
|
||||
vd->vdev_delayed_close = B_FALSE;
|
||||
|
|
|
@ -345,7 +345,7 @@ zfs_external_acl(znode_t *zp)
|
|||
* 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)
|
||||
return (acl_phys.z_acl_extern_obj);
|
||||
else {
|
||||
|
@ -368,23 +368,23 @@ static int
|
|||
zfs_acl_znode_info(znode_t *zp, int *aclsize, int *aclcount,
|
||||
zfs_acl_phys_t *aclphys)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
uint64_t acl_count;
|
||||
int size;
|
||||
int error;
|
||||
|
||||
ASSERT(MUTEX_HELD(&zp->z_acl_lock));
|
||||
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)
|
||||
return (error);
|
||||
*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)
|
||||
return (error);
|
||||
*aclcount = acl_count;
|
||||
} 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)
|
||||
return (error);
|
||||
|
||||
|
@ -418,7 +418,7 @@ zfs_znode_acl_version(znode_t *zp)
|
|||
* changed.
|
||||
*/
|
||||
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)
|
||||
return (acl_phys.z_acl_version);
|
||||
else {
|
||||
|
@ -444,7 +444,7 @@ zfs_acl_version(int version)
|
|||
static int
|
||||
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 *
|
||||
|
@ -531,7 +531,7 @@ zfs_acl_valid_ace_type(uint_t type, uint_t flags)
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -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
|
||||
*/
|
||||
|
||||
if (obj_type == VDIR &&
|
||||
if (S_ISDIR(obj_mode) &&
|
||||
(iflags & (ACE_FILE_INHERIT_ACE|ACE_DIRECTORY_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.
|
||||
*/
|
||||
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,
|
||||
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;
|
||||
if (entry_type != ACE_OWNER && entry_type != OWNING_GROUP &&
|
||||
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) ?
|
||||
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
|
||||
*/
|
||||
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)
|
||||
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
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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 &&
|
||||
entry_type != OWNING_GROUP &&
|
||||
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) ?
|
||||
ZFS_ACE_GROUP : ZFS_ACE_USER);
|
||||
} else {
|
||||
|
@ -767,7 +767,7 @@ zfs_copy_fuid_2_ace(zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr,
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
*/
|
||||
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)
|
||||
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 *
|
||||
sizeof (zfs_object_ace_t));
|
||||
aclp->z_ops = zfs_acl_fuid_ops;
|
||||
VERIFY(zfs_copy_ace_2_fuid(zp->z_zfsvfs, ZTOV(zp)->v_type, aclp,
|
||||
oldaclp, newaclnode->z_acldata, aclp->z_acl_count,
|
||||
VERIFY(zfs_copy_ace_2_fuid(ZTOZSB(zp), ZTOI(zp)->i_mode,
|
||||
aclp, oldaclp, newaclnode->z_acldata, aclp->z_acl_count,
|
||||
&newaclnode->z_size, NULL, cr) == 0);
|
||||
newaclnode->z_ace_count = aclp->z_acl_count;
|
||||
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 (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,
|
||||
aclnode->z_acldata, DMU_READ_PREFETCH);
|
||||
} else {
|
||||
|
@ -1108,7 +1108,7 @@ zfs_acl_node_read(znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp,
|
|||
aclnode->z_size);
|
||||
}
|
||||
} 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);
|
||||
}
|
||||
|
||||
|
@ -1295,7 +1295,7 @@ int
|
|||
zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
||||
{
|
||||
int error;
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
dmu_object_type_t otype;
|
||||
zfs_acl_locator_cb_t locate = { 0 };
|
||||
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_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));
|
||||
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));
|
||||
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));
|
||||
|
||||
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?
|
||||
*/
|
||||
if (!zfsvfs->z_use_fuids) {
|
||||
if (!zsb->z_use_fuids) {
|
||||
otype = DMU_OT_OLDACL;
|
||||
} else {
|
||||
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);
|
||||
ASSERT(aclp->z_version >= ZFS_ACL_VERSION_FUID);
|
||||
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 */
|
||||
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);
|
||||
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));
|
||||
} else { /* Painful legacy way */
|
||||
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;
|
||||
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)
|
||||
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 &&
|
||||
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)
|
||||
return (error);
|
||||
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 == DMU_OT_ACL ?
|
||||
DMU_OT_SYSACL : DMU_OT_NONE,
|
||||
otype == DMU_OT_ACL ?
|
||||
DN_MAX_BONUSLEN : 0, tx);
|
||||
} else {
|
||||
(void) dmu_object_set_blocksize(zfsvfs->z_os,
|
||||
(void) dmu_object_set_blocksize(zsb->z_os,
|
||||
aoid, aclp->z_acl_bytes, 0, tx);
|
||||
}
|
||||
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)) {
|
||||
if (aclnode->z_ace_count == 0)
|
||||
continue;
|
||||
dmu_write(zfsvfs->z_os, aoid, off,
|
||||
dmu_write(zsb->z_os, aoid, off,
|
||||
aclnode->z_size, aclnode->z_acldata, tx);
|
||||
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?
|
||||
*/
|
||||
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);
|
||||
if (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;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
|
@ -1444,19 +1444,19 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx)
|
|||
}
|
||||
|
||||
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;
|
||||
uint64_t who;
|
||||
int new_count, new_bytes;
|
||||
int ace_size;
|
||||
int entry_type;
|
||||
int entry_type;
|
||||
uint16_t iflags, type;
|
||||
uint32_t access_mask;
|
||||
zfs_acl_node_t *newnode;
|
||||
size_t abstract_size = aclp->z_ops.ace_abstract_size();
|
||||
void *zacep;
|
||||
uint32_t owner, group, everyone;
|
||||
size_t abstract_size = aclp->z_ops.ace_abstract_size();
|
||||
void *zacep;
|
||||
uint32_t owner, group, everyone;
|
||||
uint32_t deny1, deny2, allow0;
|
||||
|
||||
new_count = new_bytes = 0;
|
||||
|
@ -1516,7 +1516,7 @@ zfs_acl_chmod(zfsvfs_t *zfsvfs, uint64_t mode, zfs_acl_t *aclp)
|
|||
* Limit permissions to be no greater than
|
||||
* group permissions
|
||||
*/
|
||||
if (zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) {
|
||||
if (zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) {
|
||||
if (!(mode & S_IRGRP))
|
||||
access_mask &= ~ACE_READ_DATA;
|
||||
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);
|
||||
*aclp = zfs_acl_alloc(zfs_acl_version_zp(zp));
|
||||
(*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_acl_lock);
|
||||
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
|
||||
*/
|
||||
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);
|
||||
|
||||
if ((zfsvfs->z_acl_inherit == ZFS_ACL_RESTRICTED) &&
|
||||
if ((zsb->z_acl_inherit == ZFS_ACL_RESTRICTED) &&
|
||||
(aclp->z_ops.ace_type_get(acep) == ALLOW)) {
|
||||
mask &= ~RESTRICTED_CLEAR;
|
||||
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?
|
||||
*/
|
||||
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);
|
||||
|
||||
if ((vtype == VDIR) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
|
||||
if (S_ISDIR(obj_mode) && (iflags & ACE_DIRECTORY_INHERIT_ACE))
|
||||
return (1);
|
||||
else if (iflags & ACE_FILE_INHERIT_ACE)
|
||||
return (!((vtype == VDIR) &&
|
||||
return (!(S_ISDIR(obj_mode) &&
|
||||
(iflags & ACE_NO_PROPAGATE_INHERIT_ACE)));
|
||||
return (0);
|
||||
}
|
||||
|
@ -1599,7 +1599,7 @@ zfs_ace_can_use(vtype_t vtype, uint16_t acep_flags)
|
|||
* inherit inheritable ACEs from parent
|
||||
*/
|
||||
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)
|
||||
{
|
||||
void *pacep;
|
||||
|
@ -1612,21 +1612,21 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
|
|||
size_t ace_size;
|
||||
void *data1, *data2;
|
||||
size_t data1sz, data2sz;
|
||||
boolean_t vdir = vtype == VDIR;
|
||||
boolean_t vreg = vtype == VREG;
|
||||
boolean_t vdir = S_ISDIR(obj_mode);
|
||||
boolean_t vreg = S_ISREG(obj_mode);
|
||||
boolean_t passthrough, passthrough_x, noallow;
|
||||
|
||||
passthrough_x =
|
||||
zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X;
|
||||
zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH_X;
|
||||
passthrough = passthrough_x ||
|
||||
zfsvfs->z_acl_inherit == ZFS_ACL_PASSTHROUGH;
|
||||
zsb->z_acl_inherit == ZFS_ACL_PASSTHROUGH;
|
||||
noallow =
|
||||
zfsvfs->z_acl_inherit == ZFS_ACL_NOALLOW;
|
||||
zsb->z_acl_inherit == ZFS_ACL_NOALLOW;
|
||||
|
||||
*need_chmod = B_TRUE;
|
||||
pacep = NULL;
|
||||
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);
|
||||
while ((pacep = zfs_acl_next_ace(paclp, pacep, &who,
|
||||
&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);
|
||||
|
||||
if (!zfs_ace_can_use(vtype, iflags))
|
||||
if (!zfs_ace_can_use(obj_mode, iflags))
|
||||
continue;
|
||||
|
||||
/*
|
||||
|
@ -1690,7 +1690,7 @@ zfs_acl_inherit(zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp,
|
|||
newflags &= ~ALL_INHERIT;
|
||||
aclp->z_ops.ace_flags_set(acep,
|
||||
newflags|ACE_INHERITED_ACE);
|
||||
zfs_restricted_update(zfsvfs, aclp, acep);
|
||||
zfs_restricted_update(zsb, aclp, acep);
|
||||
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)
|
||||
{
|
||||
int error;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
zfs_acl_t *paclp;
|
||||
#ifdef HAVE_KSID
|
||||
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;
|
||||
|
||||
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 ((error = zfs_vsec_2_aclp(zfsvfs, vap->va_type, vsecp, cr,
|
||||
&acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0)
|
||||
if ((error = zfs_vsec_2_aclp(zsb, vap->va_mode, vsecp,
|
||||
cr, &acl_ids->z_fuidp, &acl_ids->z_aclp)) != 0)
|
||||
return (error);
|
||||
|
||||
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.
|
||||
*/
|
||||
if ((flag & IS_ROOT_NODE) || zfsvfs->z_replay ||
|
||||
((flag & IS_XATTR) && (vap->va_type == VDIR))) {
|
||||
acl_ids->z_fuid = zfs_fuid_create(zfsvfs,
|
||||
(uint64_t)vap->va_uid, cr,
|
||||
ZFS_OWNER, &acl_ids->z_fuidp);
|
||||
acl_ids->z_fgid = zfs_fuid_create(zfsvfs,
|
||||
(uint64_t)vap->va_gid, cr,
|
||||
ZFS_GROUP, &acl_ids->z_fuidp);
|
||||
if ((flag & IS_ROOT_NODE) || zsb->z_replay ||
|
||||
((flag & IS_XATTR) && (S_ISDIR(vap->va_mode)))) {
|
||||
acl_ids->z_fuid = zfs_fuid_create(zsb, (uint64_t)vap->va_uid,
|
||||
cr, ZFS_OWNER, &acl_ids->z_fuidp);
|
||||
acl_ids->z_fgid = zfs_fuid_create(zsb, (uint64_t)vap->va_gid,
|
||||
cr, ZFS_GROUP, &acl_ids->z_fuidp);
|
||||
gid = vap->va_gid;
|
||||
} 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);
|
||||
acl_ids->z_fgid = 0;
|
||||
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,
|
||||
cr, ZFS_GROUP, &acl_ids->z_fuidp);
|
||||
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;
|
||||
|
||||
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);
|
||||
|
||||
if (zfsvfs->z_use_fuids &&
|
||||
if (zsb->z_use_fuids &&
|
||||
IS_EPHEMERAL(acl_ids->z_fgid)) {
|
||||
domain = zfs_fuid_idx_domain(
|
||||
&zfsvfs->z_fuid_idx,
|
||||
&zsb->z_fuid_idx,
|
||||
FUID_INDEX(acl_ids->z_fgid));
|
||||
rid = FUID_RID(acl_ids->z_fgid);
|
||||
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);
|
||||
}
|
||||
} 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);
|
||||
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) &&
|
||||
(vap->va_type == VDIR)) {
|
||||
(S_ISDIR(vap->va_mode))) {
|
||||
acl_ids->z_mode |= S_ISGID;
|
||||
} else {
|
||||
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) {
|
||||
mutex_enter(&dzp->z_acl_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_XATTR)) {
|
||||
VERIFY(0 == zfs_acl_node_read(dzp, B_TRUE,
|
||||
&paclp, B_FALSE));
|
||||
acl_ids->z_aclp = zfs_acl_inherit(zfsvfs,
|
||||
vap->va_type, paclp, acl_ids->z_mode, &need_chmod);
|
||||
acl_ids->z_aclp = zfs_acl_inherit(zsb,
|
||||
vap->va_mode, paclp, acl_ids->z_mode, &need_chmod);
|
||||
inherited = B_TRUE;
|
||||
} else {
|
||||
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_acl_lock);
|
||||
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_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
|
||||
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) ||
|
||||
zfs_fuid_overquota(zfsvfs, B_TRUE, acl_ids->z_fgid));
|
||||
return (zfs_fuid_overquota(zsb, B_FALSE, acl_ids->z_fuid) ||
|
||||
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;
|
||||
|
||||
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));
|
||||
else {
|
||||
zfs_acl_node_t *aclnode;
|
||||
|
@ -1971,7 +1969,7 @@ zfs_getacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
|||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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)
|
||||
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;
|
||||
aclnode = zfs_acl_node_alloc(aclcnt * sizeof (zfs_object_ace_t));
|
||||
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,
|
||||
aclcnt, &aclnode->z_size)) != 0) {
|
||||
zfs_acl_free(aclp);
|
||||
|
@ -1995,7 +1993,7 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
|
|||
return (error);
|
||||
}
|
||||
} 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,
|
||||
&aclnode->z_size, fuidp, cr)) != 0) {
|
||||
zfs_acl_free(aclp);
|
||||
|
@ -2031,8 +2029,8 @@ zfs_vsec_2_aclp(zfsvfs_t *zfsvfs, vtype_t obj_type,
|
|||
int
|
||||
zfs_setacl(znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zilog_t *zilog = zfsvfs->z_log;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
zilog_t *zilog = zsb->z_log;
|
||||
ulong_t mask = vsecp->vsa_mask & (VSA_ACE | VSA_ACECNT);
|
||||
dmu_tx_t *tx;
|
||||
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)))
|
||||
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);
|
||||
if (error)
|
||||
return (error);
|
||||
|
@ -2067,13 +2065,13 @@ top:
|
|||
mutex_enter(&zp->z_acl_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);
|
||||
|
||||
fuid_dirtied = zfsvfs->z_fuid_dirty;
|
||||
fuid_dirtied = zsb->z_fuid_dirty;
|
||||
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
|
||||
|
@ -2081,7 +2079,7 @@ top:
|
|||
*/
|
||||
|
||||
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) {
|
||||
dmu_tx_hold_free(tx, acl_obj, 0,
|
||||
DMU_OBJECT_END);
|
||||
|
@ -2116,7 +2114,7 @@ top:
|
|||
zp->z_acl_cached = aclp;
|
||||
|
||||
if (fuid_dirtied)
|
||||
zfs_fuid_sync(zfsvfs, tx);
|
||||
zfs_fuid_sync(zsb, tx);
|
||||
|
||||
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)
|
||||
{
|
||||
if ((v4_mode & WRITE_MASK) &&
|
||||
(zp->z_zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) &&
|
||||
(!IS_DEVVP(ZTOV(zp)) ||
|
||||
(IS_DEVVP(ZTOV(zp)) && (v4_mode & WRITE_MASK_ATTRS)))) {
|
||||
(ZTOZSB(zp)->z_vfs->mnt_flags & MNT_READONLY) &&
|
||||
(!S_ISDEV(ZTOI(zp)->i_mode) ||
|
||||
(S_ISDEV(ZTOI(zp)->i_mode) && (v4_mode & WRITE_MASK_ATTRS)))) {
|
||||
return (EROFS);
|
||||
}
|
||||
|
||||
|
@ -2149,9 +2147,9 @@ zfs_zaccess_dataset_check(znode_t *zp, uint32_t v4_mode)
|
|||
* Only check for READONLY on non-directories.
|
||||
*/
|
||||
if ((v4_mode & WRITE_MASK_DATA) &&
|
||||
(((ZTOV(zp)->v_type != VDIR) &&
|
||||
((!S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
(zp->z_pflags & (ZFS_READONLY | ZFS_IMMUTABLE))) ||
|
||||
(ZTOV(zp)->v_type == VDIR &&
|
||||
(S_ISDIR(ZTOI(zp)->i_mode) &&
|
||||
(zp->z_pflags & ZFS_IMMUTABLE)))) {
|
||||
return (EPERM);
|
||||
}
|
||||
|
@ -2198,11 +2196,11 @@ static int
|
|||
zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
||||
boolean_t anyaccess, cred_t *cr)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
zfs_acl_t *aclp;
|
||||
int error;
|
||||
uid_t uid = crgetuid(cr);
|
||||
uint64_t who;
|
||||
uint64_t who;
|
||||
uint16_t type, iflags;
|
||||
uint16_t entry_type;
|
||||
uint32_t access_mask;
|
||||
|
@ -2231,7 +2229,8 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
|||
if (!zfs_acl_valid_ace_type(type, iflags))
|
||||
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;
|
||||
|
||||
/* 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;
|
||||
/*FALLTHROUGH*/
|
||||
case ACE_IDENTIFIER_GROUP:
|
||||
checkit = zfs_groupmember(zfsvfs, who, cr);
|
||||
checkit = zfs_groupmember(zsb, who, cr);
|
||||
break;
|
||||
case ACE_EVERYONE:
|
||||
checkit = B_TRUE;
|
||||
|
@ -2263,7 +2262,7 @@ zfs_zaccess_aces_check(znode_t *zp, uint32_t *working_mode,
|
|||
if (entry_type == 0) {
|
||||
uid_t newid;
|
||||
|
||||
newid = zfs_fuid_map_id(zfsvfs, who, cr,
|
||||
newid = zfs_fuid_map_id(zsb, who, cr,
|
||||
ZFS_ACE_USER);
|
||||
if (newid != IDMAP_WK_CREATOR_OWNER_UID &&
|
||||
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) {
|
||||
uid_t owner;
|
||||
|
||||
owner = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_uid, cr, ZFS_OWNER);
|
||||
return (secpolicy_vnode_any_access(cr, ZTOV(zp), owner) == 0);
|
||||
owner = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
|
||||
return (secpolicy_vnode_any_access(cr, ZTOI(zp), owner) == 0);
|
||||
}
|
||||
return (B_TRUE);
|
||||
}
|
||||
|
@ -2335,7 +2334,7 @@ static int
|
|||
zfs_zaccess_common(znode_t *zp, uint32_t v4_mode, uint32_t *working_mode,
|
||||
boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
int err;
|
||||
|
||||
*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
|
||||
*/
|
||||
if (v4_mode == 0 || zfsvfs->z_replay) {
|
||||
if (v4_mode == 0 || zsb->z_replay) {
|
||||
*working_mode = 0;
|
||||
return (0);
|
||||
}
|
||||
|
@ -2391,7 +2390,7 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
|
|||
return (EACCES);
|
||||
|
||||
is_attr = ((zdp->z_pflags & ZFS_XATTR) &&
|
||||
(ZTOV(zdp)->v_type == VDIR));
|
||||
(S_ISDIR(ZTOI(zdp)->i_mode)));
|
||||
if (is_attr)
|
||||
goto slow;
|
||||
|
||||
|
@ -2439,9 +2438,9 @@ zfs_fastaccesschk_execute(znode_t *zdp, cred_t *cr)
|
|||
|
||||
slow:
|
||||
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);
|
||||
ZFS_EXIT(zdp->z_zfsvfs);
|
||||
ZFS_EXIT(ZTOZSB(zdp));
|
||||
return (error);
|
||||
}
|
||||
|
||||
|
@ -2456,13 +2455,13 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
|||
uint32_t working_mode;
|
||||
int error;
|
||||
int is_attr;
|
||||
boolean_t check_privs;
|
||||
boolean_t check_privs;
|
||||
znode_t *xzp;
|
||||
znode_t *check_zp = zp;
|
||||
znode_t *check_zp = zp;
|
||||
mode_t needed_bits;
|
||||
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
|
||||
|
@ -2471,11 +2470,11 @@ zfs_zaccess(znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr)
|
|||
uint64_t parent;
|
||||
|
||||
if ((error = sa_lookup(zp->z_sa_hdl,
|
||||
SA_ZPL_PARENT(zp->z_zfsvfs), &parent,
|
||||
SA_ZPL_PARENT(ZTOZSB(zp)), &parent,
|
||||
sizeof (parent))) != 0)
|
||||
return (error);
|
||||
|
||||
if ((error = zfs_zget(zp->z_zfsvfs,
|
||||
if ((error = zfs_zget(ZTOZSB(zp),
|
||||
parent, &xzp)) != 0) {
|
||||
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
|
||||
* in needed_bits. Map the bits mapped by working_mode (currently
|
||||
* missing) in missing_bits.
|
||||
* Map the bits required to the standard inode flags
|
||||
* S_IRUSR|S_IWUSR|S_IXUSR in the needed_bits. Map the bits
|
||||
* mapped by working_mode (currently missing) in missing_bits.
|
||||
* Call secpolicy_vnode_access2() with (needed_bits & ~checkmode),
|
||||
* 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|
|
||||
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|
|
||||
ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
|
||||
needed_bits |= VWRITE;
|
||||
needed_bits |= S_IWUSR;
|
||||
if (working_mode & ACE_EXECUTE)
|
||||
needed_bits |= VEXEC;
|
||||
needed_bits |= S_IXUSR;
|
||||
|
||||
if ((error = zfs_zaccess_common(check_zp, mode, &working_mode,
|
||||
&check_privs, skipaclchk, cr)) == 0) {
|
||||
if (is_attr)
|
||||
VN_RELE(ZTOV(xzp));
|
||||
return (secpolicy_vnode_access2(cr, ZTOV(zp), owner,
|
||||
iput(ZTOI(xzp));
|
||||
return (secpolicy_vnode_access2(cr, ZTOI(zp), owner,
|
||||
needed_bits, needed_bits));
|
||||
}
|
||||
|
||||
if (error && !check_privs) {
|
||||
if (is_attr)
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
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|
|
||||
ACE_READ_ACL|ACE_READ_ATTRIBUTES|ACE_SYNCHRONIZE))
|
||||
checkmode |= VREAD;
|
||||
checkmode |= S_IRUSR;
|
||||
if (working_mode & (ACE_WRITE_DATA|ACE_WRITE_NAMED_ATTRS|
|
||||
ACE_APPEND_DATA|ACE_WRITE_ATTRIBUTES|ACE_SYNCHRONIZE))
|
||||
checkmode |= VWRITE;
|
||||
checkmode |= S_IWUSR;
|
||||
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);
|
||||
|
||||
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) {
|
||||
error = secpolicy_vnode_access2(cr, ZTOV(zp), owner,
|
||||
error = secpolicy_vnode_access2(cr, ZTOI(zp), owner,
|
||||
needed_bits, needed_bits);
|
||||
}
|
||||
|
||||
|
||||
if (is_attr)
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
|
||||
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()
|
||||
*/
|
||||
int
|
||||
|
@ -2627,10 +2626,10 @@ zfs_delete_final_check(znode_t *zp, znode_t *dzp,
|
|||
int error;
|
||||
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),
|
||||
downer, available_perms, VWRITE|VEXEC);
|
||||
error = secpolicy_vnode_access2(cr, ZTOI(dzp),
|
||||
downer, available_perms, S_IWUSR|S_IXUSR);
|
||||
|
||||
if (error == 0)
|
||||
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
|
||||
*/
|
||||
|
||||
available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : VWRITE;
|
||||
available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : VEXEC;
|
||||
available_perms = (dzp_working_mode & ACE_WRITE_DATA) ? 0 : S_IWUSR;
|
||||
available_perms |= (dzp_working_mode & ACE_EXECUTE) ? 0 : S_IXUSR;
|
||||
|
||||
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)
|
||||
return (EACCES);
|
||||
|
||||
add_perm = (ZTOV(szp)->v_type == VDIR) ?
|
||||
add_perm = S_ISDIR(ZTOI(szp)->i_mode) ?
|
||||
ACE_ADD_SUBDIRECTORY : ACE_ADD_FILE;
|
||||
|
||||
/*
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
@ -62,12 +61,12 @@
|
|||
* of names after deciding which is the appropriate lookup interface.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
int error;
|
||||
|
||||
if (zfsvfs->z_norm) {
|
||||
if (zsb->z_norm) {
|
||||
matchtype_t mt = MT_FIRST;
|
||||
boolean_t conflict = B_FALSE;
|
||||
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
|
||||
* 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);
|
||||
if (!error && deflags)
|
||||
*deflags = conflict ? ED_CASE_CONFLICT : 0;
|
||||
} 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);
|
||||
|
||||
#ifdef HAVE_DNLC
|
||||
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);
|
||||
}
|
||||
|
@ -137,12 +138,14 @@ int
|
|||
zfs_dirent_lock(zfs_dirlock_t **dlpp, znode_t *dzp, char *name, znode_t **zpp,
|
||||
int flag, int *direntflags, pathname_t *realpnp)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
zfs_dirlock_t *dl;
|
||||
boolean_t update;
|
||||
boolean_t exact;
|
||||
uint64_t zoid;
|
||||
#ifdef HAVE_DNLC
|
||||
vnode_t *vp = NULL;
|
||||
#endif /* HAVE_DNLC */
|
||||
int error = 0;
|
||||
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
|
||||
* 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
|
||||
* 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.
|
||||
*/
|
||||
exact =
|
||||
((zfsvfs->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) ||
|
||||
((zfsvfs->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK));
|
||||
((zsb->z_case == ZFS_CASE_INSENSITIVE) && (flag & ZCIEXACT)) ||
|
||||
((zsb->z_case == ZFS_CASE_MIXED) && !(flag & ZCILOOK));
|
||||
|
||||
/*
|
||||
* 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
|
||||
* case for performance improvement?
|
||||
*/
|
||||
update = !zfsvfs->z_norm ||
|
||||
((zfsvfs->z_case == ZFS_CASE_MIXED) &&
|
||||
!(zfsvfs->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK));
|
||||
update = !zsb->z_norm ||
|
||||
((zsb->z_case == ZFS_CASE_MIXED) &&
|
||||
!(zsb->z_norm & ~U8_TEXTPREP_TOUPPER) && !(flag & ZCILOOK));
|
||||
|
||||
/*
|
||||
* 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)
|
||||
cmpflags = 0;
|
||||
else
|
||||
cmpflags = zfsvfs->z_norm;
|
||||
cmpflags = zsb->z_norm;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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));
|
||||
if (error == 0)
|
||||
error = (zoid == 0 ? ENOENT : 0);
|
||||
} else {
|
||||
#ifdef HAVE_DNLC
|
||||
if (update)
|
||||
vp = dnlc_lookup(ZTOV(dzp), name);
|
||||
vp = dnlc_lookup(ZTOI(dzp), name);
|
||||
if (vp == DNLC_NO_VNODE) {
|
||||
VN_RELE(vp);
|
||||
iput(vp);
|
||||
error = ENOENT;
|
||||
} else if (vp) {
|
||||
if (flag & ZNEW) {
|
||||
zfs_dirent_unlock(dl);
|
||||
VN_RELE(vp);
|
||||
iput(vp);
|
||||
return (EEXIST);
|
||||
}
|
||||
*dlpp = dl;
|
||||
*zpp = VTOZ(vp);
|
||||
return (0);
|
||||
} else {
|
||||
error = zfs_match_find(zfsvfs, dzp, name, exact,
|
||||
error = zfs_match_find(zsb, dzp, name, exact,
|
||||
update, direntflags, realpnp, &zoid);
|
||||
}
|
||||
#else
|
||||
error = zfs_match_find(zsb, dzp, name, exact,
|
||||
update, direntflags, realpnp, &zoid);
|
||||
#endif /* HAVE_DNLC */
|
||||
}
|
||||
if (error) {
|
||||
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);
|
||||
return (EEXIST);
|
||||
}
|
||||
error = zfs_zget(zfsvfs, zoid, zpp);
|
||||
error = zfs_zget(zsb, zoid, zpp);
|
||||
if (error) {
|
||||
zfs_dirent_unlock(dl);
|
||||
return (error);
|
||||
}
|
||||
#ifdef HAVE_DNLC
|
||||
if (!(flag & ZXATTR) && update)
|
||||
dnlc_update(ZTOV(dzp), name, ZTOV(*zpp));
|
||||
dnlc_update(ZTOI(dzp), name, ZTOI(*zpp));
|
||||
#endif /* HAVE_DNLC */
|
||||
}
|
||||
|
||||
*dlpp = dl;
|
||||
|
@ -377,7 +387,7 @@ zfs_dirent_unlock(zfs_dirlock_t *dl)
|
|||
* special pseudo-directory.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
zfs_dirlock_t *dl;
|
||||
|
@ -386,31 +396,35 @@ zfs_dirlook(znode_t *dzp, char *name, vnode_t **vpp, int flags,
|
|||
uint64_t parent;
|
||||
|
||||
if (name[0] == 0 || (name[0] == '.' && name[1] == 0)) {
|
||||
*vpp = ZTOV(dzp);
|
||||
VN_HOLD(*vpp);
|
||||
*ipp = ZTOI(dzp);
|
||||
igrab(*ipp);
|
||||
} 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
|
||||
* the vp for the snapshot directory.
|
||||
*/
|
||||
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);
|
||||
if (parent == dzp->z_id && zfsvfs->z_parent != zfsvfs) {
|
||||
error = zfsctl_root_lookup(zfsvfs->z_parent->z_ctldir,
|
||||
"snapshot", vpp, NULL, 0, NULL, kcred,
|
||||
#ifdef HAVE_SNAPSHOT
|
||||
if (parent == dzp->z_id && zsb->z_parent != zsb) {
|
||||
error = zfsctl_root_lookup(zsb->z_parent->z_ctldir,
|
||||
"snapshot", ipp, NULL, 0, NULL, kcred,
|
||||
NULL, NULL, NULL);
|
||||
return (error);
|
||||
}
|
||||
#endif /* HAVE_SNAPSHOT */
|
||||
rw_enter(&dzp->z_parent_lock, RW_READER);
|
||||
error = zfs_zget(zfsvfs, parent, &zp);
|
||||
error = zfs_zget(zsb, parent, &zp);
|
||||
if (error == 0)
|
||||
*vpp = ZTOV(zp);
|
||||
*ipp = ZTOI(zp);
|
||||
rw_exit(&dzp->z_parent_lock);
|
||||
#ifdef HAVE_SNAPSHOT
|
||||
} else if (zfs_has_ctldir(dzp) && strcmp(name, ZFS_CTLDIR_NAME) == 0) {
|
||||
*vpp = zfsctl_root(dzp);
|
||||
*ipp = zfsctl_root(dzp);
|
||||
#endif /* HAVE_SNAPSHOT */
|
||||
} else {
|
||||
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);
|
||||
if (error == 0) {
|
||||
*vpp = ZTOV(zp);
|
||||
*ipp = ZTOI(zp);
|
||||
zfs_dirent_unlock(dl);
|
||||
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
|
||||
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_links == 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.
|
||||
*/
|
||||
void
|
||||
zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
||||
zfs_unlinked_drain(zfs_sb_t *zsb)
|
||||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
|
@ -475,7 +489,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
|||
/*
|
||||
* 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_advance(&zc)) {
|
||||
|
||||
|
@ -483,8 +497,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
|||
* See what kind of object we have in list
|
||||
*/
|
||||
|
||||
error = dmu_object_info(zfsvfs->z_os,
|
||||
zap.za_first_integer, &doi);
|
||||
error = dmu_object_info(zsb->z_os, zap.za_first_integer, &doi);
|
||||
if (error != 0)
|
||||
continue;
|
||||
|
||||
|
@ -494,7 +507,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
|||
* We need to re-mark these list entries for deletion,
|
||||
* 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.
|
||||
|
@ -506,7 +519,7 @@ zfs_unlinked_drain(zfsvfs_t *zfsvfs)
|
|||
continue;
|
||||
|
||||
zp->z_unlinked = B_TRUE;
|
||||
VN_RELE(ZTOV(zp));
|
||||
iput(ZTOI(zp));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
}
|
||||
|
@ -529,35 +542,34 @@ zfs_purgedir(znode_t *dzp)
|
|||
zap_attribute_t zap;
|
||||
znode_t *xzp;
|
||||
dmu_tx_t *tx;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
zfs_dirlock_t dl;
|
||||
int skipped = 0;
|
||||
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;
|
||||
zap_cursor_advance(&zc)) {
|
||||
error = zfs_zget(zfsvfs,
|
||||
error = zfs_zget(zsb,
|
||||
ZFS_DIRENT_OBJ(zap.za_first_integer), &xzp);
|
||||
if (error) {
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
ASSERT((ZTOV(xzp)->v_type == VREG) ||
|
||||
(ZTOV(xzp)->v_type == VLNK));
|
||||
ASSERT(S_ISREG(ZTOI(xzp)->i_mode)||S_ISLNK(ZTOI(xzp)->i_mode));
|
||||
|
||||
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_zap(tx, dzp->z_id, FALSE, zap.za_name);
|
||||
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 ? */
|
||||
zfs_sa_upgrade_txholds(tx, xzp);
|
||||
error = dmu_tx_assign(tx, TXG_WAIT);
|
||||
if (error) {
|
||||
dmu_tx_abort(tx);
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
skipped += 1;
|
||||
continue;
|
||||
}
|
||||
|
@ -570,7 +582,7 @@ zfs_purgedir(znode_t *dzp)
|
|||
skipped += 1;
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
}
|
||||
zap_cursor_fini(&zc);
|
||||
if (error != ENOENT)
|
||||
|
@ -581,8 +593,8 @@ zfs_purgedir(znode_t *dzp)
|
|||
void
|
||||
zfs_rmnode(znode_t *zp)
|
||||
{
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
objset_t *os = zfsvfs->z_os;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
objset_t *os = zsb->z_os;
|
||||
znode_t *xzp = NULL;
|
||||
dmu_tx_t *tx;
|
||||
uint64_t acl_obj;
|
||||
|
@ -590,19 +602,20 @@ zfs_rmnode(znode_t *zp)
|
|||
int error;
|
||||
|
||||
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 (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) {
|
||||
/*
|
||||
* Not enough space to delete some xattrs.
|
||||
* Leave it in the unlinked set.
|
||||
*/
|
||||
zfs_znode_dmu_fini(zp);
|
||||
zfs_znode_free(zp);
|
||||
zfs_inode_destroy(ZTOI(zp));
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -616,7 +629,7 @@ zfs_rmnode(znode_t *zp)
|
|||
* Not enough space. Leave the file in the unlinked set.
|
||||
*/
|
||||
zfs_znode_dmu_fini(zp);
|
||||
zfs_znode_free(zp);
|
||||
zfs_inode_destroy(ZTOI(zp));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -624,10 +637,10 @@ zfs_rmnode(znode_t *zp)
|
|||
* If the file has extended attributes, we're going to unlink
|
||||
* 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));
|
||||
if (error == 0 && xattr_obj) {
|
||||
error = zfs_zget(zfsvfs, xattr_obj, &xzp);
|
||||
error = zfs_zget(zsb, xattr_obj, &xzp);
|
||||
ASSERT(error == 0);
|
||||
}
|
||||
|
||||
|
@ -638,9 +651,9 @@ zfs_rmnode(znode_t *zp)
|
|||
*/
|
||||
tx = dmu_tx_create(os);
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
if (acl_obj)
|
||||
|
@ -656,7 +669,7 @@ zfs_rmnode(znode_t *zp)
|
|||
*/
|
||||
dmu_tx_abort(tx);
|
||||
zfs_znode_dmu_fini(zp);
|
||||
zfs_znode_free(zp);
|
||||
zfs_inode_destroy(ZTOI(zp));
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -665,7 +678,7 @@ zfs_rmnode(znode_t *zp)
|
|||
mutex_enter(&xzp->z_lock);
|
||||
xzp->z_unlinked = B_TRUE; /* mark xzp for deletion */
|
||||
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));
|
||||
mutex_exit(&xzp->z_lock);
|
||||
zfs_unlinked_add(xzp, tx);
|
||||
|
@ -673,14 +686,14 @@ zfs_rmnode(znode_t *zp)
|
|||
|
||||
/* Remove this znode from the unlinked set */
|
||||
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);
|
||||
|
||||
dmu_tx_commit(tx);
|
||||
out:
|
||||
if (xzp)
|
||||
VN_RELE(ZTOV(xzp));
|
||||
iput(ZTOI(xzp));
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
|
@ -688,7 +701,7 @@ zfs_dirent(znode_t *zp, uint64_t mode)
|
|||
{
|
||||
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;
|
||||
return (de);
|
||||
}
|
||||
|
@ -700,10 +713,9 @@ int
|
|||
zfs_link_create(zfs_dirlock_t *dl, znode_t *zp, dmu_tx_t *tx, int flag)
|
||||
{
|
||||
znode_t *dzp = dl->dl_dzp;
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
vnode_t *vp = ZTOV(zp);
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
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];
|
||||
uint64_t mtime[2], ctime[2];
|
||||
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);
|
||||
}
|
||||
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));
|
||||
|
||||
}
|
||||
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));
|
||||
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));
|
||||
|
||||
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));
|
||||
zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime,
|
||||
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_links += zp_is_dir;
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
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));
|
||||
zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE);
|
||||
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);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
@ -773,18 +787,18 @@ zfs_dropname(zfs_dirlock_t *dl, znode_t *zp, znode_t *dzp, dmu_tx_t *tx,
|
|||
{
|
||||
int error;
|
||||
|
||||
if (zp->z_zfsvfs->z_norm) {
|
||||
if (((zp->z_zfsvfs->z_case == ZFS_CASE_INSENSITIVE) &&
|
||||
if (ZTOZSB(zp)->z_norm) {
|
||||
if (((ZTOZSB(zp)->z_case == ZFS_CASE_INSENSITIVE) &&
|
||||
(flag & ZCIEXACT)) ||
|
||||
((zp->z_zfsvfs->z_case == ZFS_CASE_MIXED) &&
|
||||
((ZTOZSB(zp)->z_case == ZFS_CASE_MIXED) &&
|
||||
!(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);
|
||||
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);
|
||||
} else {
|
||||
error = zap_remove(zp->z_zfsvfs->z_os,
|
||||
error = zap_remove(ZTOZSB(zp)->z_os,
|
||||
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)
|
||||
{
|
||||
znode_t *dzp = dl->dl_dzp;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
vnode_t *vp = ZTOV(zp);
|
||||
int zp_is_dir = (vp->v_type == VDIR);
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
int zp_is_dir = S_ISDIR(ZTOI(zp)->i_mode);
|
||||
boolean_t unlinked = B_FALSE;
|
||||
sa_bulk_attr_t bulk[5];
|
||||
uint64_t mtime[2], ctime[2];
|
||||
int count = 0;
|
||||
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 (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);
|
||||
|
||||
if (zp_is_dir && !zfs_dirempty(zp)) {
|
||||
mutex_exit(&zp->z_lock);
|
||||
vn_vfsunlock(vp);
|
||||
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);
|
||||
if (error != 0) {
|
||||
mutex_exit(&zp->z_lock);
|
||||
vn_vfsunlock(vp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
if (zp->z_links <= zp_is_dir) {
|
||||
zfs_panic_recover("zfs: link count on %s is %u, "
|
||||
"should be at least %u",
|
||||
zp->z_vnode->v_path ? zp->z_vnode->v_path :
|
||||
"<unknown>", (int)zp->z_links,
|
||||
zp_is_dir + 1);
|
||||
zfs_panic_recover("zfs: link count on %lu is %u, "
|
||||
"should be at least %u", zp->z_id,
|
||||
(int)zp->z_links, zp_is_dir + 1);
|
||||
zp->z_links = zp_is_dir + 1;
|
||||
}
|
||||
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;
|
||||
unlinked = B_TRUE;
|
||||
} 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));
|
||||
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));
|
||||
zfs_tstamp_update_setup(zp, STATE_CHANGED, mtime, ctime,
|
||||
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));
|
||||
error = sa_bulk_update(zp->z_sa_hdl, bulk, count, tx);
|
||||
count = 0;
|
||||
ASSERT(error == 0);
|
||||
mutex_exit(&zp->z_lock);
|
||||
vn_vfsunlock(vp);
|
||||
} else {
|
||||
error = zfs_dropname(dl, zp, dzp, tx, flag);
|
||||
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);
|
||||
dzp->z_size--; /* one dirent removed */
|
||||
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));
|
||||
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));
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb),
|
||||
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));
|
||||
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));
|
||||
zfs_tstamp_update_setup(dzp, CONTENT_MODIFIED, mtime, ctime, B_TRUE);
|
||||
error = sa_bulk_update(dzp->z_sa_hdl, bulk, count, tx);
|
||||
|
@ -914,38 +916,40 @@ zfs_dirempty(znode_t *dzp)
|
|||
}
|
||||
|
||||
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;
|
||||
dmu_tx_t *tx;
|
||||
int error;
|
||||
zfs_acl_ids_t acl_ids;
|
||||
boolean_t fuid_dirtied;
|
||||
#ifdef DEBUG
|
||||
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);
|
||||
|
||||
if ((error = zfs_acl_ids_create(zp, IS_XATTR, vap, cr, NULL,
|
||||
&acl_ids)) != 0)
|
||||
return (error);
|
||||
if (zfs_acl_ids_overquota(zfsvfs, &acl_ids)) {
|
||||
if (zfs_acl_ids_overquota(zsb, &acl_ids)) {
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
return (EDQUOT);
|
||||
}
|
||||
|
||||
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 +
|
||||
ZFS_SA_BASE_ATTR_SIZE);
|
||||
dmu_tx_hold_sa(tx, zp->z_sa_hdl, B_TRUE);
|
||||
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)
|
||||
zfs_fuid_txhold(zfsvfs, tx);
|
||||
zfs_fuid_txhold(zsb, tx);
|
||||
error = dmu_tx_assign(tx, TXG_NOWAIT);
|
||||
if (error) {
|
||||
if (error == ERESTART) {
|
||||
|
@ -960,24 +964,24 @@ top:
|
|||
zfs_mknode(zp, vap, tx, cr, IS_XATTR, &xzp, &acl_ids);
|
||||
|
||||
if (fuid_dirtied)
|
||||
zfs_fuid_sync(zfsvfs, tx);
|
||||
zfs_fuid_sync(zsb, tx);
|
||||
|
||||
#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));
|
||||
ASSERT(error == 0 && parent == zp->z_id);
|
||||
#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));
|
||||
|
||||
(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);
|
||||
|
||||
zfs_acl_ids_free(&acl_ids);
|
||||
dmu_tx_commit(tx);
|
||||
|
||||
*xvpp = ZTOV(xzp);
|
||||
*xipp = ZTOI(xzp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -990,15 +994,15 @@ top:
|
|||
* cr - credentials of caller
|
||||
* 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
|
||||
* error number on failure
|
||||
*/
|
||||
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;
|
||||
zfs_dirlock_t *dl;
|
||||
vattr_t va;
|
||||
|
@ -1009,18 +1013,17 @@ top:
|
|||
return (error);
|
||||
|
||||
if (xzp != NULL) {
|
||||
*xvpp = ZTOV(xzp);
|
||||
*xipp = ZTOI(xzp);
|
||||
zfs_dirent_unlock(dl);
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
||||
if (!(flags & CREATE_XATTR_DIR)) {
|
||||
zfs_dirent_unlock(dl);
|
||||
return (ENOENT);
|
||||
}
|
||||
|
||||
if (zfsvfs->z_vfs->vfs_flag & VFS_RDONLY) {
|
||||
if (zsb->z_vfs->mnt_flags & MNT_READONLY) {
|
||||
zfs_dirent_unlock(dl);
|
||||
return (EROFS);
|
||||
}
|
||||
|
@ -1035,12 +1038,11 @@ top:
|
|||
* Once in a directory the ability to read/write attributes
|
||||
* is controlled by the permissions on the attribute file.
|
||||
*/
|
||||
va.va_mask = AT_TYPE | AT_MODE | AT_UID | AT_GID;
|
||||
va.va_type = VDIR;
|
||||
va.va_mask = ATTR_MODE | ATTR_UID | ATTR_GID;
|
||||
va.va_mode = S_IFDIR | S_ISVTX | 0777;
|
||||
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);
|
||||
|
||||
if (error == ERESTART) {
|
||||
|
@ -1067,25 +1069,24 @@ top:
|
|||
int
|
||||
zfs_sticky_remove_access(znode_t *zdp, znode_t *zp, cred_t *cr)
|
||||
{
|
||||
uid_t uid;
|
||||
uid_t uid;
|
||||
uid_t downer;
|
||||
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);
|
||||
|
||||
if ((zdp->z_mode & S_ISVTX) == 0)
|
||||
return (0);
|
||||
|
||||
downer = zfs_fuid_map_id(zfsvfs, zdp->z_uid, cr, ZFS_OWNER);
|
||||
fowner = zfs_fuid_map_id(zfsvfs, zp->z_uid, cr, ZFS_OWNER);
|
||||
downer = zfs_fuid_map_id(zsb, zdp->z_uid, cr, ZFS_OWNER);
|
||||
fowner = zfs_fuid_map_id(zsb, zp->z_uid, cr, ZFS_OWNER);
|
||||
|
||||
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))
|
||||
return (0);
|
||||
else
|
||||
return (secpolicy_vnode_remove(cr));
|
||||
}
|
||||
#endif /* HAVE_ZPL */
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
* 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
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
@ -196,34 +196,34 @@ zfs_fuid_idx_domain(avl_tree_t *idx_tree, uint32_t idx)
|
|||
* Load the fuid table(s) into memory.
|
||||
*/
|
||||
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) {
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
if (zsb->z_fuid_loaded) {
|
||||
rw_exit(&zsb->z_fuid_lock);
|
||||
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,
|
||||
ZFS_FUID_TABLES, 8, 1, &zfsvfs->z_fuid_obj);
|
||||
if (zfsvfs->z_fuid_obj != 0) {
|
||||
zfsvfs->z_fuid_size = zfs_fuid_table_load(zfsvfs->z_os,
|
||||
zfsvfs->z_fuid_obj, &zfsvfs->z_fuid_idx,
|
||||
&zfsvfs->z_fuid_domain);
|
||||
(void) zap_lookup(zsb->z_os, MASTER_NODE_OBJ,
|
||||
ZFS_FUID_TABLES, 8, 1, &zsb->z_fuid_obj);
|
||||
if (zsb->z_fuid_obj != 0) {
|
||||
zsb->z_fuid_size = zfs_fuid_table_load(zsb->z_os,
|
||||
zsb->z_fuid_obj, &zsb->z_fuid_idx,
|
||||
&zsb->z_fuid_domain);
|
||||
}
|
||||
|
||||
zfsvfs->z_fuid_loaded = B_TRUE;
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
zsb->z_fuid_loaded = B_TRUE;
|
||||
rw_exit(&zsb->z_fuid_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* sync out AVL trees to persistent storage.
|
||||
*/
|
||||
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 **fuids;
|
||||
|
@ -234,30 +234,30 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
|
|||
int numnodes;
|
||||
int i;
|
||||
|
||||
if (!zfsvfs->z_fuid_dirty) {
|
||||
if (!zsb->z_fuid_dirty) {
|
||||
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?
|
||||
*/
|
||||
if (zfsvfs->z_fuid_obj == 0) {
|
||||
zfsvfs->z_fuid_obj = dmu_object_alloc(zfsvfs->z_os,
|
||||
if (zsb->z_fuid_obj == 0) {
|
||||
zsb->z_fuid_obj = dmu_object_alloc(zsb->z_os,
|
||||
DMU_OT_FUID, 1 << 14, DMU_OT_FUID_SIZE,
|
||||
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,
|
||||
&zfsvfs->z_fuid_obj, tx) == 0);
|
||||
&zsb->z_fuid_obj, tx) == 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);
|
||||
for (i = 0, domnode = avl_first(&zfsvfs->z_fuid_domain); domnode; i++,
|
||||
domnode = AVL_NEXT(&zfsvfs->z_fuid_domain, domnode)) {
|
||||
for (i = 0, domnode = avl_first(&zsb->z_fuid_domain); domnode; i++,
|
||||
domnode = AVL_NEXT(&zsb->z_fuid_domain, domnode)) {
|
||||
VERIFY(nvlist_alloc(&fuids[i], NV_UNIQUE_NAME, KM_SLEEP) == 0);
|
||||
VERIFY(nvlist_add_uint64(fuids[i], FUID_IDX,
|
||||
domnode->f_idx) == 0);
|
||||
|
@ -275,30 +275,29 @@ zfs_fuid_sync(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
|
|||
VERIFY(nvlist_pack(nvp, &packed, &nvsize,
|
||||
NV_ENCODE_XDR, KM_SLEEP) == 0);
|
||||
nvlist_free(nvp);
|
||||
zfsvfs->z_fuid_size = nvsize;
|
||||
dmu_write(zfsvfs->z_os, zfsvfs->z_fuid_obj, 0,
|
||||
zfsvfs->z_fuid_size, packed, tx);
|
||||
kmem_free(packed, zfsvfs->z_fuid_size);
|
||||
VERIFY(0 == dmu_bonus_hold(zfsvfs->z_os, zfsvfs->z_fuid_obj,
|
||||
zsb->z_fuid_size = nvsize;
|
||||
dmu_write(zsb->z_os, zsb->z_fuid_obj, 0, zsb->z_fuid_size, packed, tx);
|
||||
kmem_free(packed, zsb->z_fuid_size);
|
||||
VERIFY(0 == dmu_bonus_hold(zsb->z_os, zsb->z_fuid_obj,
|
||||
FTAG, &db));
|
||||
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);
|
||||
|
||||
zfsvfs->z_fuid_dirty = B_FALSE;
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
zsb->z_fuid_dirty = B_FALSE;
|
||||
rw_exit(&zsb->z_fuid_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Query domain table for a given domain.
|
||||
*
|
||||
* 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
|
||||
* and sync out the changes.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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);
|
||||
if (retdomain)
|
||||
*retdomain = searchnode.f_ksid->kd_name;
|
||||
if (!zfsvfs->z_fuid_loaded)
|
||||
zfs_fuid_init(zfsvfs);
|
||||
if (!zsb->z_fuid_loaded)
|
||||
zfs_fuid_init(zsb);
|
||||
|
||||
retry:
|
||||
rw_enter(&zfsvfs->z_fuid_lock, rw);
|
||||
findnode = avl_find(&zfsvfs->z_fuid_domain, &searchnode, &loc);
|
||||
rw_enter(&zsb->z_fuid_lock, rw);
|
||||
findnode = avl_find(&zsb->z_fuid_domain, &searchnode, &loc);
|
||||
|
||||
if (findnode) {
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
rw_exit(&zsb->z_fuid_lock);
|
||||
ksiddomain_rele(searchnode.f_ksid);
|
||||
return (findnode->f_idx);
|
||||
} else if (addok) {
|
||||
fuid_domain_t *domnode;
|
||||
uint64_t retidx;
|
||||
|
||||
if (rw == RW_READER && !rw_tryupgrade(&zfsvfs->z_fuid_lock)) {
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
if (rw == RW_READER && !rw_tryupgrade(&zsb->z_fuid_lock)) {
|
||||
rw_exit(&zsb->z_fuid_lock);
|
||||
rw = RW_WRITER;
|
||||
goto retry;
|
||||
}
|
||||
|
@ -343,15 +342,15 @@ retry:
|
|||
domnode = kmem_alloc(sizeof (fuid_domain_t), KM_SLEEP);
|
||||
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(&zfsvfs->z_fuid_idx, domnode);
|
||||
zfsvfs->z_fuid_dirty = B_TRUE;
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
avl_add(&zsb->z_fuid_domain, domnode);
|
||||
avl_add(&zsb->z_fuid_idx, domnode);
|
||||
zsb->z_fuid_dirty = B_TRUE;
|
||||
rw_exit(&zsb->z_fuid_lock);
|
||||
return (retidx);
|
||||
} else {
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
rw_exit(&zsb->z_fuid_lock);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
@ -363,23 +362,23 @@ retry:
|
|||
*
|
||||
*/
|
||||
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;
|
||||
|
||||
if (idx == 0 || !zfsvfs->z_use_fuids)
|
||||
if (idx == 0 || !zsb->z_use_fuids)
|
||||
return (NULL);
|
||||
|
||||
if (!zfsvfs->z_fuid_loaded)
|
||||
zfs_fuid_init(zfsvfs);
|
||||
if (!zsb->z_fuid_loaded)
|
||||
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)
|
||||
domain = zfs_fuid_idx_domain(&zfsvfs->z_fuid_idx, idx);
|
||||
if (zsb->z_fuid_obj || zsb->z_fuid_dirty)
|
||||
domain = zfs_fuid_idx_domain(&zsb->z_fuid_idx, idx);
|
||||
else
|
||||
domain = nulldomain;
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
rw_exit(&zsb->z_fuid_lock);
|
||||
|
||||
ASSERT(domain);
|
||||
return (domain);
|
||||
|
@ -388,12 +387,12 @@ zfs_fuid_find_by_idx(zfsvfs_t *zfsvfs, uint32_t idx)
|
|||
void
|
||||
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);
|
||||
*gidp = zfs_fuid_map_id(zp->z_zfsvfs, zp->z_gid, cr, ZFS_GROUP);
|
||||
*uidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_uid, cr, ZFS_OWNER);
|
||||
*gidp = zfs_fuid_map_id(ZTOZSB(zp), zp->z_gid, cr, ZFS_GROUP);
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
#ifdef HAVE_KSID
|
||||
|
@ -404,7 +403,7 @@ zfs_fuid_map_id(zfsvfs_t *zfsvfs, uint64_t fuid,
|
|||
if (index == 0)
|
||||
return (fuid);
|
||||
|
||||
domain = zfs_fuid_find_by_idx(zfsvfs, index);
|
||||
domain = zfs_fuid_find_by_idx(zsb, index);
|
||||
ASSERT(domain != NULL);
|
||||
|
||||
if (type == ZFS_OWNER || type == ZFS_ACE_USER) {
|
||||
|
@ -499,13 +498,13 @@ zfs_fuid_node_add(zfs_fuid_info_t **fuidpp, const char *domain, uint32_t rid,
|
|||
* be used if it exists.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
uint64_t idx;
|
||||
ksid_t *ksid;
|
||||
uint32_t rid;
|
||||
char *kdomain;
|
||||
char *kdomain;
|
||||
const char *domain;
|
||||
uid_t id;
|
||||
|
||||
|
@ -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);
|
||||
|
||||
if (!zfsvfs->z_use_fuids || (ksid == NULL)) {
|
||||
if (!zsb->z_use_fuids || (ksid == NULL)) {
|
||||
id = (type == ZFS_OWNER) ? crgetuid(cr) : crgetgid(cr);
|
||||
|
||||
if (IS_EPHEMERAL(id))
|
||||
|
@ -536,7 +535,7 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
|
|||
rid = ksid_getrid(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);
|
||||
|
||||
|
@ -554,10 +553,10 @@ zfs_fuid_create_cred(zfsvfs_t *zfsvfs, zfs_fuid_type_t type,
|
|||
*
|
||||
* During replay operations the domain+rid information is
|
||||
* 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
|
||||
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)
|
||||
{
|
||||
#ifdef HAVE_KSID
|
||||
|
@ -578,11 +577,11 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
|
|||
* 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);
|
||||
|
||||
if (zfsvfs->z_replay) {
|
||||
fuidp = zfsvfs->z_fuid_replay;
|
||||
if (zsb->z_replay) {
|
||||
fuidp = zsb->z_fuid_replay;
|
||||
|
||||
/*
|
||||
* 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,
|
||||
rid, idx, id, type);
|
||||
else if (zfuid != NULL) {
|
||||
|
@ -648,15 +647,15 @@ zfs_fuid_create(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr,
|
|||
}
|
||||
|
||||
void
|
||||
zfs_fuid_destroy(zfsvfs_t *zfsvfs)
|
||||
zfs_fuid_destroy(zfs_sb_t *zsb)
|
||||
{
|
||||
rw_enter(&zfsvfs->z_fuid_lock, RW_WRITER);
|
||||
if (!zfsvfs->z_fuid_loaded) {
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
rw_enter(&zsb->z_fuid_lock, RW_WRITER);
|
||||
if (!zsb->z_fuid_loaded) {
|
||||
rw_exit(&zsb->z_fuid_lock);
|
||||
return;
|
||||
}
|
||||
zfs_fuid_table_destroy(&zfsvfs->z_fuid_idx, &zfsvfs->z_fuid_domain);
|
||||
rw_exit(&zfsvfs->z_fuid_lock);
|
||||
zfs_fuid_table_destroy(&zsb->z_fuid_idx, &zsb->z_fuid_domain);
|
||||
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.
|
||||
*/
|
||||
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
|
||||
ksid_t *ksid = crgetsid(cr, KSID_GROUP);
|
||||
|
@ -718,7 +717,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
|
|||
uid_t gid;
|
||||
|
||||
if (ksid && ksidlist) {
|
||||
int i;
|
||||
int i;
|
||||
ksid_t *ksid_groups;
|
||||
uint32_t idx = FUID_INDEX(id);
|
||||
uint32_t rid = FUID_RID(id);
|
||||
|
@ -734,7 +733,7 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
|
|||
} else {
|
||||
const char *domain;
|
||||
|
||||
domain = zfs_fuid_find_by_idx(zfsvfs, idx);
|
||||
domain = zfs_fuid_find_by_idx(zsb, idx);
|
||||
ASSERT(domain != NULL);
|
||||
|
||||
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
|
||||
*/
|
||||
gid = zfs_fuid_map_id(zfsvfs, id, cr, ZFS_GROUP);
|
||||
gid = zfs_fuid_map_id(zsb, id, cr, ZFS_GROUP);
|
||||
return (groupmember(gid, cr));
|
||||
#else
|
||||
return (B_TRUE);
|
||||
|
@ -760,17 +759,17 @@ zfs_groupmember(zfsvfs_t *zfsvfs, uint64_t id, cred_t *cr)
|
|||
}
|
||||
|
||||
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_write(tx, DMU_NEW_OBJECT, 0,
|
||||
FUID_SIZE_ESTIMATE(zfsvfs));
|
||||
FUID_SIZE_ESTIMATE(zsb));
|
||||
dmu_tx_hold_zap(tx, MASTER_NODE_OBJ, FALSE, NULL);
|
||||
} else {
|
||||
dmu_tx_hold_bonus(tx, zfsvfs->z_fuid_obj);
|
||||
dmu_tx_hold_write(tx, zfsvfs->z_fuid_obj, 0,
|
||||
FUID_SIZE_ESTIMATE(zfsvfs));
|
||||
dmu_tx_hold_bonus(tx, zsb->z_fuid_obj);
|
||||
dmu_tx_hold_write(tx, zsb->z_fuid_obj, 0,
|
||||
FUID_SIZE_ESTIMATE(zsb));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -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
|
||||
* 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, ...).
|
||||
*/
|
||||
if (strcasecmp(ds_hexsl, ZFS_MLSLABEL_DEFAULT) != 0) {
|
||||
|
@ -849,20 +849,6 @@ zfs_secpolicy_create(zfs_cmd_t *zc, cred_t *cr)
|
|||
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
|
||||
* 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);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
static int
|
||||
getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
|
||||
get_zfs_sb(const char *dsname, zfs_sb_t **zsbp)
|
||||
{
|
||||
objset_t *os;
|
||||
int error;
|
||||
|
@ -1121,9 +1106,9 @@ getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
|
|||
}
|
||||
|
||||
mutex_enter(&os->os_user_ptr_lock);
|
||||
*zfvp = dmu_objset_get_user(os);
|
||||
if (*zfvp) {
|
||||
VFS_HOLD((*zfvp)->z_vfs);
|
||||
*zsbp = dmu_objset_get_user(os);
|
||||
if (*zsbp) {
|
||||
mntget((*zsbp)->z_vfs);
|
||||
} else {
|
||||
error = ESRCH;
|
||||
}
|
||||
|
@ -1131,52 +1116,45 @@ getzfsvfs(const char *dsname, zfsvfs_t **zfvp)
|
|||
dmu_objset_rele(os, FTAG);
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
|
||||
if (getzfsvfs(name, zfvp) != 0)
|
||||
error = zfsvfs_create(name, zfvp);
|
||||
if (get_zfs_sb(name, zsbp) != 0)
|
||||
error = zfs_sb_create(name, zsbp);
|
||||
if (error == 0) {
|
||||
rrw_enter(&(*zfvp)->z_teardown_lock, (writer) ? RW_WRITER :
|
||||
rrw_enter(&(*zsbp)->z_teardown_lock, (writer) ? RW_WRITER :
|
||||
RW_READER, tag);
|
||||
if ((*zfvp)->z_unmounted) {
|
||||
if ((*zsbp)->z_unmounted) {
|
||||
/*
|
||||
* XXX we could probably try again, since the unmounting
|
||||
* thread should be just about to disassociate the
|
||||
* objset from the zfsvfs.
|
||||
*/
|
||||
rrw_exit(&(*zfvp)->z_teardown_lock, tag);
|
||||
rrw_exit(&(*zsbp)->z_teardown_lock, tag);
|
||||
return (EBUSY);
|
||||
}
|
||||
}
|
||||
return (error);
|
||||
#else
|
||||
return ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
zfsvfs_rele(zfsvfs_t *zfsvfs, void *tag)
|
||||
zfs_sb_rele(zfs_sb_t *zsb, void *tag)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
rrw_exit(&zfsvfs->z_teardown_lock, tag);
|
||||
rrw_exit(&zsb->z_teardown_lock, tag);
|
||||
|
||||
if (zfsvfs->z_vfs) {
|
||||
VFS_RELE(zfsvfs->z_vfs);
|
||||
if (zsb->z_vfs) {
|
||||
mntput(zsb->z_vfs);
|
||||
} else {
|
||||
dmu_objset_disown(zfsvfs->z_os, zfsvfs);
|
||||
zfsvfs_free(zfsvfs);
|
||||
dmu_objset_disown(zsb->z_os, zsb);
|
||||
zfs_sb_free(zsb);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -2086,7 +2064,6 @@ top:
|
|||
static int
|
||||
zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
const char *propname = nvpair_name(pair);
|
||||
uint64_t *valary;
|
||||
unsigned int vallen;
|
||||
|
@ -2095,7 +2072,7 @@ zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
|
|||
zfs_userquota_prop_t type;
|
||||
uint64_t rid;
|
||||
uint64_t quota;
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
int err;
|
||||
|
||||
if (nvpair_type(pair) == DATA_TYPE_NVLIST) {
|
||||
|
@ -2120,16 +2097,13 @@ zfs_prop_set_userquota(const char *dsname, nvpair_t *pair)
|
|||
rid = valary[1];
|
||||
quota = valary[2];
|
||||
|
||||
err = zfsvfs_hold(dsname, FTAG, &zfsvfs, B_FALSE);
|
||||
err = zfs_sb_hold(dsname, FTAG, &zsb, B_FALSE);
|
||||
if (err == 0) {
|
||||
err = zfs_set_userquota(zfsvfs, type, domain, rid, quota);
|
||||
zfsvfs_rele(zfsvfs, FTAG);
|
||||
err = zfs_set_userquota(zsb, type, domain, rid, quota);
|
||||
zfs_sb_rele(zsb, FTAG);
|
||||
}
|
||||
|
||||
return (err);
|
||||
#else
|
||||
return ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -2185,15 +2159,13 @@ zfs_prop_set_special(const char *dsname, zprop_source_t source,
|
|||
break;
|
||||
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;
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
err = zfs_set_version(zfsvfs, intval);
|
||||
#endif
|
||||
zfsvfs_rele(zfsvfs, FTAG);
|
||||
err = zfs_set_version(zsb, intval);
|
||||
zfs_sb_rele(zsb, FTAG);
|
||||
|
||||
if (err == 0 && intval >= ZPL_VERSION_USERSPACE) {
|
||||
zfs_cmd_t *zc;
|
||||
|
@ -2748,7 +2720,7 @@ zfs_ioc_get_fsacl(zfs_cmd_t *zc)
|
|||
return (error);
|
||||
}
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
#ifdef HAVE_SNAPSHOT
|
||||
/*
|
||||
* 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
|
||||
|
@ -2764,7 +2736,7 @@ zfs_get_vfs(const char *resource)
|
|||
vfsp = rootvfs;
|
||||
do {
|
||||
if (strcmp(refstr_value(vfsp->vfs_resource), resource) == 0) {
|
||||
VFS_HOLD(vfsp);
|
||||
mntget(vfsp);
|
||||
vfs_found = vfsp;
|
||||
break;
|
||||
}
|
||||
|
@ -2773,7 +2745,7 @@ zfs_get_vfs(const char *resource)
|
|||
vfs_list_unlock();
|
||||
return (vfs_found);
|
||||
}
|
||||
#endif /* HAVE_ZPL */
|
||||
#endif /* HAVE_SNAPSHOT */
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
|
@ -3128,7 +3100,7 @@ out:
|
|||
int
|
||||
zfs_unmount_snap(const char *name, void *arg)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
#ifdef HAVE_SNAPSHOT
|
||||
vfs_t *vfsp = NULL;
|
||||
|
||||
if (arg) {
|
||||
|
@ -3148,14 +3120,14 @@ zfs_unmount_snap(const char *name, void *arg)
|
|||
int err;
|
||||
|
||||
if ((err = vn_vfswlock(vfsp->vfs_vnodecovered)) != 0) {
|
||||
VFS_RELE(vfsp);
|
||||
mntput(vfsp);
|
||||
return (err);
|
||||
}
|
||||
VFS_RELE(vfsp);
|
||||
mntput(vfsp);
|
||||
if ((err = dounmount(vfsp, flag, kcred)) != 0)
|
||||
return (err);
|
||||
}
|
||||
#endif /* HAVE_ZPL */
|
||||
#endif /* HAVE_SNAPSHOT */
|
||||
return (0);
|
||||
}
|
||||
|
||||
|
@ -3215,10 +3187,9 @@ zfs_ioc_destroy(zfs_cmd_t *zc)
|
|||
static int
|
||||
zfs_ioc_rollback(zfs_cmd_t *zc)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
dsl_dataset_t *ds, *clone;
|
||||
int error;
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
char *clone_name;
|
||||
|
||||
error = dsl_dataset_hold(zc->zc_name, FTAG, &ds);
|
||||
|
@ -3252,8 +3223,8 @@ zfs_ioc_rollback(zfs_cmd_t *zc)
|
|||
/*
|
||||
* Do clone swap.
|
||||
*/
|
||||
if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
|
||||
error = zfs_suspend_fs(zfsvfs);
|
||||
if (get_zfs_sb(zc->zc_name, &zsb) == 0) {
|
||||
error = zfs_suspend_fs(zsb);
|
||||
if (error == 0) {
|
||||
int resume_err;
|
||||
|
||||
|
@ -3265,10 +3236,10 @@ zfs_ioc_rollback(zfs_cmd_t *zc)
|
|||
} else {
|
||||
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;
|
||||
}
|
||||
VFS_RELE(zfsvfs->z_vfs);
|
||||
mntput(zsb->z_vfs);
|
||||
} else {
|
||||
if (dsl_dataset_tryown(ds, B_FALSE, FTAG)) {
|
||||
error = dsl_dataset_clone_swap(clone, ds, B_TRUE);
|
||||
|
@ -3289,9 +3260,6 @@ out:
|
|||
if (ds)
|
||||
dsl_dataset_rele(ds, FTAG);
|
||||
return (error);
|
||||
#else
|
||||
return (ENOTSUP);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -3741,29 +3709,25 @@ zfs_ioc_recv(zfs_cmd_t *zc)
|
|||
&zc->zc_action_handle);
|
||||
|
||||
if (error == 0) {
|
||||
#ifdef HAVE_ZPL
|
||||
zfsvfs_t *zfsvfs = NULL;
|
||||
zfs_sb_t *zsb = NULL;
|
||||
|
||||
if (getzfsvfs(tofs, &zfsvfs) == 0) {
|
||||
if (get_zfs_sb(tofs, &zsb) == 0) {
|
||||
/* online recv */
|
||||
int end_err;
|
||||
|
||||
error = zfs_suspend_fs(zfsvfs);
|
||||
error = zfs_suspend_fs(zsb);
|
||||
/*
|
||||
* If the suspend fails, then the recv_end will
|
||||
* likely also fail, and clean up after itself.
|
||||
*/
|
||||
end_err = dmu_recv_end(&drc);
|
||||
if (error == 0)
|
||||
error = zfs_resume_fs(zfsvfs, tofs);
|
||||
error = zfs_resume_fs(zsb, tofs);
|
||||
error = error ? error : end_err;
|
||||
VFS_RELE(zfsvfs->z_vfs);
|
||||
mntput(zsb->z_vfs);
|
||||
} else {
|
||||
error = dmu_recv_end(&drc);
|
||||
}
|
||||
#else
|
||||
error = dmu_recv_end(&drc);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
zc->zc_cookie = off - fp->f_offset;
|
||||
|
@ -4087,25 +4051,21 @@ zfs_ioc_promote(zfs_cmd_t *zc)
|
|||
static int
|
||||
zfs_ioc_userspace_one(zfs_cmd_t *zc)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
int error;
|
||||
|
||||
if (zc->zc_objset_type >= ZFS_NUM_USERQUOTA_PROPS)
|
||||
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)
|
||||
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);
|
||||
zfsvfs_rele(zfsvfs, FTAG);
|
||||
zfs_sb_rele(zsb, FTAG);
|
||||
|
||||
return (error);
|
||||
#else
|
||||
return (ENOTSUP);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4122,20 +4082,21 @@ zfs_ioc_userspace_one(zfs_cmd_t *zc)
|
|||
static int
|
||||
zfs_ioc_userspace_many(zfs_cmd_t *zc)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
int bufsize = zc->zc_nvlist_dst_size;
|
||||
int error;
|
||||
void *buf;
|
||||
|
||||
if (bufsize <= 0)
|
||||
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)
|
||||
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);
|
||||
|
||||
if (error == 0) {
|
||||
|
@ -4144,12 +4105,9 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
|
|||
zc->zc_nvlist_dst_size);
|
||||
}
|
||||
kmem_free(buf, bufsize);
|
||||
zfsvfs_rele(zfsvfs, FTAG);
|
||||
zfs_sb_rele(zsb, FTAG);
|
||||
|
||||
return (error);
|
||||
#else
|
||||
return (ENOTSUP);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4162,25 +4120,24 @@ zfs_ioc_userspace_many(zfs_cmd_t *zc)
|
|||
static int
|
||||
zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
|
||||
{
|
||||
#ifdef HAVE_ZPL
|
||||
objset_t *os;
|
||||
int error = 0;
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
|
||||
if (getzfsvfs(zc->zc_name, &zfsvfs) == 0) {
|
||||
if (!dmu_objset_userused_enabled(zfsvfs->z_os)) {
|
||||
if (get_zfs_sb(zc->zc_name, &zsb) == 0) {
|
||||
if (!dmu_objset_userused_enabled(zsb->z_os)) {
|
||||
/*
|
||||
* If userused is not enabled, it may be because the
|
||||
* objset needs to be closed & reopened (to grow the
|
||||
* objset_phys_t). Suspend/resume the fs will do that.
|
||||
*/
|
||||
error = zfs_suspend_fs(zfsvfs);
|
||||
error = zfs_suspend_fs(zsb);
|
||||
if (error == 0)
|
||||
error = zfs_resume_fs(zfsvfs, zc->zc_name);
|
||||
error = zfs_resume_fs(zsb, zc->zc_name);
|
||||
}
|
||||
if (error == 0)
|
||||
error = dmu_objset_userspace_upgrade(zfsvfs->z_os);
|
||||
VFS_RELE(zfsvfs->z_vfs);
|
||||
error = dmu_objset_userspace_upgrade(zsb->z_os);
|
||||
mntput(zsb->z_vfs);
|
||||
} else {
|
||||
/* XXX kind of reading contents without owning */
|
||||
error = dmu_objset_hold(zc->zc_name, FTAG, &os);
|
||||
|
@ -4192,9 +4149,6 @@ zfs_ioc_userspace_upgrade(zfs_cmd_t *zc)
|
|||
}
|
||||
|
||||
return (error);
|
||||
#else
|
||||
return (ENOTSUP);
|
||||
#endif /* HAVE_ZPL */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -4456,10 +4410,10 @@ zfs_smb_acl_purge(znode_t *dzp)
|
|||
{
|
||||
zap_cursor_t zc;
|
||||
zap_attribute_t zap;
|
||||
zfsvfs_t *zfsvfs = dzp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(dzp);
|
||||
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;
|
||||
zap_cursor_advance(&zc)) {
|
||||
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;
|
||||
vnode_t *resourcevp = NULL;
|
||||
znode_t *sharedir;
|
||||
zfsvfs_t *zfsvfs;
|
||||
zfs_sb_t *zsb;
|
||||
nvlist_t *nvlist;
|
||||
char *src, *target;
|
||||
vattr_t vattr;
|
||||
|
@ -4500,17 +4454,17 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
|||
}
|
||||
|
||||
dzp = VTOZ(vp);
|
||||
zfsvfs = dzp->z_zfsvfs;
|
||||
ZFS_ENTER(zfsvfs);
|
||||
zsb = ZTOZSB(dzp);
|
||||
ZFS_ENTER(zsb);
|
||||
|
||||
/*
|
||||
* Create share dir if its missing.
|
||||
*/
|
||||
mutex_enter(&zfsvfs->z_lock);
|
||||
if (zfsvfs->z_shares_dir == 0) {
|
||||
mutex_enter(&zsb->z_lock);
|
||||
if (zsb->z_shares_dir == 0) {
|
||||
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,
|
||||
ZFS_SHARES_DIR);
|
||||
dmu_tx_hold_zap(tx, DMU_NEW_OBJECT, FALSE, NULL);
|
||||
|
@ -4518,29 +4472,28 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
|||
if (error) {
|
||||
dmu_tx_abort(tx);
|
||||
} else {
|
||||
error = zfs_create_share_dir(zfsvfs, tx);
|
||||
error = zfs_create_share_dir(zsb, tx);
|
||||
dmu_tx_commit(tx);
|
||||
}
|
||||
if (error) {
|
||||
mutex_exit(&zfsvfs->z_lock);
|
||||
mutex_exit(&zsb->z_lock);
|
||||
VN_RELE(vp);
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
return (error);
|
||||
}
|
||||
}
|
||||
mutex_exit(&zfsvfs->z_lock);
|
||||
mutex_exit(&zsb->z_lock);
|
||||
|
||||
ASSERT(zfsvfs->z_shares_dir);
|
||||
if ((error = zfs_zget(zfsvfs, zfsvfs->z_shares_dir, &sharedir)) != 0) {
|
||||
ASSERT(zsb->z_shares_dir);
|
||||
if ((error = zfs_zget(zsb, zsb->z_shares_dir, &sharedir)) != 0) {
|
||||
VN_RELE(vp);
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
return (error);
|
||||
}
|
||||
|
||||
switch (zc->zc_cookie) {
|
||||
case ZFS_SMB_ACL_ADD:
|
||||
vattr.va_mask = AT_MODE|AT_UID|AT_GID|AT_TYPE;
|
||||
vattr.va_type = VREG;
|
||||
vattr.va_mode = S_IFREG|0777;
|
||||
vattr.va_uid = 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,
|
||||
zc->zc_nvlist_src_size, zc->zc_iflags, &nvlist)) != 0) {
|
||||
VN_RELE(vp);
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
return (error);
|
||||
}
|
||||
if (nvlist_lookup_string(nvlist, ZFS_SMB_ACL_SRC, &src) ||
|
||||
|
@ -4573,7 +4526,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
|||
&target)) {
|
||||
VN_RELE(vp);
|
||||
VN_RELE(ZTOV(sharedir));
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
nvlist_free(nvlist);
|
||||
return (error);
|
||||
}
|
||||
|
@ -4594,7 +4547,7 @@ zfs_ioc_smb_acl(zfs_cmd_t *zc)
|
|||
VN_RELE(vp);
|
||||
VN_RELE(ZTOV(sharedir));
|
||||
|
||||
ZFS_EXIT(zfsvfs);
|
||||
ZFS_EXIT(zsb);
|
||||
|
||||
return (error);
|
||||
#else
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_ZPL
|
||||
|
||||
#include <sys/types.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_gid = zp->z_gid;
|
||||
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));
|
||||
(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);
|
||||
bcopy(name, (char *)(lr + 1), namesize);
|
||||
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) +
|
||||
(write_state == WR_COPIED ? len : 0));
|
||||
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) {
|
||||
zil_itx_destroy(itx);
|
||||
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;
|
||||
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) &&
|
||||
(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)
|
||||
return;
|
||||
|
||||
txtype = (zp->z_zfsvfs->z_version < ZPL_VERSION_FUID) ?
|
||||
txtype = (ZTOZSB(zp)->z_version < ZPL_VERSION_FUID) ?
|
||||
TX_ACL_V0 : 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);
|
||||
|
||||
#ifdef HAVE_XVATTR
|
||||
if (fuidp) {
|
||||
start = zfs_log_fuid_ids(fuidp, start);
|
||||
(void) zfs_log_fuid_domains(fuidp, start);
|
||||
}
|
||||
#endif /* HAVE_XVATTR */
|
||||
}
|
||||
|
||||
itx->itx_sync = (zp->z_sync_cnt != 0);
|
||||
zil_itx_assign(zilog, itx, tx);
|
||||
}
|
||||
|
||||
#endif /* HAVE_ZPL */
|
||||
|
|
|
@ -134,7 +134,7 @@ zfs_range_lock_writer(znode_t *zp, rl_t *new)
|
|||
*/
|
||||
end_size = MAX(zp->z_size, new->r_off + len);
|
||||
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_len = UINT64_MAX;
|
||||
}
|
||||
|
|
|
@ -81,7 +81,7 @@ zfs_sa_readlink(znode_t *zp, uio_t *uio)
|
|||
MIN((size_t)bufsz, uio->uio_resid), UIO_READ, uio);
|
||||
} else {
|
||||
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) {
|
||||
error = uiomove(dbp->db_data,
|
||||
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;
|
||||
|
||||
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));
|
||||
|
||||
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
|
||||
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;
|
||||
|
||||
ASSERT(MUTEX_HELD(&zp->z_lock));
|
||||
VERIFY((xoap = xva_getxoptattr(xvap)) != NULL);
|
||||
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,
|
||||
sizeof (xoap->xoa_av_scanstamp)) != 0)
|
||||
return;
|
||||
|
@ -156,13 +156,13 @@ zfs_sa_get_scanstamp(znode_t *zp, xvattr_t *xvap)
|
|||
void
|
||||
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;
|
||||
|
||||
ASSERT(MUTEX_HELD(&zp->z_lock));
|
||||
VERIFY((xoap = xva_getxoptattr(xvap)) != NULL);
|
||||
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,
|
||||
sizeof (xoap->xoa_av_scanstamp), tx));
|
||||
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));
|
||||
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -198,7 +198,7 @@ zfs_sa_upgrade(sa_handle_t *hdl, dmu_tx_t *tx)
|
|||
{
|
||||
dmu_buf_t *db = sa_get_db(hdl);
|
||||
znode_t *zp = sa_get_userdata(hdl);
|
||||
zfsvfs_t *zfsvfs = zp->z_zfsvfs;
|
||||
zfs_sb_t *zsb = ZTOZSB(zp);
|
||||
int count = 0;
|
||||
sa_bulk_attr_t *bulk, *sa_attrs;
|
||||
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"
|
||||
* 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;
|
||||
|
||||
/*
|
||||
|
@ -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 */
|
||||
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_CTIME(zfsvfs), NULL, &ctime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zfsvfs), NULL, &crtime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zfsvfs), NULL, &mode, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zfsvfs), NULL, &parent, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zfsvfs), NULL, &xattr, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zfsvfs), NULL, &rdev, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zfsvfs), NULL, &uid, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zfsvfs), NULL, &gid, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MTIME(zsb), NULL, &mtime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CTIME(zsb), NULL, &ctime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_CRTIME(zsb), NULL, &crtime, 16);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_PARENT(zsb), NULL, &parent, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_XATTR(zsb), NULL, &xattr, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_RDEV(zsb), NULL, &rdev, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_UID(zsb), NULL, &uid, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_GID(zsb), NULL, &gid, 8);
|
||||
SA_ADD_BULK_ATTR(bulk, count, SA_ZPL_ZNODE_ACL(zsb), NULL,
|
||||
&znode_acl, 88);
|
||||
|
||||
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;
|
||||
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_SIZE(zfsvfs), NULL,
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_MODE(zsb), NULL, &mode, 8);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_SIZE(zsb), NULL,
|
||||
&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);
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zfsvfs), 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_PARENT(zfsvfs),
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_UID(zsb), NULL, &uid, 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(zsb),
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
if (zp->z_vnode->v_type == VBLK || zp->z_vnode->v_type == VCHR)
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zfsvfs), NULL,
|
||||
if (S_ISBLK(ZTOI(zp)->i_mode) || S_ISCHR(ZTOI(zp)->i_mode))
|
||||
SA_ADD_BULK_ATTR(sa_attrs, count, SA_ZPL_RDEV(zsb), NULL,
|
||||
&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);
|
||||
|
||||
if (zp->z_acl_cached->z_version < ZFS_ACL_VERSION_FUID)
|
||||
zfs_acl_xform(zp, zp->z_acl_cached, CRED());
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
#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) {
|
||||
bcopy((caddr_t)db->db_data + ZFS_OLD_ZNODE_PHYS_SIZE,
|
||||
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);
|
||||
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,
|
||||
count, tx) == 0);
|
||||
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));
|
||||
|
||||
zp->z_is_sa = B_TRUE;
|
||||
|
@ -328,7 +328,7 @@ done:
|
|||
void
|
||||
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;
|
||||
|
||||
|
||||
|
|
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
Loading…
Reference in New Issue