diff --git a/lustre/ChangeLog b/lustre/ChangeLog
index 24e129b78230b08fec4d19341c5b0da009f3d6b5..a100d5a70adbc417ccf4f1aca32bb8e12ac2c899 100644
--- a/lustre/ChangeLog
+++ b/lustre/ChangeLog
@@ -335,6 +335,12 @@ Details    : Current xattr code updates the inode ctime in ext3_xattr_set_handle
              2.0->1.8 compatibility it is necessary to delete an xattr and it
              should not update the ctime.
 
+Severity   : normal
+Bugzilla   : 15058
+Description: add quota statistics
+Details    : 1. sort out quota proc entries and proc code.
+             2. add quota statistics
+
 -------------------------------------------------------------------------------
 
 
diff --git a/lustre/include/lprocfs_status.h b/lustre/include/lprocfs_status.h
index 997cfa7e146699b3ad6ec716f31a80738c3d1d51..697a459be610c8da2583d10eb27d80bd97534c49 100644
--- a/lustre/include/lprocfs_status.h
+++ b/lustre/include/lprocfs_status.h
@@ -563,6 +563,52 @@ int lprocfs_obd_wr_recovery_maxtime(struct file *file, const char *buffer,
                                     unsigned long count, void *data);
 #endif
 
+/* all quota proc functions */
+extern int lprocfs_quota_rd_bunit(char *page, char **start, off_t off, int count,
+                                  int *eof, void *data);
+extern int lprocfs_quota_wr_bunit(struct file *file, const char *buffer,
+                                  unsigned long count, void *data);
+extern int lprocfs_quota_rd_btune(char *page, char **start, off_t off, int count,
+                                  int *eof, void *data);
+extern int lprocfs_quota_wr_btune(struct file *file, const char *buffer,
+                                  unsigned long count, void *data);
+extern int lprocfs_quota_rd_iunit(char *page, char **start, off_t off, int count,
+                                  int *eof, void *data);
+extern int lprocfs_quota_wr_iunit(struct file *file, const char *buffer,
+                                  unsigned long count, void *data);
+extern int lprocfs_quota_rd_itune(char *page, char **start, off_t off, int count,
+                                  int *eof, void *data);
+extern int lprocfs_quota_wr_itune(struct file *file, const char *buffer,
+                                  unsigned long count, void *data);
+extern int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count,
+                                 int *eof, void *data);
+extern int lprocfs_quota_wr_type(struct file *file, const char *buffer,
+                                 unsigned long count, void *data);
+extern int lprocfs_quota_rd_switch_seconds(char *page, char **start, off_t off,
+                                           int count, int *eof, void *data);
+extern int lprocfs_quota_wr_switch_seconds(struct file *file, const char *buffer,
+                                           unsigned long count, void *data);
+extern int lprocfs_quota_rd_switch_qs(char *page, char **start, off_t off,
+                                      int count, int *eof, void *data);
+extern int lprocfs_quota_wr_switch_qs(struct file *file, const char *buffer,
+                                      unsigned long count, void *data);
+extern int lprocfs_quota_rd_boundary_factor(char *page, char **start, off_t off,
+                                            int count, int *eof, void *data);
+extern int lprocfs_quota_wr_boundary_factor(struct file *file, const char *buffer,
+                                            unsigned long count, void *data);
+extern int lprocfs_quota_rd_least_bunit(char *page, char **start, off_t off,
+                                        int count, int *eof, void *data);
+extern int lprocfs_quota_wr_least_bunit(struct file *file, const char *buffer,
+                                        unsigned long count, void *data);
+extern int lprocfs_quota_rd_least_iunit(char *page, char **start, off_t off,
+                                        int count, int *eof, void *data);
+extern int lprocfs_quota_wr_least_iunit(struct file *file, const char *buffer,
+                                        unsigned long count, void *data);
+extern int lprocfs_quota_rd_qs_factor(char *page, char **start, off_t off,
+                                      int count, int *eof, void *data);
+extern int lprocfs_quota_wr_qs_factor(struct file *file, const char *buffer,
+                                      unsigned long count, void *data);
+
 #else
 /* LPROCFS is not defined */
 static inline void lprocfs_counter_add(struct lprocfs_stats *stats,
diff --git a/lustre/include/lustre_quota.h b/lustre/include/lustre_quota.h
index c6d7c7c53390167616f3e844b95bc0cdc38cb320..81a306e603825bec561e680f02fc3dbd92f6e66b 100644
--- a/lustre/include/lustre_quota.h
+++ b/lustre/include/lustre_quota.h
@@ -63,6 +63,40 @@ struct client_obd;
 
 #ifdef __KERNEL__
 
+#ifdef LPROCFS
+enum {
+        LQUOTA_FIRST_STAT = 0,
+        /* these four are for measuring quota requests, for both of
+         * quota master and quota slaves */
+        LQUOTA_SYNC_ACQ = LQUOTA_FIRST_STAT,
+        LQUOTA_SYNC_REL,
+        LQUOTA_ASYNC_ACQ,
+        LQUOTA_ASYNC_REL,
+        /* these four measure how much time I/O threads spend on dealing
+         * with quota before and after writing data or creating files,
+         * only for quota slaves(lquota_chkquota and lquota_pending_commit) */
+        LQUOTA_WAIT_FOR_CHK_BLK,
+        LQUOTA_WAIT_FOR_CHK_INO,
+        LQUOTA_WAIT_FOR_COMMIT_BLK,
+        LQUOTA_WAIT_FOR_COMMIT_INO,
+        /* these two are for measuring time waiting return of quota reqs
+         * (qctxt_wait_pending_dqacq), only for quota salves */
+        LQUOTA_WAIT_PENDING_BLK_QUOTA,
+        LQUOTA_WAIT_PENDING_INO_QUOTA,
+        /* these two are for those when they are calling
+         * qctxt_wait_pending_dqacq, the quota req has returned already,
+         * only for quota salves */
+        LQUOTA_NOWAIT_PENDING_BLK_QUOTA,
+        LQUOTA_NOWAIT_PENDING_INO_QUOTA,
+        /* these are for quota ctl */
+        LQUOTA_QUOTA_CTL,
+        /* these are for adjust quota qunit, for both of
+         * quota master and quota slaves  */
+        LQUOTA_ADJUST_QUNIT,
+        LQUOTA_LAST_STAT
+};
+#endif  /* LPROCFS */
+
 /* structures to access admin quotafile */
 struct lustre_mem_dqinfo {
         unsigned int dqi_bgrace;
@@ -226,6 +260,8 @@ struct lustre_quota_ctxt {
                                              * seconds must be waited between
                                              * enlarging and shinking qunit */
         spinlock_t    lqc_lock;         /* guard lqc_imp_valid now */
+        struct proc_dir_entry *lqc_proc_dir;
+        struct lprocfs_stats  *lqc_stats; /* lquota statistics */
 };
 
 #define LQC_HASH_BODY(qctxt) (qctxt->lqc_lqs_hash_body)
@@ -369,8 +405,9 @@ typedef struct {
                             obd_flag, obd_flag);
 
         /* For adjusting qunit size b=10600 */
-        int (*quota_adjust_qunit) (struct obd_export *exp, struct
-                                   quota_adjust_qunit *oqaq);
+        int (*quota_adjust_qunit) (struct obd_export *exp,
+                                   struct quota_adjust_qunit *oqaq,
+                                   struct lustre_quota_ctxt *qctxt);
 
 } quota_interface_t;
 
@@ -590,31 +627,6 @@ static inline int lquota_pending_commit(quota_interface_t *interface,
         RETURN(rc);
 }
 
-int lprocfs_quota_rd_bunit(char *page, char **start, off_t off, int count,
-                           int *eof, void *data);
-int lprocfs_quota_wr_bunit(struct file *file, const char *buffer,
-                           unsigned long count, void *data);
-int lprocfs_quota_rd_btune(char *page, char **start, off_t off, int count,
-                           int *eof, void *data);
-int lprocfs_quota_wr_btune(struct file *file, const char *buffer,
-                           unsigned long count, void *data);
-int lprocfs_quota_rd_iunit(char *page, char **start, off_t off, int count,
-                           int *eof, void *data);
-int lprocfs_quota_wr_iunit(struct file *file, const char *buffer,
-                           unsigned long count, void *data);
-int lprocfs_quota_rd_itune(char *page, char **start, off_t off, int count,
-                           int *eof, void *data);
-int lprocfs_quota_wr_itune(struct file *file, const char *buffer,
-                           unsigned long count, void *data);
-int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count,
-                          int *eof, void *data);
-int lprocfs_quota_wr_type(struct file *file, const char *buffer,
-                          unsigned long count, void *data);
-int lprocfs_quota_rd_switch_seconds(char *page, char **start, off_t off,
-                                    int count, int *eof, void *data);
-int lprocfs_quota_wr_switch_seconds(struct file *file, const char *buffer,
-                                    unsigned long count, void *data);
-
 #ifndef __KERNEL__
 extern quota_interface_t osc_quota_interface;
 extern quota_interface_t mdc_quota_interface;
diff --git a/lustre/include/obd.h b/lustre/include/obd.h
index 7cccdb5d49db4e3343710e38b88dd01bf36c3d8f..e3556cfdc95a84fd72fa714befdbac32512499e3 100644
--- a/lustre/include/obd.h
+++ b/lustre/include/obd.h
@@ -1109,7 +1109,8 @@ struct obd_ops {
         int (*o_quotacheck)(struct obd_export *, struct obd_quotactl *);
         int (*o_quotactl)(struct obd_export *, struct obd_quotactl *);
         int (*o_quota_adjust_qunit)(struct obd_export *exp,
-                                    struct quota_adjust_qunit *oqaq);
+                                    struct quota_adjust_qunit *oqaq,
+                                    struct lustre_quota_ctxt *qctxt);
 
 
         int (*o_ping)(struct obd_export *exp);
diff --git a/lustre/include/obd_class.h b/lustre/include/obd_class.h
index f370f3f05649bfdeaf6102d63d786f1278fccc56..dee007ff5701298b910b6db8afcce595c7adb51c 100644
--- a/lustre/include/obd_class.h
+++ b/lustre/include/obd_class.h
@@ -1408,15 +1408,34 @@ static inline int obd_quotactl(struct obd_export *exp,
 }
 
 static inline int obd_quota_adjust_qunit(struct obd_export *exp,
-                                         struct quota_adjust_qunit *oqaq)
+                                         struct quota_adjust_qunit *oqaq,
+                                         struct lustre_quota_ctxt *qctxt)
 {
+#ifdef LPROCFS
+        struct timeval work_start;
+        struct timeval work_end;
+        long timediff;
+#endif
         int rc;
         ENTRY;
 
+#ifdef LPROCFS
+        if (qctxt)
+                do_gettimeofday(&work_start);
+#endif
         EXP_CHECK_OP(exp, quota_adjust_qunit);
         EXP_COUNTER_INCREMENT(exp, quota_adjust_qunit);
 
-        rc = OBP(exp->exp_obd, quota_adjust_qunit)(exp, oqaq);
+        rc = OBP(exp->exp_obd, quota_adjust_qunit)(exp, oqaq, qctxt);
+
+#ifdef LPROCFS
+        if (qctxt) {
+                do_gettimeofday(&work_end);
+                timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
+                lprocfs_counter_add(qctxt->lqc_stats, LQUOTA_ADJUST_QUNIT,
+                                    timediff);
+        }
+#endif
         RETURN(rc);
 }
 
