static int do_proc_dqstats(struct ctl_table *table, int write,
                     void __user *buffer, size_t *lenp, loff_t *ppos)
 {
-       unsigned int type = (int *)table->data - dqstats.stat;
+       unsigned int type = (unsigned long *)table->data - dqstats.stat;
+       s64 value = percpu_counter_sum(&dqstats.counter[type]);
+
+       /* Filter negative values for non-monotonic counters */
+       if (value < 0 && (type == DQST_ALLOC_DQUOTS ||
+                         type == DQST_FREE_DQUOTS))
+               value = 0;
 
        /* Update global table */
-       dqstats.stat[type] =
-                       percpu_counter_sum_positive(&dqstats.counter[type]);
-       return proc_dointvec(table, write, buffer, lenp, ppos);
+       dqstats.stat[type] = value;
+       return proc_doulongvec_minmax(table, write, buffer, lenp, ppos);
 }
 
 static struct ctl_table fs_dqstats_table[] = {
        {
                .procname       = "lookups",
                .data           = &dqstats.stat[DQST_LOOKUPS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "drops",
                .data           = &dqstats.stat[DQST_DROPS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "reads",
                .data           = &dqstats.stat[DQST_READS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "writes",
                .data           = &dqstats.stat[DQST_WRITES],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "cache_hits",
                .data           = &dqstats.stat[DQST_CACHE_HITS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "allocated_dquots",
                .data           = &dqstats.stat[DQST_ALLOC_DQUOTS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "free_dquots",
                .data           = &dqstats.stat[DQST_FREE_DQUOTS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },
        {
                .procname       = "syncs",
                .data           = &dqstats.stat[DQST_SYNCS],
-               .maxlen         = sizeof(int),
+               .maxlen         = sizeof(unsigned long),
                .mode           = 0444,
                .proc_handler   = do_proc_dqstats,
        },