]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
vfs: Add general support to enforce project quota limits
authorLi Xi <pkuelelixi@gmail.com>
Wed, 18 Mar 2015 19:04:53 +0000 (04:04 +0900)
committerJan Kara <jack@suse.cz>
Wed, 18 Mar 2015 20:55:08 +0000 (21:55 +0100)
This patch adds support for a new quota type PRJQUOTA for project quota
enforcement. Also a new method get_projid() is added into dquot_operations
structure.

Signed-off-by: Li Xi <lixi@ddn.com>
Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Jan Kara <jack@suse.cz>
fs/quota/dquot.c
fs/quota/quotaio_v2.h
include/linux/quota.h
include/uapi/linux/quota.h

index 327a584485928b40ca3e294dccfa44018e9247eb..ecc25cf0ee6e99f96b8d4c7550d8881593c303cf 100644 (file)
@@ -1163,8 +1163,8 @@ static int need_print_warning(struct dquot_warn *warn)
                        return uid_eq(current_fsuid(), warn->w_dq_id.uid);
                case GRPQUOTA:
                        return in_group_p(warn->w_dq_id.gid);
-               case PRJQUOTA:  /* Never taken... Just make gcc happy */
-                       return 0;
+               case PRJQUOTA:
+                       return 1;
        }
        return 0;
 }
@@ -1405,6 +1405,9 @@ static void __dquot_initialize(struct inode *inode, int type)
        /* First get references to structures we might need. */
        for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                struct kqid qid;
+               kprojid_t projid;
+               int rc;
+
                got[cnt] = NULL;
                if (type != -1 && cnt != type)
                        continue;
@@ -1415,6 +1418,10 @@ static void __dquot_initialize(struct inode *inode, int type)
                 */
                if (dquots[cnt])
                        continue;
+
+               if (!sb_has_quota_active(sb, cnt))
+                       continue;
+
                init_needed = 1;
 
                switch (cnt) {
@@ -1424,6 +1431,12 @@ static void __dquot_initialize(struct inode *inode, int type)
                case GRPQUOTA:
                        qid = make_kqid_gid(inode->i_gid);
                        break;
+               case PRJQUOTA:
+                       rc = inode->i_sb->dq_op->get_projid(inode, &projid);
+                       if (rc)
+                               continue;
+                       qid = make_kqid_projid(projid);
+                       break;
                }
                got[cnt] = dqget(sb, qid);
        }
@@ -2176,7 +2189,8 @@ static int vfs_load_quota_inode(struct inode *inode, int type, int format_id,
                error = -EROFS;
                goto out_fmt;
        }
-       if (!sb->s_op->quota_write || !sb->s_op->quota_read) {
+       if (!sb->s_op->quota_write || !sb->s_op->quota_read ||
+           (type == PRJQUOTA && sb->dq_op->get_projid == NULL)) {
                error = -EINVAL;
                goto out_fmt;
        }
index f1966b42c2fdc07c3269a36402ab4bc3e2d9cb76..4e95430093d9959f271b970e645c1911152a7886 100644 (file)
  */
 #define V2_INITQMAGICS {\
        0xd9c01f11,     /* USRQUOTA */\
-       0xd9c01927      /* GRPQUOTA */\
+       0xd9c01927,     /* GRPQUOTA */\
+       0xd9c03f14,     /* PRJQUOTA */\
 }
 
 #define V2_INITQVERSIONS {\
        1,              /* USRQUOTA */\
-       1               /* GRPQUOTA */\
+       1,              /* GRPQUOTA */\
+       1,              /* PRJQUOTA */\
 }
 
 /* First generic header */
index cf910d1f8efad197daf9e8f78c029d157aaa4864..b2505acfd3c078c70e733f7d9e826cfc4b6c9524 100644 (file)
@@ -50,6 +50,7 @@
 
 #undef USRQUOTA
 #undef GRPQUOTA
+#undef PRJQUOTA
 enum quota_type {
        USRQUOTA = 0,           /* element used for user quotas */
        GRPQUOTA = 1,           /* element used for group quotas */
@@ -319,6 +320,7 @@ struct dquot_operations {
        /* get reserved quota for delayed alloc, value returned is managed by
         * quota code only */
        qsize_t *(*get_reserved_space) (struct inode *);
+       int (*get_projid) (struct inode *, kprojid_t *);/* Get project ID */
 };
 
 struct path;
index 1f49b8341c994f27ca84374a1115a1d2be01a1e9..9c95b2c1c88a6ef0a6bb4207cd5122011d3007f9 100644 (file)
 #include <linux/errno.h>
 #include <linux/types.h>
 
-#define __DQUOT_VERSION__      "dquot_6.5.2"
+#define __DQUOT_VERSION__      "dquot_6.6.0"
 
-#define MAXQUOTAS 2
+#define MAXQUOTAS 3
 #define USRQUOTA  0            /* element used for user quotas */
 #define GRPQUOTA  1            /* element used for group quotas */
+#define PRJQUOTA  2            /* element used for project quotas */
 
 /*
  * Definitions for the default names of the quotas files.
@@ -48,6 +49,7 @@
 #define INITQFNAMES { \
        "user",    /* USRQUOTA */ \
        "group",   /* GRPQUOTA */ \
+       "project", /* PRJQUOTA */ \
        "undefined", \
 };