diff options
author | Nasf-Fan <[email protected]> | 2018-03-06 04:56:27 +0800 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2018-03-05 12:56:27 -0800 |
commit | 2705ebf0a74f15bb246fb899f19b0ee17aa1c4b5 (patch) | |
tree | 8ba5896d7bcf69891d85dadec737631aaa7d6e2e | |
parent | dd3e1e3083e6b80ac7cc4dabfbf9b5036b7a889d (diff) |
Misc fixes and cleanup for project quota
1) The Coverity Scan reports some issues for the project
quota patch, including:
1.1) zfs_prop_get_userquota() directly uses the const quota
type value as the condition check by wrong.
1.2) dmu_objset_userquota_get_ids() may cause dnode::dn_newgid
to be overwritten by dnode::dn->dn_oldprojid.
2) This patch fixes related issues. It also enhances the logic
for zfs_project_item_alloc() to avoid buffer overflow.
3) Skip project quota ability check if does not change project
quota related things (id or flag). Otherwise, it will cause
chattr (for other non project quota flags) operation failed
if project quota disabled.
Reviewed-by: Brian Behlendorf <[email protected]>
Signed-off-by: Fan Yong <[email protected]>
Closes #7251
Closes #7265
-rw-r--r-- | cmd/zfs/zfs_project.c | 4 | ||||
-rw-r--r-- | lib/libzfs/libzfs_dataset.c | 3 | ||||
-rw-r--r-- | module/zfs/dmu_objset.c | 2 | ||||
-rw-r--r-- | module/zfs/zfs_vnops.c | 6 |
4 files changed, 9 insertions, 6 deletions
diff --git a/cmd/zfs/zfs_project.c b/cmd/zfs/zfs_project.c index 5ac88f279..341cc005d 100644 --- a/cmd/zfs/zfs_project.c +++ b/cmd/zfs/zfs_project.c @@ -43,7 +43,7 @@ typedef struct zfs_project_item { list_node_t zpi_list; - char zpi_name[PATH_MAX]; + char zpi_name[0]; } zfs_project_item_t; static void @@ -51,7 +51,7 @@ zfs_project_item_alloc(list_t *head, const char *name) { zfs_project_item_t *zpi; - zpi = safe_malloc(sizeof (zfs_project_item_t)); + zpi = safe_malloc(sizeof (zfs_project_item_t) + strlen(name) + 1); strcpy(zpi->zpi_name, name); list_insert_tail(head, zpi); } diff --git a/lib/libzfs/libzfs_dataset.c b/lib/libzfs/libzfs_dataset.c index 1879eb757..17c17fa79 100644 --- a/lib/libzfs/libzfs_dataset.c +++ b/lib/libzfs/libzfs_dataset.c @@ -3179,7 +3179,8 @@ zfs_prop_get_userquota(zfs_handle_t *zhp, const char *propname, } else if (propvalue == 0 && (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA || type == ZFS_PROP_USEROBJQUOTA || type == ZFS_PROP_GROUPOBJQUOTA || - type == ZFS_PROP_PROJECTQUOTA || ZFS_PROP_PROJECTOBJQUOTA)) { + type == ZFS_PROP_PROJECTQUOTA || + type == ZFS_PROP_PROJECTOBJQUOTA)) { (void) strlcpy(propbuf, "none", proplen); } else if (type == ZFS_PROP_USERQUOTA || type == ZFS_PROP_GROUPQUOTA || type == ZFS_PROP_USERUSED || type == ZFS_PROP_GROUPUSED || diff --git a/module/zfs/dmu_objset.c b/module/zfs/dmu_objset.c index d7c46c3e5..c2dd31a8b 100644 --- a/module/zfs/dmu_objset.c +++ b/module/zfs/dmu_objset.c @@ -2077,7 +2077,7 @@ dmu_objset_userquota_get_ids(dnode_t *dn, boolean_t before, dmu_tx_t *tx) if (flags & DN_ID_OLD_EXIST) { dn->dn_newuid = dn->dn_olduid; dn->dn_newgid = dn->dn_oldgid; - dn->dn_newgid = dn->dn_oldprojid; + dn->dn_newprojid = dn->dn_oldprojid; } else { dn->dn_newuid = 0; dn->dn_newgid = 0; diff --git a/module/zfs/zfs_vnops.c b/module/zfs/zfs_vnops.c index f35165de3..a2d7d7b24 100644 --- a/module/zfs/zfs_vnops.c +++ b/module/zfs/zfs_vnops.c @@ -2891,10 +2891,12 @@ zfs_setattr(struct inode *ip, vattr_t *vap, int flags, cred_t *cr) } if (XVA_ISSET_REQ(xvap, XAT_PROJINHERIT) && + (xoap->xoa_projinherit != + ((zp->z_pflags & ZFS_PROJINHERIT) != 0)) && (!dmu_objset_projectquota_enabled(os) || (!S_ISREG(ip->i_mode) && !S_ISDIR(ip->i_mode)))) { - ZFS_EXIT(zfsvfs); - return (SET_ERROR(ENOTSUP)); + ZFS_EXIT(zfsvfs); + return (SET_ERROR(ENOTSUP)); } } |