diff options
Diffstat (limited to 'include/sys')
-rw-r--r-- | include/sys/Makefile.am | 1 | ||||
-rw-r--r-- | include/sys/dmu.h | 5 | ||||
-rw-r--r-- | include/sys/dmu_objset.h | 28 | ||||
-rw-r--r-- | include/sys/dnode.h | 6 | ||||
-rw-r--r-- | include/sys/dsl_deleg.h | 4 | ||||
-rw-r--r-- | include/sys/fs/zfs.h | 4 | ||||
-rw-r--r-- | include/sys/sa.h | 1 | ||||
-rw-r--r-- | include/sys/xvattr.h | 9 | ||||
-rw-r--r-- | include/sys/zfs_acl.h | 3 | ||||
-rw-r--r-- | include/sys/zfs_project.h | 83 | ||||
-rw-r--r-- | include/sys/zfs_sa.h | 3 | ||||
-rw-r--r-- | include/sys/zfs_vfsops.h | 14 | ||||
-rw-r--r-- | include/sys/zfs_znode.h | 24 |
13 files changed, 163 insertions, 22 deletions
diff --git a/include/sys/Makefile.am b/include/sys/Makefile.am index 348e6584f..8e18a8790 100644 --- a/include/sys/Makefile.am +++ b/include/sys/Makefile.am @@ -105,6 +105,7 @@ COMMON_H = \ $(top_srcdir)/include/sys/zfs_delay.h \ $(top_srcdir)/include/sys/zfs_dir.h \ $(top_srcdir)/include/sys/zfs_fuid.h \ + $(top_srcdir)/include/sys/zfs_project.h \ $(top_srcdir)/include/sys/zfs_ratelimit.h \ $(top_srcdir)/include/sys/zfs_rlock.h \ $(top_srcdir)/include/sys/zfs_sa.h \ diff --git a/include/sys/dmu.h b/include/sys/dmu.h index 5553667c3..cf9cbaa64 100644 --- a/include/sys/dmu.h +++ b/include/sys/dmu.h @@ -276,9 +276,10 @@ void zfs_znode_byteswap(void *buf, size_t size); #define DMU_USERUSED_OBJECT (-1ULL) #define DMU_GROUPUSED_OBJECT (-2ULL) +#define DMU_PROJECTUSED_OBJECT (-3ULL) /* - * Zap prefix for object accounting in DMU_{USER,GROUP}USED_OBJECT. + * Zap prefix for object accounting in DMU_{USER,GROUP,PROJECT}USED_OBJECT. */ #define DMU_OBJACCT_PREFIX "obj-" #define DMU_OBJACCT_PREFIX_LEN 4 @@ -971,7 +972,7 @@ extern int dmu_dir_list_next(objset_t *os, int namelen, char *name, uint64_t *idp, uint64_t *offp); typedef int objset_used_cb_t(dmu_object_type_t bonustype, - void *bonus, uint64_t *userp, uint64_t *groupp); + void *bonus, uint64_t *userp, uint64_t *groupp, uint64_t *projectp); extern void dmu_objset_register_type(dmu_objset_type_t ost, objset_used_cb_t *cb); extern void dmu_objset_set_user(objset_t *os, void *user_ptr); diff --git a/include/sys/dmu_objset.h b/include/sys/dmu_objset.h index 7ee992f31..df9b1a73a 100644 --- a/include/sys/dmu_objset.h +++ b/include/sys/dmu_objset.h @@ -49,14 +49,18 @@ struct dsl_pool; struct dsl_dataset; struct dmu_tx; -#define OBJSET_PHYS_SIZE 2048 -#define OBJSET_OLD_PHYS_SIZE 1024 +#define OBJSET_PHYS_SIZE_V1 1024 +#define OBJSET_PHYS_SIZE_V2 2048 +#define OBJSET_PHYS_SIZE_V3 4096 #define OBJSET_BUF_HAS_USERUSED(buf) \ - (arc_buf_size(buf) > OBJSET_OLD_PHYS_SIZE) + (arc_buf_size(buf) >= OBJSET_PHYS_SIZE_V2) +#define OBJSET_BUF_HAS_PROJECTUSED(buf) \ + (arc_buf_size(buf) >= OBJSET_PHYS_SIZE_V3) -#define OBJSET_FLAG_USERACCOUNTING_COMPLETE (1ULL<<0) -#define OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE (1ULL<<1) +#define OBJSET_FLAG_USERACCOUNTING_COMPLETE (1ULL << 0) +#define OBJSET_FLAG_USEROBJACCOUNTING_COMPLETE (1ULL << 1) +#define OBJSET_FLAG_PROJECTQUOTA_COMPLETE (1ULL << 2) /* all flags are currently non-portable */ #define OBJSET_CRYPT_PORTABLE_FLAGS_MASK (0) @@ -68,11 +72,14 @@ typedef struct objset_phys { uint64_t os_flags; uint8_t os_portable_mac[ZIO_OBJSET_MAC_LEN]; uint8_t os_local_mac[ZIO_OBJSET_MAC_LEN]; - char os_pad[OBJSET_PHYS_SIZE - sizeof (dnode_phys_t)*3 - + char os_pad0[OBJSET_PHYS_SIZE_V2 - sizeof (dnode_phys_t)*3 - sizeof (zil_header_t) - sizeof (uint64_t)*2 - 2*ZIO_OBJSET_MAC_LEN]; dnode_phys_t os_userused_dnode; dnode_phys_t os_groupused_dnode; + dnode_phys_t os_projectused_dnode; + char os_pad1[OBJSET_PHYS_SIZE_V3 - OBJSET_PHYS_SIZE_V2 - + sizeof (dnode_phys_t)]; } objset_phys_t; typedef int (*dmu_objset_upgrade_cb_t)(objset_t *); @@ -94,6 +101,7 @@ struct objset { dnode_handle_t os_meta_dnode; dnode_handle_t os_userused_dnode; dnode_handle_t os_groupused_dnode; + dnode_handle_t os_projectused_dnode; zilog_t *os_zil; list_node_t os_evicting_node; @@ -143,7 +151,7 @@ struct objset { list_t os_dnodes; list_t os_downgraded_dbufs; - /* Protects changes to DMU_{USER,GROUP}USED_OBJECT */ + /* Protects changes to DMU_{USER,GROUP,PROJECT}USED_OBJECT */ kmutex_t os_userused_lock; /* stuff we store for the user */ @@ -165,6 +173,7 @@ struct objset { #define DMU_META_DNODE(os) ((os)->os_meta_dnode.dnh_dnode) #define DMU_USERUSED_DNODE(os) ((os)->os_userused_dnode.dnh_dnode) #define DMU_GROUPUSED_DNODE(os) ((os)->os_groupused_dnode.dnh_dnode) +#define DMU_PROJECTUSED_DNODE(os) ((os)->os_projectused_dnode.dnh_dnode) #define DMU_OS_IS_L2CACHEABLE(os) \ ((os)->os_secondary_cache == ZFS_CACHE_ALL || \ @@ -215,9 +224,12 @@ int dmu_objset_userspace_upgrade(objset_t *os); boolean_t dmu_objset_userspace_present(objset_t *os); boolean_t dmu_objset_userobjused_enabled(objset_t *os); boolean_t dmu_objset_userobjspace_upgradable(objset_t *os); -void dmu_objset_userobjspace_upgrade(objset_t *os); boolean_t dmu_objset_userobjspace_present(objset_t *os); boolean_t dmu_objset_incompatible_encryption_version(objset_t *os); +boolean_t dmu_objset_projectquota_enabled(objset_t *os); +boolean_t dmu_objset_projectquota_present(objset_t *os); +boolean_t dmu_objset_projectquota_upgradable(objset_t *os); +void dmu_objset_id_quota_upgrade(objset_t *os); int dmu_fsname(const char *snapname, char *buf); diff --git a/include/sys/dnode.h b/include/sys/dnode.h index 691fd443a..9c44a2232 100644 --- a/include/sys/dnode.h +++ b/include/sys/dnode.h @@ -147,7 +147,7 @@ enum dnode_dirtycontext { /* Does dnode have a SA spill blkptr in bonus? */ #define DNODE_FLAG_SPILL_BLKPTR (1 << 2) -/* User/Group dnode accounting */ +/* User/Group/Project dnode accounting */ #define DNODE_FLAG_USEROBJUSED_ACCOUNTED (1 << 3) #define DNODE_CRYPT_PORTABLE_FLAGS_MASK (DNODE_FLAG_SPILL_BLKPTR) @@ -356,8 +356,8 @@ struct dnode { /* used in syncing context */ uint64_t dn_oldused; /* old phys used bytes */ uint64_t dn_oldflags; /* old phys dn_flags */ - uint64_t dn_olduid, dn_oldgid; - uint64_t dn_newuid, dn_newgid; + uint64_t dn_olduid, dn_oldgid, dn_oldprojid; + uint64_t dn_newuid, dn_newgid, dn_newprojid; int dn_id_flags; /* holds prefetch structure */ diff --git a/include/sys/dsl_deleg.h b/include/sys/dsl_deleg.h index 153c08f93..eb95c68e8 100644 --- a/include/sys/dsl_deleg.h +++ b/include/sys/dsl_deleg.h @@ -63,6 +63,10 @@ extern "C" { #define ZFS_DELEG_PERM_BOOKMARK "bookmark" #define ZFS_DELEG_PERM_LOAD_KEY "load-key" #define ZFS_DELEG_PERM_CHANGE_KEY "change-key" +#define ZFS_DELEG_PERM_PROJECTUSED "projectused" +#define ZFS_DELEG_PERM_PROJECTQUOTA "projectquota" +#define ZFS_DELEG_PERM_PROJECTOBJUSED "projectobjused" +#define ZFS_DELEG_PERM_PROJECTOBJQUOTA "projectobjquota" /* * Note: the names of properties that are marked delegatable are also diff --git a/include/sys/fs/zfs.h b/include/sys/fs/zfs.h index 7b86f6631..88f590276 100644 --- a/include/sys/fs/zfs.h +++ b/include/sys/fs/zfs.h @@ -192,6 +192,10 @@ typedef enum { ZFS_PROP_USEROBJQUOTA, ZFS_PROP_GROUPOBJUSED, ZFS_PROP_GROUPOBJQUOTA, + ZFS_PROP_PROJECTUSED, + ZFS_PROP_PROJECTQUOTA, + ZFS_PROP_PROJECTOBJUSED, + ZFS_PROP_PROJECTOBJQUOTA, ZFS_NUM_USERQUOTA_PROPS } zfs_userquota_prop_t; diff --git a/include/sys/sa.h b/include/sys/sa.h index b7ed9fe38..50b906221 100644 --- a/include/sys/sa.h +++ b/include/sys/sa.h @@ -159,6 +159,7 @@ void sa_handle_unlock(sa_handle_t *); #ifdef _KERNEL int sa_lookup_uio(sa_handle_t *, sa_attr_type_t, uio_t *); +int sa_add_projid(sa_handle_t *, dmu_tx_t *, uint64_t); #endif #ifdef __cplusplus diff --git a/include/sys/xvattr.h b/include/sys/xvattr.h index 4779b6321..1c919454d 100644 --- a/include/sys/xvattr.h +++ b/include/sys/xvattr.h @@ -64,6 +64,8 @@ typedef struct xoptattr { uint64_t xoa_generation; uint8_t xoa_offline; uint8_t xoa_sparse; + uint8_t xoa_projinherit; + uint64_t xoa_projid; } xoptattr_t; /* @@ -169,11 +171,14 @@ typedef struct xvattr { #define XAT0_GEN 0x00004000 /* object generation number */ #define XAT0_OFFLINE 0x00008000 /* offline */ #define XAT0_SPARSE 0x00010000 /* sparse */ +#define XAT0_PROJINHERIT 0x00020000 /* Create with parent projid */ +#define XAT0_PROJID 0x00040000 /* Project ID */ #define XAT0_ALL_ATTRS (XAT0_CREATETIME|XAT0_ARCHIVE|XAT0_SYSTEM| \ XAT0_READONLY|XAT0_HIDDEN|XAT0_NOUNLINK|XAT0_IMMUTABLE|XAT0_APPENDONLY| \ XAT0_NODUMP|XAT0_OPAQUE|XAT0_AV_QUARANTINED| XAT0_AV_MODIFIED| \ - XAT0_AV_SCANSTAMP|XAT0_REPARSE|XATO_GEN|XAT0_OFFLINE|XAT0_SPARSE) + XAT0_AV_SCANSTAMP|XAT0_REPARSE|XATO_GEN|XAT0_OFFLINE|XAT0_SPARSE| \ + XAT0_PROJINHERIT | XAT0_PROJID) /* Support for XAT_* optional attributes */ #define XVA_MASK 0xffffffff /* Used to mask off 32 bits */ @@ -210,6 +215,8 @@ typedef struct xvattr { #define XAT_GEN ((XAT0_INDEX << XVA_SHFT) | XAT0_GEN) #define XAT_OFFLINE ((XAT0_INDEX << XVA_SHFT) | XAT0_OFFLINE) #define XAT_SPARSE ((XAT0_INDEX << XVA_SHFT) | XAT0_SPARSE) +#define XAT_PROJINHERIT ((XAT0_INDEX << XVA_SHFT) | XAT0_PROJINHERIT) +#define XAT_PROJID ((XAT0_INDEX << XVA_SHFT) | XAT0_PROJID) /* * The returned attribute map array (xva_rtnattrmap[]) is located past the diff --git a/include/sys/zfs_acl.h b/include/sys/zfs_acl.h index 2572fee86..6d3db5041 100644 --- a/include/sys/zfs_acl.h +++ b/include/sys/zfs_acl.h @@ -208,7 +208,7 @@ struct zfsvfs; 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 zfsvfs *, zfs_acl_ids_t *, uint64_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 *); @@ -237,6 +237,7 @@ void zfs_acl_xform(struct znode *, zfs_acl_t *, cred_t *); void zfs_acl_data_locator(void **, uint32_t *, uint32_t, boolean_t, void *); uint64_t zfs_mode_compute(uint64_t, zfs_acl_t *, uint64_t *, uint64_t, uint64_t); +int zfs_acl_node_read(struct znode *, boolean_t, zfs_acl_t **, boolean_t); int zfs_acl_chown_setattr(struct znode *); #endif diff --git a/include/sys/zfs_project.h b/include/sys/zfs_project.h new file mode 100644 index 000000000..52d5204a6 --- /dev/null +++ b/include/sys/zfs_project.h @@ -0,0 +1,83 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright (c) 2017, Intel Corporation. All rights reserved. + */ + +#ifndef _SYS_ZFS_PROJECT_H +#define _SYS_ZFS_PROJECT_H + +#ifndef _KERNEL +#ifndef _SYS_MOUNT_H +/* XXX: some hack to avoid include sys/mount.h */ +#define _SYS_MOUNT_H +#endif +#endif + +#include <linux/fs.h> + +#ifdef FS_PROJINHERIT_FL +#define ZFS_PROJINHERIT_FL FS_PROJINHERIT_FL +#else +#define ZFS_PROJINHERIT_FL 0x20000000 +#endif + +#ifdef FS_IOC_FSGETXATTR +typedef struct fsxattr zfsxattr_t; + +#define ZFS_IOC_FSGETXATTR FS_IOC_FSGETXATTR +#define ZFS_IOC_FSSETXATTR FS_IOC_FSSETXATTR +#else +struct zfsxattr { + uint32_t fsx_xflags; /* xflags field value (get/set) */ + uint32_t fsx_extsize; /* extsize field value (get/set) */ + uint32_t fsx_nextents; /* nextents field value (get) */ + uint32_t fsx_projid; /* project identifier (get/set) */ + uint32_t fsx_cowextsize; + unsigned char fsx_pad[8]; +}; +typedef struct zfsxattr zfsxattr_t; + +#define ZFS_IOC_FSGETXATTR _IOR('X', 31, zfsxattr_t) +#define ZFS_IOC_FSSETXATTR _IOW('X', 32, zfsxattr_t) +#endif + +#define ZFS_DEFAULT_PROJID (0ULL) +/* + * It is NOT ondisk project ID value. Just means either the object has + * no project ID or the operation does not touch project ID attribute. + */ +#define ZFS_INVALID_PROJID (-1ULL) + +static inline boolean_t +zpl_is_valid_projid(uint32_t projid) +{ + /* + * zfsxattr::fsx_projid is 32-bits, when convert to uint64_t, + * the higher 32-bits will be set as zero, so cannot directly + * compare with ZFS_INVALID_PROJID (-1ULL) + */ + if ((uint32_t)ZFS_INVALID_PROJID == projid) + return (B_FALSE); + return (B_TRUE); +} + +#endif /* _SYS_ZFS_PROJECT_H */ diff --git a/include/sys/zfs_sa.h b/include/sys/zfs_sa.h index 06c4d589a..4e6d28638 100644 --- a/include/sys/zfs_sa.h +++ b/include/sys/zfs_sa.h @@ -74,6 +74,7 @@ typedef enum zpl_attr { ZPL_SCANSTAMP, ZPL_DACL_ACES, ZPL_DXATTR, + ZPL_PROJID, ZPL_END } zpl_attr_t; @@ -87,6 +88,8 @@ typedef enum zpl_attr { #define SA_UID_OFFSET 24 #define SA_GID_OFFSET 32 #define SA_PARENT_OFFSET 40 +#define SA_FLAGS_OFFSET 48 +#define SA_PROJID_OFFSET 128 extern sa_attr_reg_t zfs_attr_table[ZPL_END + 1]; extern sa_attr_reg_t zfs_legacy_attr_table[ZPL_END + 1]; diff --git a/include/sys/zfs_vfsops.h b/include/sys/zfs_vfsops.h index 7dbdfd718..70f0cd50d 100644 --- a/include/sys/zfs_vfsops.h +++ b/include/sys/zfs_vfsops.h @@ -121,6 +121,8 @@ struct zfsvfs { uint64_t z_groupquota_obj; uint64_t z_userobjquota_obj; uint64_t z_groupobjquota_obj; + uint64_t z_projectquota_obj; + uint64_t z_projectobjquota_obj; uint64_t z_replay_eof; /* New end of file - replay only */ sa_attr_type_t *z_attr_table; /* SA attr mapping->id */ uint64_t z_hold_size; /* znode hold array size */ @@ -195,12 +197,12 @@ extern int zfs_userspace_many(zfsvfs_t *zfsvfs, 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, const char *domain, uint64_t rid, uint64_t quota); -extern boolean_t zfs_owner_overquota(zfsvfs_t *zfsvfs, struct znode *, - boolean_t isgroup); -extern boolean_t zfs_fuid_overquota(zfsvfs_t *zfsvfs, boolean_t isgroup, - uint64_t fuid); -extern boolean_t zfs_fuid_overobjquota(zfsvfs_t *zfsvfs, boolean_t isgroup, - uint64_t fuid); +extern boolean_t zfs_id_overblockquota(zfsvfs_t *zfsvfs, uint64_t usedobj, + uint64_t id); +extern boolean_t zfs_id_overobjquota(zfsvfs_t *zfsvfs, uint64_t usedobj, + uint64_t id); +extern boolean_t zfs_id_overquota(zfsvfs_t *zfsvfs, uint64_t usedobj, + uint64_t id); extern int zfs_set_version(zfsvfs_t *zfsvfs, uint64_t newvers); extern int zfsvfs_create(const char *name, zfsvfs_t **zfvp); extern int zfsvfs_create_impl(zfsvfs_t **zfvp, zfsvfs_t *zfsvfs, objset_t *os); diff --git a/include/sys/zfs_znode.h b/include/sys/zfs_znode.h index 6a3a3b233..311babe59 100644 --- a/include/sys/zfs_znode.h +++ b/include/sys/zfs_znode.h @@ -42,6 +42,7 @@ #endif #include <sys/zfs_acl.h> #include <sys/zil.h> +#include <sys/zfs_project.h> #ifdef __cplusplus extern "C" { @@ -66,6 +67,18 @@ extern "C" { #define ZFS_OFFLINE 0x0000100000000000ull #define ZFS_SPARSE 0x0000200000000000ull +/* + * PROJINHERIT attribute is used to indicate that the child object under the + * directory which has the PROJINHERIT attribute needs to inherit its parent + * project ID that is used by project quota. + */ +#define ZFS_PROJINHERIT 0x0000400000000000ull + +/* + * PROJID attr is used internally to indicate that the object has project ID. + */ +#define ZFS_PROJID 0x0000800000000000ull + #define ZFS_ATTR_SET(zp, attr, value, pflags, tx) \ { \ if (value) \ @@ -110,6 +123,7 @@ extern "C" { #define SA_ZPL_ZNODE_ACL(z) z->z_attr_table[ZPL_ZNODE_ACL] #define SA_ZPL_DXATTR(z) z->z_attr_table[ZPL_DXATTR] #define SA_ZPL_PAD(z) z->z_attr_table[ZPL_PAD] +#define SA_ZPL_PROJID(z) z->z_attr_table[ZPL_PROJID] /* * Is ID ephemeral? @@ -128,7 +142,7 @@ extern "C" { /* * Special attributes for master node. - * "userquota@" and "groupquota@" are also valid (from + * "userquota@", "groupquota@" and "projectquota@" are also valid (from * zfs_userquota_prop_prefixes[]). */ #define ZFS_FSID "FSID" @@ -196,6 +210,7 @@ typedef struct znode { krwlock_t z_xattr_lock; /* xattr data lock */ nvlist_t *z_xattr_cached; /* cached xattrs */ uint64_t z_xattr_parent; /* parent obj for this xattr */ + uint64_t z_projid; /* project ID */ list_node_t z_link_node; /* all znodes in fs link */ sa_handle_t *z_sa_hdl; /* handle to sa data */ boolean_t z_is_sa; /* are we native sa? */ @@ -212,6 +227,13 @@ typedef struct znode_hold { refcount_t zh_refcount; /* active consumer reference count */ } znode_hold_t; +static inline uint64_t +zfs_inherit_projid(znode_t *dzp) +{ + return ((dzp->z_pflags & ZFS_PROJINHERIT) ? dzp->z_projid : + ZFS_DEFAULT_PROJID); +} + /* * Range locking rules * -------------------- |