]> git.proxmox.com Git - mirror_zfs.git/commitdiff
Misc fixes and cleanup for project quota
authorNasf-Fan <fan.yong@intel.com>
Mon, 5 Mar 2018 20:56:27 +0000 (04:56 +0800)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Mon, 5 Mar 2018 20:56:27 +0000 (12:56 -0800)
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 <behlendorf1@llnl.gov>
Signed-off-by: Fan Yong <fan.yong@intel.com>
Closes #7251
Closes #7265

cmd/zfs/zfs_project.c
lib/libzfs/libzfs_dataset.c
module/zfs/dmu_objset.c
module/zfs/zfs_vnops.c

index 5ac88f279b5b5a8cbd4760243d260bb91bb488ee..341cc005de48e40fd2251d1bb9eede4720cd1773 100644 (file)
@@ -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);
 }
index 1879eb757f332b11b44db9852c45377c685c95f8..17c17fa798bfac281f47fefed9bf3a1c0c5e22ba 100644 (file)
@@ -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 ||
index d7c46c3e51dfc34394e4c15b28927811e6b40d3d..c2dd31a8b8affc8daa50059842636161bea788b2 100644 (file)
@@ -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;
index f35165de3e8976cd95b2baab53e255935dc2517e..a2d7d7b24da6ff89bb4104916b01a249a555f7fd 100644 (file)
@@ -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));
                }
        }