diff --git a/lustre/mds/lproc_mds.c b/lustre/mds/lproc_mds.c
index aee7e6ae07cd4f965e7e7a4614064cd5f218ca7f..9bbe76a0e13351c4ee0e4bfa8b3dc543d3d6d0cf 100644
--- a/lustre/mds/lproc_mds.c
+++ b/lustre/mds/lproc_mds.c
@@ -405,155 +405,6 @@ static int lprocfs_rd_nosquash_nid(char *page, char **start, off_t off,
                         libcfs_nid2str(mds->mds_nosquash_nid));
 }
 
-#ifdef HAVE_QUOTA_SUPPORT
-static int lprocfs_mds_rd_switch_qs(char *page, char **start, off_t off,
-                                    int count, int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-        return snprintf(page, count, "changing qunit size is %s\n",
-                        obd->u.obt.obt_qctxt.lqc_switch_qs ?
-                        "enabled" : "disabled");
-}
-
-static int lprocfs_mds_rd_boundary_factor(char *page, char **start, off_t off,
-                                          int count, int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-
-        return snprintf(page, count, "%lu\n",
-                        obd->u.obt.obt_qctxt.lqc_cqs_boundary_factor);
-}
-
-static int lprocfs_mds_rd_least_bunit(char *page, char **start, off_t off,
-                                      int count, int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-
-        return snprintf(page, count, "%lu\n",
-                        obd->u.obt.obt_qctxt.lqc_cqs_least_bunit);
-}
-
-static int lprocfs_mds_rd_least_iunit(char *page, char **start, off_t off,
-                                      int count, int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-
-        return snprintf(page, count, "%lu\n",
-                        obd->u.obt.obt_qctxt.lqc_cqs_least_iunit);
-}
-
-static int lprocfs_mds_rd_qs_factor(char *page, char **start, off_t off,
-                                    int count, int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-
-        return snprintf(page, count, "%lu\n",
-                        obd->u.obt.obt_qctxt.lqc_cqs_qs_factor);
-}
-
-static int lprocfs_mds_wr_switch_qs(struct file *file, const char *buffer,
-                                    unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val)
-            obd->u.obt.obt_qctxt.lqc_switch_qs = 1;
-        else
-            obd->u.obt.obt_qctxt.lqc_switch_qs = 0;
-
-        return count;
-}
-
-static int lprocfs_mds_wr_boundary_factor(struct file *file, const char *buffer,
-                                          unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val < 2)
-                return -EINVAL;
-
-        obd->u.obt.obt_qctxt.lqc_cqs_boundary_factor = val;
-        return count;
-}
-
-static int lprocfs_mds_wr_least_bunit(struct file *file, const char *buffer,
-                                  unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val < PTLRPC_MAX_BRW_SIZE ||
-            val >= obd->u.obt.obt_qctxt.lqc_bunit_sz)
-                return -EINVAL;
-
-        obd->u.obt.obt_qctxt.lqc_cqs_least_bunit = val;
-        return count;
-}
-
-static int lprocfs_mds_wr_least_iunit(struct file *file, const char *buffer,
-                                  unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val < 1 || val >= obd->u.obt.obt_qctxt.lqc_iunit_sz)
-                return -EINVAL;
-
-        obd->u.obt.obt_qctxt.lqc_cqs_least_iunit = val;
-        return count;
-}
-
-static int lprocfs_mds_wr_qs_factor(struct file *file, const char *buffer,
-                                    unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val < 2)
-                return -EINVAL;
-
-        obd->u.obt.obt_qctxt.lqc_cqs_qs_factor = val;
-        return count;
-}
-#endif
-
 struct lprocfs_vars lprocfs_mds_obd_vars[] = {
         { "uuid",            lprocfs_rd_uuid,        0, 0 },
         { "blocksize",       lprocfs_rd_blksize,     0, 0 },
@@ -575,16 +426,16 @@ struct lprocfs_vars lprocfs_mds_obd_vars[] = {
         { "quota_iunit_sz",  lprocfs_quota_rd_iunit, lprocfs_quota_wr_iunit, 0 },
         { "quota_itune_sz",  lprocfs_quota_rd_itune, lprocfs_quota_wr_itune, 0 },
         { "quota_type",      lprocfs_quota_rd_type,  lprocfs_quota_wr_type, 0 },
-        { "quota_switch_qs", lprocfs_mds_rd_switch_qs,
-                             lprocfs_mds_wr_switch_qs, 0 },
-        { "quota_boundary_factor", lprocfs_mds_rd_boundary_factor,
-                                   lprocfs_mds_wr_boundary_factor, 0 },
-        { "quota_least_bunit", lprocfs_mds_rd_least_bunit,
-                               lprocfs_mds_wr_least_bunit, 0 },
-        { "quota_least_iunit", lprocfs_mds_rd_least_iunit,
-                               lprocfs_mds_wr_least_iunit, 0 },
-        { "quota_qs_factor",   lprocfs_mds_rd_qs_factor,
-                               lprocfs_mds_wr_qs_factor, 0 },
+        { "quota_switch_qs", lprocfs_quota_rd_switch_qs,
+                             lprocfs_quota_wr_switch_qs, 0 },
+        { "quota_boundary_factor", lprocfs_quota_rd_boundary_factor,
+                                   lprocfs_quota_wr_boundary_factor, 0 },
+        { "quota_least_bunit", lprocfs_quota_rd_least_bunit,
+                               lprocfs_quota_wr_least_bunit, 0 },
+        { "quota_least_iunit", lprocfs_quota_rd_least_iunit,
+                               lprocfs_quota_wr_least_iunit, 0 },
+        { "quota_qs_factor",   lprocfs_quota_rd_qs_factor,
+                               lprocfs_quota_wr_qs_factor, 0 },
         { "quota_switch_seconds",  lprocfs_quota_rd_switch_seconds,
                                    lprocfs_quota_wr_switch_seconds, 0 },
 #endif
diff --git a/lustre/obdclass/lprocfs_status.c b/lustre/obdclass/lprocfs_status.c
index 080adf6e894aa05e5dddedde5cbb6f7942debb68..5522d9d9e87aa057133367ce0ac73905b9b2f635 100644
--- a/lustre/obdclass/lprocfs_status.c
+++ b/lustre/obdclass/lprocfs_status.c
@@ -1773,163 +1773,6 @@ int lprocfs_obd_wr_recovery_maxtime(struct file *file, const char *buffer,
 EXPORT_SYMBOL(lprocfs_obd_wr_recovery_maxtime);
 #endif /* CRAY_XT3 */
 
-#ifdef HAVE_QUOTA_SUPPORT
-int lprocfs_quota_rd_bunit(char *page, char **start, off_t off, int count,
-                           int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-        return snprintf(page, count, "%lu\n",
-                        obd->u.obt.obt_qctxt.lqc_bunit_sz);
-}
-EXPORT_SYMBOL(lprocfs_quota_rd_bunit);
-
-int lprocfs_quota_wr_bunit(struct file *file, const char *buffer,
-                           unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val % QUOTABLOCK_SIZE ||
-            val <= obd->u.obt.obt_qctxt.lqc_btune_sz)
-                return -EINVAL;
-
-        obd->u.obt.obt_qctxt.lqc_bunit_sz = val;
-        return count;
-}
-EXPORT_SYMBOL(lprocfs_quota_wr_bunit);
-
-int lprocfs_quota_rd_btune(char *page, char **start, off_t off, int count,
-                           int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-        return snprintf(page, count, "%lu\n",
-                        obd->u.obt.obt_qctxt.lqc_btune_sz);
-}
-EXPORT_SYMBOL(lprocfs_quota_rd_btune);
-
-int lprocfs_quota_wr_btune(struct file *file, const char *buffer,
-                           unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val <= QUOTABLOCK_SIZE * MIN_QLIMIT || val % QUOTABLOCK_SIZE ||
-            val >= obd->u.obt.obt_qctxt.lqc_bunit_sz)
-                return -EINVAL;
-
-        obd->u.obt.obt_qctxt.lqc_btune_sz = val;
-        return count;
-}
-EXPORT_SYMBOL(lprocfs_quota_wr_btune);
-
-int lprocfs_quota_rd_iunit(char *page, char **start, off_t off, int count,
-                           int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-        return snprintf(page, count, "%lu\n",
-                        obd->u.obt.obt_qctxt.lqc_iunit_sz);
-}
-EXPORT_SYMBOL(lprocfs_quota_rd_iunit);
-
-int lprocfs_quota_wr_iunit(struct file *file, const char *buffer,
-                           unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val <= obd->u.obt.obt_qctxt.lqc_itune_sz)
-                return -EINVAL;
-
-        obd->u.obt.obt_qctxt.lqc_iunit_sz = val;
-        return count;
-}
-EXPORT_SYMBOL(lprocfs_quota_wr_iunit);
-
-int lprocfs_quota_rd_itune(char *page, char **start, off_t off, int count,
-                           int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-        return snprintf(page, count, "%lu\n",
-                        obd->u.obt.obt_qctxt.lqc_itune_sz);
-}
-EXPORT_SYMBOL(lprocfs_quota_rd_itune);
-
-int lprocfs_quota_wr_itune(struct file *file, const char *buffer,
-                           unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val <= MIN_QLIMIT ||
-            val >= obd->u.obt.obt_qctxt.lqc_iunit_sz)
-                return -EINVAL;
-
-        obd->u.obt.obt_qctxt.lqc_itune_sz = val;
-        return count;
-}
-EXPORT_SYMBOL(lprocfs_quota_wr_itune);
-
-int lprocfs_quota_rd_switch_seconds(char *page, char **start, off_t off,
-                                    int count, int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        LASSERT(obd != NULL);
-
-        return snprintf(page, count, "%d\n",
-                        obd->u.obt.obt_qctxt.lqc_switch_seconds);
-}
-EXPORT_SYMBOL(lprocfs_quota_rd_switch_seconds);
-
-int lprocfs_quota_wr_switch_seconds(struct file *file, const char *buffer,
-                                    unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        int val, rc;
-        LASSERT(obd != NULL);
-
-        rc = lprocfs_write_helper(buffer, count, &val);
-        if (rc)
-                return rc;
-
-        if (val <= 10)
-                return -EINVAL;
-
-        obd->u.obt.obt_qctxt.lqc_switch_seconds = val;
-        return count;
-}
-EXPORT_SYMBOL(lprocfs_quota_wr_switch_seconds);
-
-#endif
-
-
 EXPORT_SYMBOL(lprocfs_register);
 EXPORT_SYMBOL(lprocfs_srch);
 EXPORT_SYMBOL(lprocfs_remove);
diff --git a/lustre/obdfilter/lproc_obdfilter.c b/lustre/obdfilter/lproc_obdfilter.c
index 65bb6dab983dffe964af16ba2a8666426af39457..8fa00f1a14645e97f6a35c386e5b9098775cd6e7 100644
--- a/lustre/obdfilter/lproc_obdfilter.c
+++ b/lustre/obdfilter/lproc_obdfilter.c
@@ -225,8 +225,7 @@ static struct lprocfs_vars lprocfs_filter_obd_vars[] = {
         { "quota_type",     lprocfs_quota_rd_type,
                             lprocfs_quota_wr_type, 0},
         { "quota_switch_seconds",  lprocfs_quota_rd_switch_seconds,
-                            lprocfs_quota_wr_switch_seconds, 0 },
-
+                                   lprocfs_quota_wr_switch_seconds, 0 },
 #endif
         { "client_cache_count", lprocfs_filter_rd_fmd_max_num,
                           lprocfs_filter_wr_fmd_max_num, 0 },
