VFS quota: add per mount-point global, uid and gid limit fields.
authorFrancois Tigeot <ftigeot@wolfpond.org>
Sat, 17 Mar 2012 17:17:49 +0000 (18:17 +0100)
committerFran├žois Tigeot <ftigeot@wolfpond.org>
Sun, 15 Apr 2012 17:38:00 +0000 (19:38 +0200)
sbin/vquota/vquota.c
sys/kern/vfs_quota.c
sys/sys/mount.h

index faf7d4f..b532420 100644 (file)
@@ -312,8 +312,8 @@ get_dirsize(char* dirname)
                                unp = unode_insert(file_uid);
                        if ((gnp = RB_FIND(ac_gtree, &ac_groot, &gfind)) == NULL)
                                gnp = gnode_insert(file_gid);
-                       unp->uid_chunk[(file_uid & ACCT_CHUNK_MASK)] += file_size;
-                       gnp->gid_chunk[(file_gid & ACCT_CHUNK_MASK)] += file_size;
+                       unp->uid_chunk[(file_uid & ACCT_CHUNK_MASK)].space += file_size;
+                       gnp->gid_chunk[(file_gid & ACCT_CHUNK_MASK)].space += file_size;
                }
        }
        fts_close(fts);
@@ -365,30 +365,30 @@ cmd_check(char* dirname)
        }
        RB_FOREACH(unp, ac_utree, &ac_uroot) {
            for (i=0; i<ACCT_CHUNK_NIDS; i++) {
-               if (unp->uid_chunk[i] != 0) {
+               if (unp->uid_chunk[i].space != 0) {
                    uid = (unp->left_bits << ACCT_CHUNK_BITS) + i;
                    print_user(uid);
                    if (flag_humanize) {
                        humanize_number(hbuf, sizeof(hbuf),
-                       unp->uid_chunk[i], "", HN_AUTOSCALE, HN_NOSPACE);
+                       unp->uid_chunk[i].space, "", HN_AUTOSCALE, HN_NOSPACE);
                        printf(" %s\n", hbuf);
                    } else {
-                       printf(" %" PRIu64 "\n", unp->uid_chunk[i]);
+                       printf(" %" PRIu64 "\n", unp->uid_chunk[i].space);
                    }
                }
            }
        }
        RB_FOREACH(gnp, ac_gtree, &ac_groot) {
            for (i=0; i<ACCT_CHUNK_NIDS; i++) {
-               if (gnp->gid_chunk[i] != 0) {
+               if (gnp->gid_chunk[i].space != 0) {
                    gid = (gnp->left_bits << ACCT_CHUNK_BITS) + i;
                    print_group(gid);
                    if (flag_humanize) {
                        humanize_number(hbuf, sizeof(hbuf),
-                       gnp->gid_chunk[i], "", HN_AUTOSCALE, HN_NOSPACE);
+                       gnp->gid_chunk[i].space, "", HN_AUTOSCALE, HN_NOSPACE);
                        printf(" %s\n", hbuf);
                    } else {
-                       printf(" %" PRIu64 "\n", gnp->gid_chunk[i]);
+                       printf(" %" PRIu64 "\n", gnp->gid_chunk[i].space);
                    }
                }
            }
@@ -570,24 +570,24 @@ static int cmd_sync(char *dirname)
 
        RB_FOREACH(unp, ac_utree, &ac_uroot) {
            for (i=0; i<ACCT_CHUNK_NIDS; i++) {
-               if (unp->uid_chunk[i] != 0) {
+               if (unp->uid_chunk[i].space != 0) {
                    item = prop_dictionary_create();
                    (void) prop_dictionary_set_uint32(item, "uid",
                                (unp->left_bits << ACCT_CHUNK_BITS) + i);
                    (void) prop_dictionary_set_uint64(item, "space used",
-                               unp->uid_chunk[i]);
+                               unp->uid_chunk[i].space);
                    prop_array_add_and_rel(args, item);
                }
            }
        }
        RB_FOREACH(gnp, ac_gtree, &ac_groot) {
            for (i=0; i<ACCT_CHUNK_NIDS; i++) {
-               if (gnp->gid_chunk[i] != 0) {
+               if (gnp->gid_chunk[i].space != 0) {
                    item = prop_dictionary_create();
                    (void) prop_dictionary_set_uint32(item, "gid",
                                (gnp->left_bits << ACCT_CHUNK_BITS) + i);
                    (void) prop_dictionary_set_uint64(item, "space used",
-                               gnp->gid_chunk[i]);
+                               gnp->gid_chunk[i].space);
                    prop_array_add_and_rel(args, item);
                }
            }
index ea67458..84959d9 100644 (file)
@@ -165,8 +165,8 @@ vfs_stdaccount(struct mount *mp, uid_t uid, gid_t gid, int64_t delta)
                gnp = gnode_insert(mp, gid);
 
        /* update existing chunk */
-       unp->uid_chunk[(uid & ACCT_CHUNK_MASK)] += delta;
-       gnp->gid_chunk[(gid & ACCT_CHUNK_MASK)] += delta;
+       unp->uid_chunk[(uid & ACCT_CHUNK_MASK)].space += delta;
+       gnp->gid_chunk[(gid & ACCT_CHUNK_MASK)].space += delta;
 
        spin_unlock(&mp->mnt_acct.ac_spin);
 }
@@ -185,12 +185,12 @@ cmd_get_usage_all(struct mount *mp, prop_array_t dict_out)
 
        RB_FOREACH(unp, ac_utree, &mp->mnt_acct.ac_uroot) {
                for (i=0; i<ACCT_CHUNK_NIDS; i++) {
-                       if (unp->uid_chunk[i] != 0) {
+                       if (unp->uid_chunk[i].space != 0) {
                                item = prop_dictionary_create();
                                (void) prop_dictionary_set_uint32(item, "uid",
                                        (unp->left_bits << ACCT_CHUNK_BITS) + i);
                                (void) prop_dictionary_set_uint64(item, "space used",
-                                       unp->uid_chunk[i]);
+                                       unp->uid_chunk[i].space);
                                prop_array_add_and_rel(dict_out, item);
                        }
                }
@@ -198,12 +198,12 @@ cmd_get_usage_all(struct mount *mp, prop_array_t dict_out)
 
        RB_FOREACH(gnp, ac_gtree, &mp->mnt_acct.ac_groot) {
                for (i=0; i<ACCT_CHUNK_NIDS; i++) {
-                       if (gnp->gid_chunk[i] != 0) {
+                       if (gnp->gid_chunk[i].space != 0) {
                                item = prop_dictionary_create();
                                (void) prop_dictionary_set_uint32(item, "gid",
                                        (gnp->left_bits << ACCT_CHUNK_BITS) + i);
                                (void) prop_dictionary_set_uint64(item, "space used",
-                                       gnp->gid_chunk[i]);
+                                       gnp->gid_chunk[i].space);
                                prop_array_add_and_rel(dict_out, item);
                        }
                }
@@ -247,13 +247,13 @@ cmd_set_usage_all(struct mount *mp, prop_array_t args)
                        unp = RB_FIND(ac_utree, &mp->mnt_acct.ac_uroot, &ufind);
                        if (unp == NULL)
                                unp = unode_insert(mp, id);
-                       unp->uid_chunk[(id & ACCT_CHUNK_MASK)] = space;
+                       unp->uid_chunk[(id & ACCT_CHUNK_MASK)].space = space;
                } else if (prop_dictionary_get_uint32(item, "gid", &id)) {
                        gfind.left_bits = (id >> ACCT_CHUNK_BITS);
                        gnp = RB_FIND(ac_gtree, &mp->mnt_acct.ac_groot, &gfind);
                        if (gnp == NULL)
                                gnp = gnode_insert(mp, id);
-                       gnp->gid_chunk[(id & ACCT_CHUNK_MASK)] = space;
+                       gnp->gid_chunk[(id & ACCT_CHUNK_MASK)].space = space;
                } else {
                        mp->mnt_acct.ac_bytes = space;
                }
index e3c3b1c..14c9bc0 100644 (file)
@@ -155,16 +155,21 @@ struct bio_ops {
 #define ACCT_CHUNK_NIDS        (1<<ACCT_CHUNK_BITS)
 #define ACCT_CHUNK_MASK        (ACCT_CHUNK_NIDS - 1)
 
+struct ac_counters {
+       uint64_t space;
+       uint64_t limit;
+};
+
 struct ac_unode {
        RB_ENTRY(ac_unode)      rb_entry;
        uid_t                   left_bits;
-       uint64_t                uid_chunk[ACCT_CHUNK_NIDS];
+       struct ac_counters      uid_chunk[ACCT_CHUNK_NIDS];
 };
 
 struct ac_gnode {
        RB_ENTRY(ac_gnode)      rb_entry;
        gid_t                   left_bits;
-       uint64_t                gid_chunk[ACCT_CHUNK_NIDS];
+       struct ac_counters      gid_chunk[ACCT_CHUNK_NIDS];
 };
 
 #if defined(_KERNEL) || defined(_KERNEL_STRUCTURES)
@@ -173,6 +178,7 @@ struct vfs_acct {
        RB_HEAD(ac_utree,ac_unode)      ac_uroot;
        RB_HEAD(ac_gtree,ac_gnode)      ac_groot;
        uint64_t                        ac_bytes;       /* total bytes used */
+       uint64_t                        ac_limit;
        struct spinlock                 ac_spin;        /* protective spinlock */
 };