diff --git a/lustre/ost/ost_handler.c b/lustre/ost/ost_handler.c
index 4ddb1eafd36cf23aecdfb01ce540b919e0044753..836bedf0688951ade9cd8ce32abc6172f8440610 100644
--- a/lustre/ost/ost_handler.c
+++ b/lustre/ost/ost_handler.c
@@ -1389,10 +1389,12 @@ static int ost_handle_quotacheck(struct ptlrpc_request *req)
 static int ost_handle_quota_adjust_qunit(struct ptlrpc_request *req)
 {
         struct quota_adjust_qunit *oqaq, *repoqa;
+        struct lustre_quota_ctxt *qctxt;
         int size[2] = { sizeof(struct ptlrpc_body), sizeof(*repoqa) };
         int rc;
         ENTRY;
 
+        qctxt = &req->rq_export->exp_obd->u.obt.obt_qctxt;
         oqaq = lustre_swab_reqbuf(req, REQ_REC_OFF, sizeof(*oqaq),
                                   lustre_swab_quota_adjust_qunit);
 
@@ -1402,7 +1404,7 @@ static int ost_handle_quota_adjust_qunit(struct ptlrpc_request *req)
         if (rc)
                 GOTO(out, rc);
         repoqa = lustre_msg_buf(req->rq_repmsg, REPLY_REC_OFF, sizeof(*repoqa));
-        req->rq_status = obd_quota_adjust_qunit(req->rq_export, oqaq);
+        req->rq_status = obd_quota_adjust_qunit(req->rq_export, oqaq, qctxt);
         *repoqa = *oqaq;
  out:
         RETURN(rc);
diff --git a/lustre/quota/Makefile.in b/lustre/quota/Makefile.in
index 2f1bfad372111ed6d135308d5f6409c86e54785b..112e82d05921bb194ff07f4567cbf729971706a6 100644
--- a/lustre/quota/Makefile.in
+++ b/lustre/quota/Makefile.in
@@ -2,7 +2,7 @@ MODULES := lquota
 MODULES += quotactl_test quotacheck_test
 
 lquota-objs := quota_check.o quota_context.o quota_ctl.o quota_interface.o
-lquota-objs += quota_master.o quota_adjust_qunit.o
+lquota-objs += quota_master.o quota_adjust_qunit.o lproc_quota.o
 quotactl-objs := quotactl_test.o
 quotaccheck-objs := quotacheck_test.o
 
diff --git a/lustre/quota/lproc_quota.c b/lustre/quota/lproc_quota.c
new file mode 100644
index 0000000000000000000000000000000000000000..244a22802a03edd4348e5d03215a5de33b264017
--- /dev/null
+++ b/lustre/quota/lproc_quota.c
@@ -0,0 +1,719 @@
+/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
+ * vim:expandtab:shiftwidth=8:tabstop=8:
+ *
+ *  Copyright (C) 2002, 2003 Cluster File Systems, Inc.
+ *
+ *   This file is part of the Lustre file system, http://www.lustre.org
+ *   Lustre is a trademark of Cluster File Systems, Inc.
+ *
+ *   You may have signed or agreed to another license before downloading
+ *   this software.  If so, you are bound by the terms and conditions
+ *   of that agreement, and the following does not apply to you.  See the
+ *   LICENSE file included with this distribution for more information.
+ *
+ *   If you did not agree to a different license, then this copy of Lustre
+ *   is open source software; you can redistribute it and/or modify it
+ *   under the terms of version 2 of the GNU General Public License as
+ *   published by the Free Software Foundation.
+ *
+ *   In either case, Lustre is distributed in the hope that it will be
+ *   useful, but WITHOUT ANY WARRANTY; without even the implied warranty
+ *   of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   license text for more details.
+ *
+ */
+#define DEBUG_SUBSYSTEM S_LQUOTA
+
+#include <linux/version.h>
+#include <lprocfs_status.h>
+#include <obd.h>
+#include <linux/seq_file.h>
+#include <lustre_fsfilt.h>
+
+#include "quota_internal.h"
+
+#ifdef LPROCFS
+int lprocfs_quota_rd_bunit(char *page, char **start, off_t off, int count,
+                           int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+        return snprintf(page, count, "%lu\n",
+                        obd->u.obt.obt_qctxt.lqc_bunit_sz);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_bunit);
+
+int lprocfs_quota_wr_bunit(struct file *file, const char *buffer,
+                           unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val % QUOTABLOCK_SIZE ||
+            val <= obd->u.obt.obt_qctxt.lqc_btune_sz)
+                return -EINVAL;
+
+        obd->u.obt.obt_qctxt.lqc_bunit_sz = val;
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_bunit);
+
+int lprocfs_quota_rd_btune(char *page, char **start, off_t off, int count,
+                           int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+        return snprintf(page, count, "%lu\n",
+                        obd->u.obt.obt_qctxt.lqc_btune_sz);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_btune);
+
+int lprocfs_quota_wr_btune(struct file *file, const char *buffer,
+                           unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val <= QUOTABLOCK_SIZE * MIN_QLIMIT || val % QUOTABLOCK_SIZE ||
+            val >= obd->u.obt.obt_qctxt.lqc_bunit_sz)
+                return -EINVAL;
+
+        obd->u.obt.obt_qctxt.lqc_btune_sz = val;
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_btune);
+
+int lprocfs_quota_rd_iunit(char *page, char **start, off_t off, int count,
+                           int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+        return snprintf(page, count, "%lu\n",
+                        obd->u.obt.obt_qctxt.lqc_iunit_sz);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_iunit);
+
+int lprocfs_quota_wr_iunit(struct file *file, const char *buffer,
+                           unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val <= obd->u.obt.obt_qctxt.lqc_itune_sz)
+                return -EINVAL;
+
+        obd->u.obt.obt_qctxt.lqc_iunit_sz = val;
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_iunit);
+
+int lprocfs_quota_rd_itune(char *page, char **start, off_t off, int count,
+                           int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+        return snprintf(page, count, "%lu\n",
+                        obd->u.obt.obt_qctxt.lqc_itune_sz);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_itune);
+
+int lprocfs_quota_wr_itune(struct file *file, const char *buffer,
+                           unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val <= MIN_QLIMIT ||
+            val >= obd->u.obt.obt_qctxt.lqc_iunit_sz)
+                return -EINVAL;
+
+        obd->u.obt.obt_qctxt.lqc_itune_sz = val;
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_itune);
+
+#define USER_QUOTA      1
+#define GROUP_QUOTA     2
+
+#define MAX_STYPE_SIZE  5
+
+/* The following information about CURRENT quotas is expected on the output:
+ * MDS: u for user quotas (administrative+operational) turned on,
+ *      g for group quotas (administrative+operational) turned on,
+ *      1 for 32-bit operational quotas and 32-bit administrative quotas,
+ *      2 for 32-bit operational quotas and 64-bit administrative quotas,
+ *      3 for 64-bit operational quotas and 64-bit administrative quotas
+ * OST: u for user quotas (operational) turned on,
+ *      g for group quotas (operational) turned on,
+ *      1 for 32-bit local operational quotas,
+ *      3 for 64-bit local operational quotas,
+ * Permanent parameters can be read with lctl (?)
+ */
+int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count,
+                          int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        char stype[MAX_STYPE_SIZE + 1] = "";
+        int oq_type, rc, is_mds;
+        lustre_quota_version_t aq_version, oq_version;
+        struct obd_device_target *obt;
+
+        LASSERT(obd != NULL);
+
+        obt = &obd->u.obt;
+        is_mds = !strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME);
+
+        /* Collect the needed information */
+        oq_type = obd->u.obt.obt_qctxt.lqc_flags;
+        oq_version = obt->obt_qfmt;
+        if (is_mds) {
+                rc = mds_quota_get_version(obd, &aq_version);
+                if (rc)
+                        return -EPROTO;
+                /* Here we can also assert that aq_type == oq_type
+                 * except for quota startup/shutdown states     */
+        }
+
+        /* Transform the collected data into a user-readable string */
+        if (oq_type & LQC_USRQUOTA_FLAG)
+                strcat(stype, "u");
+        if (oq_type & LQC_GRPQUOTA_FLAG)
+                strcat(stype, "g");
+
+        if ((!is_mds || aq_version == LUSTRE_QUOTA_V1) &&
+            oq_version == LUSTRE_QUOTA_V1)
+                strcat(stype, "1");
+#ifdef HAVE_QUOTA64
+        else if ((!is_mds || aq_version == LUSTRE_QUOTA_V2) &&
+                 oq_version == LUSTRE_QUOTA_V2)
+                strcat(stype, "3");
+#endif
+        else if (is_mds && aq_version == LUSTRE_QUOTA_V2 &&
+                 oq_version == LUSTRE_QUOTA_V1)
+                strcat(stype, "2");
+        else
+                return -EPROTO;
+
+        return snprintf(page, count, "%s\n", stype);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_type);
+
+static int auto_quota_on(struct obd_device *obd, int type,
+                         struct super_block *sb, int is_master)
+{
+        struct obd_quotactl *oqctl;
+        struct lvfs_run_ctxt saved;
+        int rc = 0, id;
+        struct obd_device_target *obt;
+        ENTRY;
+
+        LASSERT(type == USRQUOTA || type == GRPQUOTA || type == UGQUOTA);
+
+        obt = &obd->u.obt;
+
+        OBD_ALLOC_PTR(oqctl);
+        if (!oqctl)
+                RETURN(-ENOMEM);
+
+        if (!atomic_dec_and_test(&obt->obt_quotachecking)) {
+                CDEBUG(D_INFO, "other people are doing quotacheck\n");
+                atomic_inc(&obt->obt_quotachecking);
+                RETURN(-EBUSY);
+        }
+
+        id = UGQUOTA2LQC(type);
+        /* quota already turned on */
+        if ((obt->obt_qctxt.lqc_flags & id) == id) {
+                rc = 0;
+                goto out;
+        }
+
+        oqctl->qc_type = type;
+        oqctl->qc_cmd = Q_QUOTAON;
+        oqctl->qc_id = obt->obt_qfmt;
+
+        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+        if (is_master) {
+                struct mds_obd *mds = &obd->u.mds;
+
+                down(&mds->mds_qonoff_sem);
+                /* turn on cluster wide quota */
+                rc = mds_admin_quota_on(obd, oqctl);
+                if (rc)
+                        CDEBUG(rc == -ENOENT ? D_QUOTA : D_ERROR,
+                               "auto-enable admin quota failed. rc=%d\n", rc);
+                up(&mds->mds_qonoff_sem);
+
+        }
+        if (!rc) {
+                /* turn on local quota */
+                rc = fsfilt_quotactl(obd, sb, oqctl);
+                if (rc)
+                        CDEBUG(rc == -ENOENT ? D_QUOTA : D_ERROR,
+                               "auto-enable local quota failed. rc=%d\n", rc);
+                else
+                        obt->obt_qctxt.lqc_flags |= UGQUOTA2LQC(type);
+        }
+
+        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+
+out:
+        atomic_inc(&obt->obt_quotachecking);
+
+        OBD_FREE_PTR(oqctl);
+        RETURN(rc);
+}
+
+static int filter_quota_set_version(struct obd_device *obd,
+                                    lustre_quota_version_t version)
+{
+        struct obd_device_target *obt = &obd->u.obt;
+
+        if (version != LUSTRE_QUOTA_V1) {
+#ifdef HAVE_QUOTA64
+                if (version != LUSTRE_QUOTA_V2)
+#endif
+                        return -EINVAL;
+        }
+
+        if (!atomic_dec_and_test(&obt->obt_quotachecking)) {
+                CDEBUG(D_INFO, "other people are doing quotacheck\n");
+                atomic_inc(&obt->obt_quotachecking);
+                return -EBUSY;
+        }
+
+        if (obt->obt_qctxt.lqc_flags & (LQC_USRQUOTA_FLAG | LQC_GRPQUOTA_FLAG)) {
+                atomic_inc(&obt->obt_quotachecking);
+                return -EBUSY;
+        }
+
+        obt->obt_qfmt = version;
+
+        atomic_inc(&obt->obt_quotachecking);
+
+        return 0;
+}
+
+/* The following settings of CURRENT quotas is expected on the input:
+ * MDS: u for user quotas (administrative+operational) turned on,
+ *      g for group quotas (administrative+operational) turned on,
+ *      1 for 32-bit operational quotas and 32-bit administrative quotas,
+ *      2 for 32-bit operational quotas and 64-bit administrative quotas,
+ *      3 for 64-bit operational quotas and 64-bit administrative quotas
+ * OST: u for user quotas (operational) turned on,
+ *      g for group quotas (operational) turned on,
+ *      1 for 32-bit local operational quotas,
+ *      2 for 32-bit local operational quotas,
+ *      3 for 64-bit local operational quotas,
+ * Permanent parameters can be set with lctl/tunefs
+ */
+int lprocfs_quota_wr_type(struct file *file, const char *buffer,
+                          unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        struct obd_device_target *obt;
+        int type = 0, is_mds, idx;
+        unsigned long i;
+        char stype[MAX_STYPE_SIZE + 1] = "";
+        static const lustre_quota_version_t s2av[3] = {LUSTRE_QUOTA_V1,
+                                                       LUSTRE_QUOTA_V2,
+                                                       LUSTRE_QUOTA_V2},
+                                            s2ov[3] = {LUSTRE_QUOTA_V1,
+                                                       LUSTRE_QUOTA_V1,
+                                                       LUSTRE_QUOTA_V2};
+        LASSERT(obd != NULL);
+
+        obt = &obd->u.obt;
+
+        is_mds = !strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME);
+
+        if (count > MAX_STYPE_SIZE)
+                return -EINVAL;
+
+        if (copy_from_user(stype, buffer, count))
+                return -EFAULT;
+
+        for (i = 0 ; i < count ; i++) {
+                int rc;
+
+                switch (stype[i]) {
+                case 'u' :
+                        type |= USER_QUOTA;
+                        break;
+                case 'g' :
+                        type |= GROUP_QUOTA;
+                        break;
+                /* quota version specifiers */
+                case '1' :
+                case '2' :
+                case '3' :
+                        idx = stype[i] - '1';
+#ifndef HAVE_QUOTA64
+                        if (s2ov[idx] == LUSTRE_QUOTA_V2)
+                                return -EINVAL;
+#endif
+                        if (is_mds) {
+                                rc = mds_quota_set_version(obd, s2av[idx]);
+                                if (rc) {
+                                        CDEBUG(D_QUOTA, "failed to set admin "
+                                               "quota to spec %c! %d\n",
+                                               stype[i], rc);
+                                        return rc;
+                                }
+                        }
+                        rc = filter_quota_set_version(obd, s2ov[idx]);
+                        if (rc) {
+                                CDEBUG(D_QUOTA, "failed to set operational quota"
+                                       " to spec %c! %d\n", stype[i], rc);
+                                return rc;
+                        }
+                        break;
+                default  : /* just skip stray symbols like \n */
+                        break;
+                }
+        }
+
+        if (type != 0)
+                auto_quota_on(obd, type - 1, obt->obt_sb, is_mds);
+
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_type);
+
+int lprocfs_quota_rd_switch_seconds(char *page, char **start, off_t off,
+                                    int count, int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+        return snprintf(page, count, "%d\n",
+                        obd->u.obt.obt_qctxt.lqc_switch_seconds);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_switch_seconds);
+
+int lprocfs_quota_wr_switch_seconds(struct file *file, const char *buffer,
+                                    unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val <= 10)
+                return -EINVAL;
+
+        obd->u.obt.obt_qctxt.lqc_switch_seconds = val;
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_switch_seconds);
+
+int lprocfs_quota_rd_switch_qs(char *page, char **start, off_t off,
+                               int count, int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+        return snprintf(page, count, "changing qunit size is %s\n",
+                        obd->u.obt.obt_qctxt.lqc_switch_qs ?
+                        "enabled" : "disabled");
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_switch_qs);
+
+int lprocfs_quota_wr_switch_qs(struct file *file, const char *buffer,
+                               unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val)
+            obd->u.obt.obt_qctxt.lqc_switch_qs = 1;
+        else
+            obd->u.obt.obt_qctxt.lqc_switch_qs = 0;
+
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_switch_qs);
+
+int lprocfs_quota_rd_boundary_factor(char *page, char **start, off_t off,
+                                     int count, int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+
+        return snprintf(page, count, "%lu\n",
+                        obd->u.obt.obt_qctxt.lqc_cqs_boundary_factor);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_boundary_factor);
+
+int lprocfs_quota_wr_boundary_factor(struct file *file, const char *buffer,
+                                     unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val < 2)
+                return -EINVAL;
+
+        obd->u.obt.obt_qctxt.lqc_cqs_boundary_factor = val;
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_boundary_factor);
+
+int lprocfs_quota_rd_least_bunit(char *page, char **start, off_t off,
+                                 int count, int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+
+        return snprintf(page, count, "%lu\n",
+                        obd->u.obt.obt_qctxt.lqc_cqs_least_bunit);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_least_bunit);
+
+int lprocfs_quota_wr_least_bunit(struct file *file, const char *buffer,
+                                 unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val < PTLRPC_MAX_BRW_SIZE ||
+            val >= obd->u.obt.obt_qctxt.lqc_bunit_sz)
+                return -EINVAL;
+
+        obd->u.obt.obt_qctxt.lqc_cqs_least_bunit = val;
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_least_bunit);
+
+int lprocfs_quota_rd_least_iunit(char *page, char **start, off_t off,
+                                 int count, int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+
+        return snprintf(page, count, "%lu\n",
+                        obd->u.obt.obt_qctxt.lqc_cqs_least_iunit);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_least_iunit);
+
+int lprocfs_quota_wr_least_iunit(struct file *file, const char *buffer,
+                                 unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val < 1 || val >= obd->u.obt.obt_qctxt.lqc_iunit_sz)
+                return -EINVAL;
+
+        obd->u.obt.obt_qctxt.lqc_cqs_least_iunit = val;
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_least_iunit);
+
+int lprocfs_quota_rd_qs_factor(char *page, char **start, off_t off,
+                               int count, int *eof, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        LASSERT(obd != NULL);
+
+
+        return snprintf(page, count, "%lu\n",
+                        obd->u.obt.obt_qctxt.lqc_cqs_qs_factor);
+}
+EXPORT_SYMBOL(lprocfs_quota_rd_qs_factor);
+
+int lprocfs_quota_wr_qs_factor(struct file *file, const char *buffer,
+                               unsigned long count, void *data)
+{
+        struct obd_device *obd = (struct obd_device *)data;
+        int val, rc;
+        LASSERT(obd != NULL);
+
+        rc = lprocfs_write_helper(buffer, count, &val);
+        if (rc)
+                return rc;
+
+        if (val < 2)
+                return -EINVAL;
+
+        obd->u.obt.obt_qctxt.lqc_cqs_qs_factor = val;
+        return count;
+}
+EXPORT_SYMBOL(lprocfs_quota_wr_qs_factor);
+
+struct lprocfs_vars lprocfs_quota_common_vars[] = {
+        { "quota_bunit_sz", lprocfs_quota_rd_bunit,
+                            lprocfs_quota_wr_bunit, 0},
+        { "quota_btune_sz", lprocfs_quota_rd_btune,
+                            lprocfs_quota_wr_btune, 0},
+        { "quota_iunit_sz", lprocfs_quota_rd_iunit,
+                            lprocfs_quota_wr_iunit, 0},
+        { "quota_itune_sz", lprocfs_quota_rd_itune,
+                            lprocfs_quota_wr_itune, 0},
+        { "quota_type",     lprocfs_quota_rd_type,
+                            lprocfs_quota_wr_type, 0},
+        { "quota_switch_seconds",  lprocfs_quota_rd_switch_seconds,
+                                   lprocfs_quota_wr_switch_seconds, 0 },
+};
+
+struct lprocfs_vars lprocfs_quota_master_vars[] = {
+        { "quota_switch_qs", lprocfs_quota_rd_switch_qs,
+                             lprocfs_quota_wr_switch_qs, 0 },
+        { "quota_boundary_factor", lprocfs_quota_rd_boundary_factor,
+                                   lprocfs_quota_wr_boundary_factor, 0 },
+        { "quota_least_bunit", lprocfs_quota_rd_least_bunit,
+                               lprocfs_quota_wr_least_bunit, 0 },
+        { "quota_least_iunit", lprocfs_quota_rd_least_iunit,
+                               lprocfs_quota_wr_least_iunit, 0 },
+        { "quota_qs_factor",   lprocfs_quota_rd_qs_factor,
+                               lprocfs_quota_wr_qs_factor, 0 },
+};
+
+int lquota_proc_setup(struct obd_device *obd, int is_master)
+{
+        struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
+        int rc = 0;
+        ENTRY;
+
+        LASSERT(lquota_type_proc_dir && obd);
+        qctxt->lqc_proc_dir = lprocfs_register(obd->obd_name,
+                                               lquota_type_proc_dir,
+                                               lprocfs_quota_common_vars, obd);
+        if (IS_ERR(qctxt->lqc_proc_dir)) {
+                rc = PTR_ERR(qctxt->lqc_proc_dir);
+                CERROR("error %d setting up lprocfs for %s\n", rc,
+                       obd->obd_name);
+                qctxt->lqc_proc_dir = NULL;
+                GOTO(out, rc);
+        }
+
+        if (is_master) {
+                rc = lprocfs_add_vars(qctxt->lqc_proc_dir,
+                                      lprocfs_quota_master_vars, obd);
+                if (rc) {
+                        CERROR("error %d setting up lprocfs for %s"
+                               "(quota master)\n", rc, obd->obd_name);
+                        GOTO(out_free_proc, rc);
+                }
+        }
+
+        qctxt->lqc_stats = lprocfs_alloc_stats(LQUOTA_LAST_STAT -
+                                               LQUOTA_FIRST_STAT, 0);
+        if (!qctxt->lqc_stats)
+                GOTO(out_free_proc, rc = -ENOMEM);
+
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_SYNC_ACQ,
+                             LPROCFS_CNTR_AVGMINMAX, "sync_acq_req", "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_SYNC_REL,
+                             LPROCFS_CNTR_AVGMINMAX, "sync_rel_req", "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_ASYNC_ACQ,
+                             LPROCFS_CNTR_AVGMINMAX, "async_acq_req", "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_ASYNC_REL,
+                             LPROCFS_CNTR_AVGMINMAX, "async_rel_req", "us");
+
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_CHK_BLK,
+                             LPROCFS_CNTR_AVGMINMAX,
+                             "wait_for_blk_quota(lquota_chkquota)", "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_CHK_INO,
+                             LPROCFS_CNTR_AVGMINMAX,
+                             "wait_for_ino_quota(lquota_chkquota)", "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_COMMIT_BLK,
+                             LPROCFS_CNTR_AVGMINMAX,
+                             "wait_for_blk_quota(lquota_pending_commit)",
+                             "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_FOR_COMMIT_INO,
+                             LPROCFS_CNTR_AVGMINMAX,
+                             "wait_for_ino_quota(lquota_pending_commit)",
+                             "us");
+
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_PENDING_BLK_QUOTA,
+                             LPROCFS_CNTR_AVGMINMAX,
+                             "wait_for_pending_blk_quota_req"
+                             "(qctxt_wait_pending_dqacq)", "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_WAIT_PENDING_INO_QUOTA,
+                             LPROCFS_CNTR_AVGMINMAX,
+                             "wait_for_pending_ino_quota_req"
+                             "(qctxt_wait_pending_dqacq)", "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_NOWAIT_PENDING_BLK_QUOTA,
+                             LPROCFS_CNTR_AVGMINMAX,
+                             "nowait_for_pending_blk_quota_req"
+                             "(qctxt_wait_pending_dqacq)", "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_NOWAIT_PENDING_INO_QUOTA,
+                             LPROCFS_CNTR_AVGMINMAX,
+                             "nowait_for_pending_ino_quota_req"
+                             "(qctxt_wait_pending_dqacq)", "us");
+
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_QUOTA_CTL,
+                             LPROCFS_CNTR_AVGMINMAX, "quota_ctl", "us");
+        lprocfs_counter_init(qctxt->lqc_stats, LQUOTA_ADJUST_QUNIT,
+                             LPROCFS_CNTR_AVGMINMAX, "adjust_qunit", "us");
+
+        lprocfs_register_stats(qctxt->lqc_proc_dir, "stats", qctxt->lqc_stats);
+
+        RETURN(rc);
+
+out_free_proc:
+        lprocfs_remove(&qctxt->lqc_proc_dir);
+out:
+        RETURN(rc);
+}
+
+int lquota_proc_cleanup(struct lustre_quota_ctxt *qctxt)
+{
+        if (!qctxt || !qctxt->lqc_proc_dir)
+                return -EINVAL;
+        lprocfs_remove(&qctxt->lqc_proc_dir);
+        return 0;
+}
+
+#endif  /* LPROCFS */
diff --git a/lustre/quota/quota_adjust_qunit.c b/lustre/quota/quota_adjust_qunit.c
index 8344fa8bda95f83884ac70b8943b90fc29236956..a894bc1d55d1bae9631ffdb63d1384ceaeb66dc1 100644
--- a/lustre/quota/quota_adjust_qunit.c
+++ b/lustre/quota/quota_adjust_qunit.c
@@ -36,7 +36,7 @@
 #ifndef EXPORT_SYMTAB
 # define EXPORT_SYMTAB
 #endif
-#define DEBUG_SUBSYSTEM S_MDS
+#define DEBUG_SUBSYSTEM S_LQUOTA
 
 #ifdef __KERNEL__
 # include <linux/version.h>
@@ -321,10 +321,10 @@ search_lqs:
 }
 
 int filter_quota_adjust_qunit(struct obd_export *exp,
-                              struct quota_adjust_qunit *oqaq)
+                              struct quota_adjust_qunit *oqaq,
+                              struct lustre_quota_ctxt *qctxt)
 {
         struct obd_device *obd = exp->exp_obd;
-        struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         unsigned int uid = 0, gid = 0;
         int rc = 0;
         ENTRY;
@@ -355,7 +355,8 @@ int filter_quota_adjust_qunit(struct obd_export *exp,
 #endif /* __KERNEL__ */
 
 int client_quota_adjust_qunit(struct obd_export *exp,
-                              struct quota_adjust_qunit *oqaq)
+                              struct quota_adjust_qunit *oqaq,
+                              struct lustre_quota_ctxt *qctxt)
 {
         struct ptlrpc_request *req;
         struct quota_adjust_qunit *oqa;
@@ -395,7 +396,8 @@ out:
 }
 
 int lov_quota_adjust_qunit(struct obd_export *exp,
-                           struct quota_adjust_qunit *oqaq)
+                           struct quota_adjust_qunit *oqaq,
+                           struct lustre_quota_ctxt *qctxt)
 {
         struct obd_device *obd = class_exp2obd(exp);
         struct lov_obd *lov = &obd->u.lov;
@@ -415,7 +417,8 @@ int lov_quota_adjust_qunit(struct obd_export *exp,
                         continue;
                 }
 
-                err = obd_quota_adjust_qunit(lov->lov_tgts[i]->ltd_exp, oqaq);
+                err = obd_quota_adjust_qunit(lov->lov_tgts[i]->ltd_exp, oqaq,
+                                             NULL);
                 if (err) {
                         if (lov->lov_tgts[i]->ltd_active && !rc)
                                 rc = err;
diff --git a/lustre/quota/quota_check.c b/lustre/quota/quota_check.c
index 2789c011dc5bcd7a0f847d9c34b55faace844886..b91bee7ebab89959eadcab1b4d0f2d1b2e2e37cb 100644
--- a/lustre/quota/quota_check.c
+++ b/lustre/quota/quota_check.c
@@ -36,7 +36,7 @@
 #ifndef EXPORT_SYMTAB
 # define EXPORT_SYMTAB
 #endif
-#define DEBUG_SUBSYSTEM S_MDS
+#define DEBUG_SUBSYSTEM S_LQUOTA
 
 #ifdef __KERNEL__
 # include <linux/version.h>
diff --git a/lustre/quota/quota_context.c b/lustre/quota/quota_context.c
index 9fbf63126c4c2321a6690d14d7dc9d31dc1b6353..c1300a23bd0fa4a50237f34abc657134a491f08a 100644
--- a/lustre/quota/quota_context.c
+++ b/lustre/quota/quota_context.c
@@ -44,7 +44,7 @@
 # define EXPORT_SYMTAB
 #endif
 
-#define DEBUG_SUBSYSTEM S_MDS
+#define DEBUG_SUBSYSTEM S_LQUOTA
 
 #include <linux/version.h>
 #include <linux/fs.h>
@@ -58,6 +58,7 @@
 #include <lustre_quota.h>
 #include <lustre_fsfilt.h>
 #include <class_hash.h>
+#include <lprocfs_status.h>
 #include "quota_internal.h"
 
 extern struct lustre_hash_operations lqs_hash_operations;
@@ -508,9 +509,14 @@ static int split_before_schedule_dqacq(struct obd_device *obd,
         int rc = 0;
         unsigned long factor;
         struct qunit_data tmp_qdata;
+        struct timeval    work_start;
+        struct timeval    work_end;
+        long              timediff;
         ENTRY;
 
         LASSERT(qdata && qdata->qd_count);
+        LASSERT(opc == QUOTA_DQACQ || opc == QUOTA_DQREL);
+        do_gettimeofday(&work_start);
         QDATA_DEBUG(qdata, "%s quota split.\n",
                     QDATA_IS_BLK(qdata) ? "block" : "inode");
         if (QDATA_IS_BLK(qdata))
@@ -531,6 +537,16 @@ static int split_before_schedule_dqacq(struct obd_device *obd,
                 QDATA_DEBUG(qdata, "don't be split.\n");
                 rc = schedule_dqacq(obd, qctxt, qdata, opc, wait);
         }
+        do_gettimeofday(&work_end);
+        timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
+        if (opc == QUOTA_DQACQ)
+                lprocfs_counter_add(qctxt->lqc_stats,
+                                    wait ? LQUOTA_SYNC_ACQ : LQUOTA_ASYNC_ACQ,
+                                    timediff);
+        else
+                lprocfs_counter_add(qctxt->lqc_stats,
+                                    wait ? LQUOTA_SYNC_REL : LQUOTA_ASYNC_REL,
+                                    timediff);
 
         RETURN(rc);
 }
@@ -976,9 +992,13 @@ qctxt_wait_pending_dqacq(struct lustre_quota_ctxt *qctxt, unsigned int id,
 {
         struct lustre_qunit *qunit = NULL;
         struct qunit_data qdata;
+        struct timeval work_start;
+        struct timeval work_end;
+        long timediff;
         struct l_wait_info lwi = { 0 };
         ENTRY;
 
+        do_gettimeofday(&work_start);
         qdata.qd_id = id;
         qdata.qd_flags = type;
         if (isblk)
@@ -1002,14 +1022,29 @@ qctxt_wait_pending_dqacq(struct lustre_quota_ctxt *qctxt, unsigned int id,
                 CDEBUG(D_QUOTA, "qunit(%p) finishes waiting. (rc:%d)\n",
                        qunit, qunit->lq_rc);
                 qunit_put(qunit);
+                do_gettimeofday(&work_end);
+                timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
+                lprocfs_counter_add(qctxt->lqc_stats,
+                                    isblk ? LQUOTA_WAIT_PENDING_BLK_QUOTA :
+                                            LQUOTA_WAIT_PENDING_INO_QUOTA,
+                                    timediff);
+        } else {
+                do_gettimeofday(&work_end);
+                timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
+                lprocfs_counter_add(qctxt->lqc_stats,
+                                    isblk ? LQUOTA_NOWAIT_PENDING_BLK_QUOTA :
+                                            LQUOTA_NOWAIT_PENDING_INO_QUOTA,
+                                    timediff);
         }
+
         RETURN(0);
 }
 
 int
-qctxt_init(struct lustre_quota_ctxt *qctxt, struct super_block *sb,
-           dqacq_handler_t handler)
+qctxt_init(struct obd_device *obd, dqacq_handler_t handler)
 {
+        struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
+        struct super_block *sb = obd->u.obt.obt_sb;
         int rc = 0;
         ENTRY;
 
@@ -1040,11 +1075,17 @@ qctxt_init(struct lustre_quota_ctxt *qctxt, struct super_block *sb,
         rc = lustre_hash_init(&LQC_HASH_BODY(qctxt), "LQS_HASH",128,
                               &lqs_hash_operations);
         if (rc) {
-                CDEBUG(D_ERROR, "initialize hash lqs on ost error!\n");
+                CDEBUG(D_ERROR, "initialize hash lqs for %s error!\n",
+                       obd->obd_name);
                 lustre_hash_exit(&LQC_HASH_BODY(qctxt));
         }
         spin_unlock(&qctxt->lqc_lock);
 
+#ifdef LPROCFS
+        if (lquota_proc_setup(obd, is_master(obd, qctxt, 0, 0)))
+                CERROR("initialize proc for %s error!\n", obd->obd_name);
+#endif
+
         RETURN(rc);
 }
 
@@ -1081,6 +1122,11 @@ void qctxt_cleanup(struct lustre_quota_ctxt *qctxt, int force)
         lustre_hash_exit(&LQC_HASH_BODY(qctxt));
         ptlrpcd_decref();
 
+#ifdef LPROCFS
+        if (lquota_proc_cleanup(qctxt))
+                CERROR("cleanup proc error!\n");
+#endif
+
         EXIT;
 }
 
diff --git a/lustre/quota/quota_ctl.c b/lustre/quota/quota_ctl.c
index 31e5a49e59a675adab412506a007b052dda823d0..327287e2d31ce822771615aa8e7158db073db251 100644
--- a/lustre/quota/quota_ctl.c
+++ b/lustre/quota/quota_ctl.c
@@ -36,7 +36,7 @@
 #ifndef EXPORT_SYMTAB
 # define EXPORT_SYMTAB
 #endif
-#define DEBUG_SUBSYSTEM S_MDS
+#define DEBUG_SUBSYSTEM S_LQUOTA
 
 #ifdef __KERNEL__
 # include <linux/version.h>
@@ -71,9 +71,14 @@
 int mds_quota_ctl(struct obd_export *exp, struct obd_quotactl *oqctl)
 {
         struct obd_device *obd = exp->exp_obd;
+        struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
+        struct timeval work_start;
+        struct timeval work_end;
+        long timediff;
         int rc = 0;
         ENTRY;
 
+        do_gettimeofday(&work_start);
         switch (oqctl->qc_cmd) {
         case Q_QUOTAON:
                 rc = mds_quota_on(obd, oqctl);
@@ -113,6 +118,9 @@ int mds_quota_ctl(struct obd_export *exp, struct obd_quotactl *oqctl)
                 CDEBUG(D_INFO, "mds_quotactl admin quota command %d, id %u, "
                                "type %d, failed: rc = %d\n",
                        oqctl->qc_cmd, oqctl->qc_id, oqctl->qc_type, rc);
+        do_gettimeofday(&work_end);
+        timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
+        lprocfs_counter_add(qctxt->lqc_stats, LQUOTA_QUOTA_CTL, timediff);
 
         RETURN(rc);
 }
@@ -122,9 +130,14 @@ int filter_quota_ctl(struct obd_export *exp, struct obd_quotactl *oqctl)
         struct obd_device *obd = exp->exp_obd;
         struct obd_device_target *obt = &obd->u.obt;
         struct lvfs_run_ctxt saved;
+        struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
+        struct timeval work_start;
+        struct timeval work_end;
+        long timediff;
         int rc = 0;
         ENTRY;
 
+        do_gettimeofday(&work_start);
         switch (oqctl->qc_cmd) {
         case Q_FINVALIDATE:
         case Q_QUOTAON:
@@ -234,6 +247,9 @@ adjust:
                        obd->obd_name, oqctl->qc_cmd);
                 RETURN(-EFAULT);
         }
+        do_gettimeofday(&work_end);
+        timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
+        lprocfs_counter_add(qctxt->lqc_stats, LQUOTA_QUOTA_CTL, timediff);
 
         RETURN(rc);
 }
diff --git a/lustre/quota/quota_interface.c b/lustre/quota/quota_interface.c
index e5b9f8134b2afd63cbe6ea1e710fcd72df9a4b55..eeee79e0c743a5f1c68f61adad6fe3cdfc5da1b8 100644
--- a/lustre/quota/quota_interface.c
+++ b/lustre/quota/quota_interface.c
@@ -37,7 +37,7 @@
 #ifndef EXPORT_SYMTAB
 # define EXPORT_SYMTAB
 #endif
-#define DEBUG_SUBSYSTEM S_MDS
+#define DEBUG_SUBSYSTEM S_LQUOTA
 
 #ifdef __KERNEL__
 # include <linux/version.h>
@@ -69,260 +69,6 @@
 #include "quota_internal.h"
 
 #ifdef __KERNEL__
-
-/* quota proc file handling functions */
-#ifdef LPROCFS
-
-#define USER_QUOTA      1
-#define GROUP_QUOTA     2
-
-#define MAX_STYPE_SIZE  5
-
-/* The following information about CURRENT quotas is expected on the output:
- * MDS: u for user quotas (administrative+operational) turned on,
- *      g for group quotas (administrative+operational) turned on,
- *      1 for 32-bit operational quotas and 32-bit administrative quotas,
- *      2 for 32-bit operational quotas and 64-bit administrative quotas,
- *      3 for 64-bit operational quotas and 64-bit administrative quotas
- * OST: u for user quotas (operational) turned on,
- *      g for group quotas (operational) turned on,
- *      1 for 32-bit local operational quotas,
- *      3 for 64-bit local operational quotas,
- * Permanent parameters can be read with lctl (?)
- */
-int lprocfs_quota_rd_type(char *page, char **start, off_t off, int count,
-                          int *eof, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        char stype[MAX_STYPE_SIZE + 1] = "";
-        int oq_type, rc, is_mds;
-        lustre_quota_version_t aq_version, oq_version;
-        struct obd_device_target *obt;
-
-        LASSERT(obd != NULL);
-
-        obt = &obd->u.obt;
-        is_mds = !strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME);
-
-        /* Collect the needed information */
-        oq_type = obd->u.obt.obt_qctxt.lqc_flags;
-        oq_version = obt->obt_qfmt;
-        if (is_mds) {
-                rc = mds_quota_get_version(obd, &aq_version);
-                if (rc)
-                        return -EPROTO;
-                /* Here we can also assert that aq_type == oq_type
-                 * except for quota startup/shutdown states     */
-        }
-
-        /* Transform the collected data into a user-readable string */
-        if (oq_type & LQC_USRQUOTA_FLAG)
-                strcat(stype, "u");
-        if (oq_type & LQC_GRPQUOTA_FLAG)
-                strcat(stype, "g");
-
-        if ((!is_mds || aq_version == LUSTRE_QUOTA_V1) &&
-            oq_version == LUSTRE_QUOTA_V1)
-                strcat(stype, "1");
-#ifdef HAVE_QUOTA64
-        else if ((!is_mds || aq_version == LUSTRE_QUOTA_V2) &&
-                 oq_version == LUSTRE_QUOTA_V2)
-                strcat(stype, "3");
-#endif
-        else if (is_mds && aq_version == LUSTRE_QUOTA_V2 &&
-                 oq_version == LUSTRE_QUOTA_V1)
-                strcat(stype, "2");
-        else
-                return -EPROTO;
-
-        return snprintf(page, count, "%s\n", stype);
-}
-EXPORT_SYMBOL(lprocfs_quota_rd_type);
-
-static int auto_quota_on(struct obd_device *obd, int type,
-                         struct super_block *sb, int is_master)
-{
-        struct obd_quotactl *oqctl;
-        struct lvfs_run_ctxt saved;
-        int rc = 0, id;
-        struct obd_device_target *obt;
-        ENTRY;
-
-        LASSERT(type == USRQUOTA || type == GRPQUOTA || type == UGQUOTA);
-
-        obt = &obd->u.obt;
-
-        OBD_ALLOC_PTR(oqctl);
-        if (!oqctl)
-                RETURN(-ENOMEM);
-
-        if (!atomic_dec_and_test(&obt->obt_quotachecking)) {
-                CDEBUG(D_INFO, "other people are doing quotacheck\n");
-                atomic_inc(&obt->obt_quotachecking);
-                RETURN(-EBUSY);
-        }
-
-        id = UGQUOTA2LQC(type);
-        /* quota already turned on */
-        if ((obt->obt_qctxt.lqc_flags & id) == id) {
-                rc = 0;
-                goto out;
-        }
-
-        oqctl->qc_type = type;
-        oqctl->qc_cmd = Q_QUOTAON;
-        oqctl->qc_id = obt->obt_qfmt;
-
-        push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-        if (is_master) {
-                struct mds_obd *mds = &obd->u.mds;
-
-                down(&mds->mds_qonoff_sem);
-                /* turn on cluster wide quota */
-                rc = mds_admin_quota_on(obd, oqctl);
-                if (rc)
-                        CDEBUG(rc == -ENOENT ? D_QUOTA : D_ERROR,
-                               "auto-enable admin quota failed. rc=%d\n", rc);
-                up(&mds->mds_qonoff_sem);
-
-        }
-        if (!rc) {
-                /* turn on local quota */
-                rc = fsfilt_quotactl(obd, sb, oqctl);
-                if (rc)
-                        CDEBUG(rc == -ENOENT ? D_QUOTA : D_ERROR,
-                               "auto-enable local quota failed. rc=%d\n", rc);
-                else
-                        obt->obt_qctxt.lqc_flags |= UGQUOTA2LQC(type);
-        }
-
-        pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
-
-out:
-        atomic_inc(&obt->obt_quotachecking);
-
-        OBD_FREE_PTR(oqctl);
-        RETURN(rc);
-}
-
-static int filter_quota_set_version(struct obd_device *obd, 
-                                    lustre_quota_version_t version)
-{
-        struct obd_device_target *obt = &obd->u.obt;
-
-        if (version != LUSTRE_QUOTA_V1) {
-#ifdef HAVE_QUOTA64
-                if (version != LUSTRE_QUOTA_V2)
-#endif
-                        return -EINVAL;
-        }
-
-        if (!atomic_dec_and_test(&obt->obt_quotachecking)) {
-                CDEBUG(D_INFO, "other people are doing quotacheck\n");
-                atomic_inc(&obt->obt_quotachecking);
-                return -EBUSY;
-        }
-
-        if (obt->obt_qctxt.lqc_flags & (LQC_USRQUOTA_FLAG | LQC_GRPQUOTA_FLAG)) {
-                atomic_inc(&obt->obt_quotachecking);
-                return -EBUSY;
-        }
-
-        obt->obt_qfmt = version;
-
-        atomic_inc(&obt->obt_quotachecking);
-
-        return 0;
-}
-
-/* The following settings of CURRENT quotas is expected on the input:
- * MDS: u for user quotas (administrative+operational) turned on,
- *      g for group quotas (administrative+operational) turned on,
- *      1 for 32-bit operational quotas and 32-bit administrative quotas,
- *      2 for 32-bit operational quotas and 64-bit administrative quotas,
- *      3 for 64-bit operational quotas and 64-bit administrative quotas
- * OST: u for user quotas (operational) turned on,
- *      g for group quotas (operational) turned on,
- *      1 for 32-bit local operational quotas,
- *      2 for 32-bit local operational quotas,
- *      3 for 64-bit local operational quotas,
- * Permanent parameters can be set with lctl/tunefs
- */
-int lprocfs_quota_wr_type(struct file *file, const char *buffer,
-                          unsigned long count, void *data)
-{
-        struct obd_device *obd = (struct obd_device *)data;
-        struct obd_device_target *obt;
-        int type = 0, is_mds, idx;
-        unsigned long i;
-        char stype[MAX_STYPE_SIZE + 1] = "";
-        static const lustre_quota_version_t s2av[3] = {LUSTRE_QUOTA_V1,
-                                                       LUSTRE_QUOTA_V2,
-                                                       LUSTRE_QUOTA_V2},
-                                            s2ov[3] = {LUSTRE_QUOTA_V1,
-                                                       LUSTRE_QUOTA_V1,
-                                                       LUSTRE_QUOTA_V2};
-        LASSERT(obd != NULL);
-
-        obt = &obd->u.obt;
-
-        is_mds = !strcmp(obd->obd_type->typ_name, LUSTRE_MDS_NAME);
-
-        if (count > MAX_STYPE_SIZE)
-                return -EINVAL;
-
-        if (copy_from_user(stype, buffer, count))
-                return -EFAULT;
-
-        for (i = 0 ; i < count ; i++) {
-                int rc;
-
-                switch (stype[i]) {
-                case 'u' :
-                        type |= USER_QUOTA;
-                        break;
-                case 'g' :
-                        type |= GROUP_QUOTA;
-                        break;
-                /* quota version specifiers */
-                case '1' :
-                case '2' :
-                case '3' :
-                        idx = stype[i] - '1';
-#ifndef HAVE_QUOTA64
-                        if (s2ov[idx] == LUSTRE_QUOTA_V2)
-                                return -EINVAL;
-#endif
-                        if (is_mds) {
-                                rc = mds_quota_set_version(obd, s2av[idx]);
-                                if (rc) {
-                                        CDEBUG(D_QUOTA, "failed to set admin "
-                                               "quota to spec %c! %d\n",
-                                               stype[i], rc);
-                                        return rc;
-                                }
-                        }
-                        rc = filter_quota_set_version(obd, s2ov[idx]);
-                        if (rc) {
-                                CDEBUG(D_QUOTA, "failed to set operational quota"
-                                       " to spec %c! %d\n", stype[i], rc);
-                                return rc;
-                        }
-                        break;
-                default  : /* just skip stray symbols like \n */
-                        break;
-                }
-        }
-
-        if (type != 0)
-                auto_quota_on(obd, type - 1, obt->obt_sb, is_mds);
-
-        return count;
-}
-EXPORT_SYMBOL(lprocfs_quota_wr_type);
-
-#endif /* LPROCFS */
-
 static int filter_quota_setup(struct obd_device *obd)
 {
         int rc = 0;
@@ -335,7 +81,7 @@ static int filter_quota_setup(struct obd_device *obd)
         obt->obt_qfmt = LUSTRE_QUOTA_V1;
 #endif
         atomic_set(&obt->obt_quotachecking, 1);
-        rc = qctxt_init(&obt->obt_qctxt, obt->obt_sb, NULL);
+        rc = qctxt_init(obd, NULL);
         if (rc)
                 CERROR("initialize quota context failed! (rc:%d)\n", rc);
 
@@ -537,6 +283,10 @@ static int quota_chk_acq_common(struct obd_device *obd, unsigned int uid,
                                 unsigned int gid, int count, int *pending,
                                 int isblk, quota_acquire acquire)
 {
+        struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
+        struct timeval work_start;
+        struct timeval work_end;
+        long timediff;
         int rc = 0, cycle = 0, count_err = 0;
         ENTRY;
 
@@ -544,6 +294,7 @@ static int quota_chk_acq_common(struct obd_device *obd, unsigned int uid,
          * pre-dqacq in time and quota hash on ost is used up, we
          * have to wait for the completion of in flight dqacq/dqrel,
          * in order to get enough quota for write b=12588 */
+        do_gettimeofday(&work_start);
         while ((rc = quota_check_common(obd, uid, gid, count, cycle, isblk)) &
                QUOTA_RET_ACQUOTA) {
 
@@ -591,10 +342,16 @@ static int quota_chk_acq_common(struct obd_device *obd, unsigned int uid,
         if (!cycle && rc & QUOTA_RET_INC_PENDING)
                 *pending = 1;
 
+        do_gettimeofday(&work_end);
+        timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
+        lprocfs_counter_add(qctxt->lqc_stats,
+                            isblk ? LQUOTA_WAIT_FOR_CHK_BLK :
+                                    LQUOTA_WAIT_FOR_CHK_INO,
+                            timediff);
+
         RETURN(rc);
 }
 
-
 static int filter_quota_check(struct obd_device *obd, unsigned int uid,
                               unsigned int gid, int npage, int *flag,
                               quota_acquire acquire)
@@ -609,6 +366,9 @@ static int quota_pending_commit(struct obd_device *obd, unsigned int uid,
                                 unsigned int gid, int count, int isblk)
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
+        struct timeval work_start;
+        struct timeval work_end;
+        long timediff;
         int i;
         __u32 id[MAXQUOTAS] = { uid, gid };
         struct qunit_data qdata[MAXQUOTAS];
@@ -618,6 +378,7 @@ static int quota_pending_commit(struct obd_device *obd, unsigned int uid,
         if (!sb_any_quota_enabled(qctxt->lqc_sb))
                 RETURN(0);
 
+        do_gettimeofday(&work_start);
         for (i = 0; i < MAXQUOTAS; i++) {
                 struct lustre_qunit_size *lqs = NULL;
 
@@ -664,6 +425,12 @@ static int quota_pending_commit(struct obd_device *obd, unsigned int uid,
                                 lqs_putref(lqs);
                 }
         }
+        do_gettimeofday(&work_end);
+        timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
+        lprocfs_counter_add(qctxt->lqc_stats,
+                            isblk ? LQUOTA_WAIT_FOR_COMMIT_BLK :
+                                    LQUOTA_WAIT_FOR_COMMIT_INO,
+                            timediff);
 
         RETURN(0);
 }
@@ -701,7 +468,7 @@ static int mds_quota_setup(struct obd_device *obd)
         atomic_set(&obt->obt_quotachecking, 1);
         /* initialize quota master and quota context */
         sema_init(&mds->mds_qonoff_sem, 1);
-        rc = qctxt_init(&obt->obt_qctxt, obt->obt_sb, dqacq_handler);
+        rc = qctxt_init(obd, dqacq_handler);
         if (rc) {
                 CERROR("initialize quota context failed! (rc:%d)\n", rc);
                 RETURN(rc);
@@ -1021,9 +788,23 @@ quota_interface_t lov_quota_interface = {
 };
 
 #ifdef __KERNEL__
+
+cfs_proc_dir_entry_t *lquota_type_proc_dir = NULL;
+
 static int __init init_lustre_quota(void)
 {
-        int rc = qunit_cache_init();
+        int rc = 0;
+
+        lquota_type_proc_dir = lprocfs_register(OBD_LQUOTA_DEVICENAME,
+                                                proc_lustre_root,
+                                                NULL, NULL);
+        if (IS_ERR(lquota_type_proc_dir)) {
+                CERROR("LProcFS failed in lquota-init\n");
+                rc = PTR_ERR(lquota_type_proc_dir);
+                return rc;
+        }
+
+        rc = qunit_cache_init();
         if (rc)
                 return rc;
         PORTAL_SYMBOL_REGISTER(filter_quota_interface);
@@ -1043,6 +824,9 @@ static void /*__exit*/ exit_lustre_quota(void)
         PORTAL_SYMBOL_UNREGISTER(lov_quota_interface);
 
         qunit_cache_cleanup();
+
+        if (lquota_type_proc_dir)
+                lprocfs_remove(&lquota_type_proc_dir);
 }
 
 MODULE_AUTHOR("Sun Microsystems, Inc. <http://www.lustre.org/>");
diff --git a/lustre/quota/quota_internal.h b/lustre/quota/quota_internal.h
index c2250a212632e284aca28e56dd683285ae7e2c8b..03e6af13a8cca720c8571018a3db794f1fd813cc 100644
--- a/lustre/quota/quota_internal.h
+++ b/lustre/quota/quota_internal.h
@@ -45,6 +45,7 @@
 /* This flag is set in qc_stat to distinguish if the current getquota
  * operation is for quota recovery */
 #define QUOTA_RECOVERING    0x01
+#define OBD_LQUOTA_DEVICENAME  "lquota"
 
 #ifdef __KERNEL__
 
@@ -101,8 +102,7 @@ int qctxt_adjust_qunit(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
                        uid_t uid, gid_t gid, __u32 isblk, int wait);
 int qctxt_wait_pending_dqacq(struct lustre_quota_ctxt *qctxt, unsigned int id,
                              unsigned short type, int isblk);
-int qctxt_init(struct lustre_quota_ctxt *qctxt, struct super_block *sb,
-               dqacq_handler_t handler);
+int qctxt_init(struct obd_device *obd, dqacq_handler_t handler);
 void qctxt_cleanup(struct lustre_quota_ctxt *qctxt, int force);
 void qslave_start_recovery(struct obd_device *obd,
                            struct lustre_quota_ctxt *qctxt);
@@ -167,10 +167,12 @@ static inline void lprocfs_quotacheck_test_init_vars
 #endif
 
 /* quota_adjust_qunit.c */
-int client_quota_adjust_qunit(struct obd_export *exp, struct
-                              quota_adjust_qunit *oqaq);
-int lov_quota_adjust_qunit(struct obd_export *exp, struct
-                           quota_adjust_qunit *oqaq);
+int client_quota_adjust_qunit(struct obd_export *exp,
+                              struct quota_adjust_qunit *oqaq,
+                              struct lustre_quota_ctxt *qctxt);
+int lov_quota_adjust_qunit(struct obd_export *exp,
+                           struct quota_adjust_qunit *oqaq,
+                           struct lustre_quota_ctxt *qctxt);
 int quota_adjust_slave_lqs(struct quota_adjust_qunit *oqaq, struct
                           lustre_quota_ctxt *qctxt);
 void qdata_to_oqaq(struct qunit_data *qdata,
@@ -192,8 +194,13 @@ extern int quote_get_qdata(struct ptlrpc_request *req, struct qunit_data *qdata,
                            int is_req, int is_exp);
 extern int quote_copy_qdata(struct ptlrpc_request *req, struct qunit_data *qdata,
                             int is_req, int is_exp);
-int filter_quota_adjust_qunit(struct obd_export *exp, struct
-                              quota_adjust_qunit *oqaq);
+int filter_quota_adjust_qunit(struct obd_export *exp,
+                              struct quota_adjust_qunit *oqaq,
+                              struct lustre_quota_ctxt *qctxt);
+int lquota_proc_setup(struct obd_device *obd, int is_master);
+int lquota_proc_cleanup(struct lustre_quota_ctxt *qctxt);
+
+extern cfs_proc_dir_entry_t *lquota_type_proc_dir;
 #endif
 
 #define LQS_BLK_DECREASE 1
diff --git a/lustre/quota/quota_master.c b/lustre/quota/quota_master.c
index 8691c1b8779daa7e6a49e5f278285936a678e8a2..196fb818e0665f137a97f0f860b740897959bc48 100644
--- a/lustre/quota/quota_master.c
+++ b/lustre/quota/quota_master.c
@@ -44,7 +44,7 @@
 # define EXPORT_SYMTAB
 #endif
 
-#define DEBUG_SUBSYSTEM S_MDS
+#define DEBUG_SUBSYSTEM S_LQUOTA
 
 #include <linux/version.h>
 #include <linux/fs.h>
@@ -322,7 +322,7 @@ int dqacq_adjust_qunit_sz(struct obd_device *obd, qid_t id, int type,
 
         /* only when block qunit is reduced, boardcast to osts */
         if ((adjust_res & LQS_BLK_DECREASE) && QAQ_IS_ADJBLK(oqaq))
-                rc = obd_quota_adjust_qunit(mds->mds_osc_exp, oqaq);
+                rc = obd_quota_adjust_qunit(mds->mds_osc_exp, oqaq, qctxt);
 
 out:
         lustre_dqput(dquot);
@@ -1227,7 +1227,7 @@ static int mds_init_slave_blimits(struct obd_device *obd,
          * this is will create a lqs for every ost, which will present
          * certain uid/gid is set quota or not */
         QAQ_SET_ADJBLK(oqaq);
-        rc = obd_quota_adjust_qunit(mds->mds_osc_exp, oqaq);
+        rc = obd_quota_adjust_qunit(mds->mds_osc_exp, oqaq, qctxt);
 
         EXIT;
 out:
diff --git a/lustre/tests/sanity-quota.sh b/lustre/tests/sanity-quota.sh
index d2f042e59e2c613a29254383adfc5197bdcaef4c..224b03a419f17ef83e1f744f962624aa755079ba 100644
--- a/lustre/tests/sanity-quota.sh
+++ b/lustre/tests/sanity-quota.sh
@@ -76,38 +76,38 @@ eval ONLY_99=true
 
 # set_blk_tunables(btune_sz)
 set_blk_tunesz() {
-        local btune=$(($1 * BLK_SZ))
+	local btune=$(($1 * BLK_SZ))
 	# set btune size on all obdfilters
-	do_facet ost1 "lctl set_param obdfilter.*.quota_btune_sz=$btune"
+	do_facet ost1 "lctl set_param lquota.${FSNAME}-OST*.quota_btune_sz=$btune"
 	# set btune size on mds
-	do_facet mds "lctl set_param mds.${FSNAME}-MDT*.quota_btune_sz=$btune"
+	do_facet mds  "lctl set_param lquota.${FSNAME}-MDT*.quota_btune_sz=$btune"
 }
 
 # set_blk_unitsz(bunit_sz)
 set_blk_unitsz() {
 	local bunit=$(($1 * BLK_SZ))
 	# set bunit size on all obdfilters
-	do_facet ost1 "lctl set_param obdfilter.*.quota_bunit_sz=$bunit"
+	do_facet ost1 "lctl set_param lquota.${FSNAME}-OST*.quota_bunit_sz=$bunit"
 	# set bunit size on mds
-	do_facet mds "lctl set_param mds.${FSNAME}-MDT*.quota_bunit_sz=$bunit"
+	do_facet mds  "lctl set_param lquota.${FSNAME}-MDT*.quota_bunit_sz=$bunit"
 }
 
 # set_file_tunesz(itune_sz)
 set_file_tunesz() {
 	local itune=$1
 	# set itune size on all obdfilters
-	do_facet ost1 "lctl set_param obdfilter.*.quota_itune_sz=$itune"
+	do_facet ost1 "lctl set_param lquota.${FSNAME}-OST*.quota_itune_sz=$itune"
 	# set itune size on mds
-	do_facet mds "lctl set_param mds.${FSNAME}-MDT*.quota_itune_sz=$itune"
+	do_facet mds  "lctl set_param lquota.${FSNAME}-MDT*.quota_itune_sz=$itune"
 }
 
 # set_file_unitsz(iunit_sz)
 set_file_unitsz() {
 	local iunit=$1
 	# set iunit size on all obdfilters
-	do_facet ost1 "lctl set_param obdfilter.*.quota_iunit_sz=$iunit"
+	do_facet ost1 "lctl set_param lquota.${FSNAME}-OST*.quota_iunit_sz=$iunit"
 	# set iunit size on mds
-	do_facet mds "lctl set_param mds.${FSNAME}-MDT*.quota_iunit_sz=$iunit"
+	do_facet mds  "lctl set_param lquota.${FSNAME}-MDT*.quota_iunit_sz=$iunit"
 }
 
 lustre_fail() {
@@ -138,6 +138,24 @@ FAIL_ON_ERROR=true check_runas_id $TSTID2 $RUNAS2
 
 FAIL_ON_ERROR=false
 
+run_test_with_stat() {
+	(($# != 2)) && error "the number of arguments is wrong"
+
+	do_facet mds  "lctl set_param lquota.${FSNAME}-MDT*.stats=0" > /dev/null
+	for j in `seq $OSTCOUNT`; do
+	    do_facet ost$j "lctl set_param lquota.${FSNAME}-OST*.stats=0" > /dev/null
+	done
+	run_test "$@"
+	if [ ${STAT:-"yes"} != "no" ]; then
+	    echo "statistics info begin ***************************************"
+	    do_facet mds  "lctl get_param lquota.${FSNAME}-MDT*.stats"
+	    for j in `seq $OSTCOUNT`; do
+		do_facet ost$j "lctl get_param lquota.${FSNAME}-OST*.stats"
+	    done
+	    echo "statistics info end   ***************************************"
+	fi
+}
+
 # set quota
 test_0() {
 	$LFS quotaoff -ug $DIR
@@ -152,7 +170,7 @@ test_0() {
 	    do_facet ost$num "lctl set_param debug=+quota"
 	done
 }
-run_test 0 "Set quota ============================="
+run_test_with_stat 0 "Set quota ============================="
 
 # test for specific quota limitation, qunit, qtune $1=block_quota_limit
 test_1_sub() {
@@ -241,7 +259,7 @@ test_1() {
 	    set_blk_tunesz $((128 * 1024 / 2))
         done
 }
-run_test 1 "Block hard limit (normal use and out of quota) ==="
+run_test_with_stat 1 "Block hard limit (normal use and out of quota) ==="
 
 # test for specific quota limitation, qunit, qtune $1=block_quota_limit
 test_2_sub() {
@@ -331,7 +349,7 @@ test_2() {
 	    set_file_tunesz 2560
         done
 }
-run_test 2 "File hard limit (normal use and out of quota) ==="
+run_test_with_stat 2 "File hard limit (normal use and out of quota) ==="
 
 test_block_soft() {
 	TESTFILE=$1
@@ -428,7 +446,7 @@ test_3() {
 	test_block_soft $TESTFILE $GRACE
 	$LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR
 }
-run_test 3 "Block soft limit (start timer, timer goes off, stop timer) ==="
+run_test_with_stat 3 "Block soft limit (start timer, timer goes off, stop timer) ==="
 
 test_file_soft() {
 	TESTFILE=$1
@@ -514,7 +532,7 @@ test_4a() {	# was test_4
 	$LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace $MAX_IQ_TIME $DIR
 	$LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace $MAX_IQ_TIME $DIR
 }
-run_test 4a "File soft limit (start timer, timer goes off, stop timer) ==="
+run_test_with_stat 4a "File soft limit (start timer, timer goes off, stop timer) ==="
 
 test_4b() {	# was test_4a
         GR_STR1="1w3d"
@@ -542,7 +560,7 @@ test_4b() {	# was test_4a
         $LFS setquota -t -u --block-grace $MAX_DQ_TIME --inode-grace $MAX_IQ_TIME $DIR
         $LFS setquota -t -g --block-grace $MAX_DQ_TIME --inode-grace $MAX_IQ_TIME $DIR
 }
-run_test 4b "Grace time strings handling ==="
+run_test_with_stat 4b "Grace time strings handling ==="
 
 # chown & chgrp (chown & chgrp successfully even out of block/file quota)
 test_5() {
@@ -576,7 +594,7 @@ test_5() {
 	$LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR
 	$LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR
 }
-run_test 5 "Chown & chgrp successfully even out of block/file quota ==="
+run_test_with_stat 5 "Chown & chgrp successfully even out of block/file quota ==="
 
 # block quota acquire & release
 test_6() {
@@ -644,7 +662,7 @@ test_6() {
 	$LFS setquota -g $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR
 	return 0
 }
-run_test 6 "Block quota acquire & release ========="
+run_test_with_stat 6 "Block quota acquire & release ========="
 
 # quota recovery (block quota only by now)
 test_7()
@@ -697,7 +715,7 @@ test_7()
 	# cleanup
 	$LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR
 }
-run_test 7 "Quota recovery (only block limit) ======"
+run_test_with_stat 7 "Quota recovery (only block limit) ======"
 
 # run dbench with quota enabled
 test_8() {
@@ -736,7 +754,7 @@ test_8() {
 	cd $SAVE_PWD
 	return $RC
 }
-run_test 8 "Run dbench with quota enabled ==========="
+run_test_with_stat 8 "Run dbench with quota enabled ==========="
 
 # run for fixing bug10707, it needs a big room. test for 64bit
 KB=1024
@@ -808,7 +826,7 @@ test_9() {
 
         return $RC
 }
-run_test 9 "run for fixing bug10707(64bit) ==========="
+run_test_with_stat 9 "run for fixing bug10707(64bit) ==========="
 
 # run for fixing bug10707, it need a big room. test for 32bit
 test_10() {
@@ -866,7 +884,7 @@ test_10() {
 
 	return $RC
 }
-run_test 10 "run for fixing bug10707(32bit) ==========="
+run_test_with_stat 10 "run for fixing bug10707(32bit) ==========="
 
 test_11() {
        wait_delete_completed
@@ -935,7 +953,7 @@ test_11() {
        fi
        return $RV
 }
-run_test 11 "run for fixing bug10912 ==========="
+run_test_with_stat 11 "run for fixing bug10912 ==========="
 
 
 # test a deadlock between quota and journal b=11693
@@ -1007,7 +1025,7 @@ test_12() {
 
         $LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR
 }
-run_test 12 "test a deadlock between quota and journal ==="
+run_test_with_stat 12 "test a deadlock between quota and journal ==="
 
 # test multiple clients write block quota b=11693
 test_13() {
@@ -1071,7 +1089,7 @@ test_13() {
 
 	$LFS setquota -u $TSTUSR -b 0 -B 0 -i 0 -I 0 $DIR
 }
-run_test 13 "test multiple clients write block quota ==="
+run_test_with_stat 13 "test multiple clients write block quota ==="
 
 check_if_quota_zero(){
         line=`$LFS quota -v -$1 $2 $DIR | wc -l`
@@ -1126,13 +1144,13 @@ test_14a() {	# was test_14 b=12223 -- setting quota on root
 	rm -f $TESTFILE
 	sync; sleep 3; sync;
 }
-run_test 14a "test setting quota on root ==="
+run_test_with_stat 14a "test setting quota on root ==="
 
 # set quota version (both administrative and operational quotas)
 quota_set_version() {
-        do_facet mds "lctl set_param mds.${FSNAME}-MDT*.quota_type=$1"
+        do_facet mds "lctl set_param lquota.${FSNAME}-MDT*.quota_type=$1"
         for j in `seq $OSTCOUNT`; do
-                do_facet ost$j "lctl set_param obdfilter.*.quota_type=$1"
+                do_facet ost$j "lctl set_param lquota.${FSNAME}-OST*.quota_type=$1"
         done
 }
 
@@ -1212,7 +1230,7 @@ test_14b(){
                 $LFS setquota -u quota15_$i -b 0 -B 0 -i 0 -I 0 $DIR || error "ifs setquota clear failed"
         done
 }
-run_test 14b "setting 30 quota entries in quota v1 file before conversion ==="
+run_test_with_stat 14b "setting 30 quota entries in quota v1 file before conversion ==="
 
 test_15(){
         LIMIT=$((24 * 1024 * 1024 * 1024 * 1024)) # 24 TB
@@ -1240,7 +1258,7 @@ test_15(){
         echo "Testing that >4GB quota limits fail on volume with quota v1"
         ! $LFS setquota -u $TSTUSR -b 0 -B $LIMIT -i 0 -I 0 $DIR
 }
-run_test 15 "set block quota more than 4T ==="
+run_test_with_stat 15 "set block quota more than 4T ==="
 
 # $1=u/g $2=with qunit adjust or not
 test_16_tub() {
@@ -1301,7 +1319,7 @@ test_16 () {
 	set_blk_unitsz $((128 * 1024))
 	set_blk_tunesz $((128 * 1024 / 2))
 }
-run_test 16 "test without adjusting qunit"
+run_test_with_stat 16 "test without adjusting qunit"
 
 # run for fixing bug14526, failed returned quota reqs shouldn't ruin lustre.
 test_17() {
@@ -1358,7 +1376,7 @@ test_17() {
 
 	return $RC
 }
-run_test 17 "run for fixing bug14526 ==========="
+run_test_with_stat 17 "run for fixing bug14526 ==========="
 
 # test when mds takes a long time to handle a quota req so that
 # the ost has dropped it, the ost still could work well b=14840
@@ -1415,7 +1433,7 @@ test_18() {
 	set_blk_unitsz $((128 * 1024))
 	set_blk_tunesz $((128 * 1024 / 2))
 }
-run_test 18 "run for fixing bug14840 ==========="
+run_test_with_stat 18 "run for fixing bug14840 ==========="
 
 # test when mds drops a quota req, the ost still could work well b=14840
 test_18a() {
@@ -1472,7 +1490,7 @@ test_18a() {
 	set_blk_unitsz $((128 * 1024))
 	set_blk_tunesz $((128 * 1024 / 2))
 }
-run_test 18a "run for fixing bug14840 ==========="
+run_test_with_stat 18a "run for fixing bug14840 ==========="
 
 test_19() {
 	# 1 Mb bunit per each MDS/OSS
@@ -1514,7 +1532,7 @@ test_19() {
 	set_blk_tunesz $((128 * 1024 / 2))
 
 }
-run_test 19 "test if administrative limits updates do not zero operational limits (14790) ==="
+run_test_with_stat 19 "test if administrative limits updates do not zero operational limits (14790) ==="
 
 test_20()
 {
@@ -1537,7 +1555,7 @@ test_20()
                                  $MOUNT || error "could not reset quota limits"
 
 }
-run_test 20 "test if setquota specifiers work properly (15754)"
+run_test_with_stat 20 "test if setquota specifiers work properly (15754)"
 
 test_21_sub() {
 	local testfile=$1
@@ -1615,7 +1633,7 @@ test_21() {
 
 	return $RC
 }
-run_test 21 "run for fixing bug16053 ==========="
+run_test_with_stat 21 "run for fixing bug16053 ==========="
 
 test_22() {
         local SAVEREFORMAT
@@ -1640,7 +1658,7 @@ test_22() {
 
         run_test 0 "reboot lustre"
 }
-run_test 22 "test if quota_type saved as permanent parameter ===="
+run_test_with_stat 22 "test if quota_type saved as permanent parameter ===="
 
 # turn off quota
 test_99()
@@ -1650,7 +1668,7 @@ test_99()
 
 	return 0
 }
-run_test 99 "Quota off ==============================="
+run_test_with_stat 99 "Quota off ==============================="
 
 
 log "cleanup: ======================================================"