Whamcloud - gitweb
Branch HEAD
authorfanyong <fanyong>
Thu, 28 May 2009 11:15:45 +0000 (11:15 +0000)
committerfanyong <fanyong>
Thu, 28 May 2009 11:15:45 +0000 (11:15 +0000)
b=19447
i=tianzy
i=andrew.perepechko

Separate user and group pending when quota check/commit.

12 files changed:
lustre/include/lustre_quota.h
lustre/mdd/mdd_dir.c
lustre/mdd/mdd_internal.h
lustre/mdd/mdd_object.c
lustre/obdfilter/filter_io_26.c
lustre/osc/osc_request.c
lustre/quota/quota_adjust_qunit.c
lustre/quota/quota_context.c
lustre/quota/quota_ctl.c
lustre/quota/quota_interface.c
lustre/quota/quota_internal.h
lustre/quota/quota_master.c

index b4a2314..6f0105a 100644 (file)
@@ -412,9 +412,8 @@ struct quotacheck_thread_args {
 };
 
 struct obd_trans_info;
 };
 
 struct obd_trans_info;
-typedef int (*quota_acquire)(struct obd_device *obd, unsigned int uid,
-                             unsigned int gid, struct obd_trans_info *oti,
-                             int isblk);
+typedef int (*quota_acquire)(struct obd_device *obd, const unsigned int id[],
+                             struct obd_trans_info *oti, int isblk);
 
 typedef struct {
         int (*quota_init) (void);
 
 typedef struct {
         int (*quota_init) (void);
@@ -434,8 +433,8 @@ typedef struct {
         /**
          * For quota master/slave, adjust quota limit after fs operation
          */
         /**
          * For quota master/slave, adjust quota limit after fs operation
          */
-        int (*quota_adjust) (struct obd_device *, unsigned int[],
-                             unsigned int[], int, int);
+        int (*quota_adjust) (struct obd_device *, const unsigned int[],
+                             const unsigned int[], int, int);
 
         /**
          * For quota slave, set import, trigger quota recovery,
 
         /**
          * For quota slave, set import, trigger quota recovery,
@@ -462,7 +461,7 @@ typedef struct {
         /**
          * For quota slave, acquire/release quota from master if needed
          */
         /**
          * For quota slave, acquire/release quota from master if needed
          */
-        int (*quota_acquire) (struct obd_device *, unsigned int, unsigned int,
+        int (*quota_acquire) (struct obd_device *, const unsigned int [],
                               struct obd_trans_info *, int);
 
         /**
                               struct obd_trans_info *, int);
 
         /**
@@ -470,16 +469,16 @@ typedef struct {
          * can finish a block_write or inode_create rpc. It updates the pending
          * record of block and inode, acquires quota if necessary
          */
          * can finish a block_write or inode_create rpc. It updates the pending
          * record of block and inode, acquires quota if necessary
          */
-        int (*quota_chkquota) (struct obd_device *, unsigned int, unsigned int,
-                               int, int *, quota_acquire,
+        int (*quota_chkquota) (struct obd_device *, const unsigned int [],
+                               int [], int, quota_acquire,
                                struct obd_trans_info *, int, struct inode *,
                                int);
 
         /**
          * For quota client, the actions after the pending write is committed
          */
                                struct obd_trans_info *, int, struct inode *,
                                int);
 
         /**
          * For quota client, the actions after the pending write is committed
          */
-        int (*quota_pending_commit) (struct obd_device *, unsigned int,
-                                     unsigned int, int, int);
+        int (*quota_pending_commit) (struct obd_device *, const unsigned int [],
+                                     int [], int);
 #endif
 
         /**
 #endif
 
         /**
@@ -490,12 +489,12 @@ typedef struct {
         /**
          * For quota client, check whether specified uid/gid is over quota
          */
         /**
          * For quota client, check whether specified uid/gid is over quota
          */
-        int (*quota_chkdq) (struct client_obd *, unsigned int, unsigned int);
+        int (*quota_chkdq) (struct client_obd *, const unsigned int []);
 
         /**
          * For quota client, set over quota flag for specifed uid/gid
          */
 
         /**
          * For quota client, set over quota flag for specifed uid/gid
          */
-        int (*quota_setdq) (struct client_obd *, unsigned int, unsigned int,
+        int (*quota_setdq) (struct client_obd *, const unsigned int [],
                             obd_flag, obd_flag);
 
         /**
                             obd_flag, obd_flag);
 
         /**
@@ -612,8 +611,8 @@ static inline int lquota_ctl(quota_interface_t *interface,
 
 static inline int lquota_adjust(quota_interface_t *interface,
                                 struct obd_device *obd,
 
 static inline int lquota_adjust(quota_interface_t *interface,
                                 struct obd_device *obd,
-                                unsigned int qcids[],
-                                unsigned int qpids[],
+                                const unsigned int qcids[],
+                                const unsigned int qpids[],
                                 int rc, int opc)
 {
         int ret;
                                 int rc, int opc)
 {
         int ret;
@@ -625,27 +624,25 @@ static inline int lquota_adjust(quota_interface_t *interface,
 }
 
 static inline int lquota_chkdq(quota_interface_t *interface,
 }
 
 static inline int lquota_chkdq(quota_interface_t *interface,
-                               struct client_obd *cli,
-                               unsigned int uid, unsigned int gid)
+                               struct client_obd *cli, const unsigned int qid[])
 {
         int rc;
         ENTRY;
 
         QUOTA_CHECK_OP(interface, chkdq);
 {
         int rc;
         ENTRY;
 
         QUOTA_CHECK_OP(interface, chkdq);
-        rc = QUOTA_OP(interface, chkdq)(cli, uid, gid);
+        rc = QUOTA_OP(interface, chkdq)(cli, qid);
         RETURN(rc);
 }
 
 static inline int lquota_setdq(quota_interface_t *interface,
         RETURN(rc);
 }
 
 static inline int lquota_setdq(quota_interface_t *interface,
-                               struct client_obd *cli,
-                               unsigned int uid, unsigned int gid,
+                               struct client_obd *cli, const unsigned int qid[],
                                obd_flag valid, obd_flag flags)
 {
         int rc;
         ENTRY;
 
         QUOTA_CHECK_OP(interface, setdq);
                                obd_flag valid, obd_flag flags)
 {
         int rc;
         ENTRY;
 
         QUOTA_CHECK_OP(interface, setdq);
-        rc = QUOTA_OP(interface, setdq)(cli, uid, gid, valid, flags);
+        rc = QUOTA_OP(interface, setdq)(cli, qid, valid, flags);
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
@@ -711,8 +708,8 @@ static inline int lquota_getflag(quota_interface_t *interface,
 #ifdef __KERNEL__
 static inline int lquota_chkquota(quota_interface_t *interface,
                                   struct obd_device *obd,
 #ifdef __KERNEL__
 static inline int lquota_chkquota(quota_interface_t *interface,
                                   struct obd_device *obd,
-                                  unsigned int uid, unsigned int gid, int count,
-                                  int *flag, struct obd_trans_info *oti,
+                                  const unsigned int id[], int pending[],
+                                  int count, struct obd_trans_info *oti,
                                   int isblk, void *data, int frags)
 {
         int rc;
                                   int isblk, void *data, int frags)
 {
         int rc;
@@ -720,7 +717,7 @@ static inline int lquota_chkquota(quota_interface_t *interface,
 
         QUOTA_CHECK_OP(interface, chkquota);
         QUOTA_CHECK_OP(interface, acquire);
 
         QUOTA_CHECK_OP(interface, chkquota);
         QUOTA_CHECK_OP(interface, acquire);
-        rc = QUOTA_OP(interface, chkquota)(obd, uid, gid, count, flag,
+        rc = QUOTA_OP(interface, chkquota)(obd, id, pending, count,
                                            QUOTA_OP(interface, acquire), oti,
                                            isblk, (struct inode *)data, frags);
         RETURN(rc);
                                            QUOTA_OP(interface, acquire), oti,
                                            isblk, (struct inode *)data, frags);
         RETURN(rc);
@@ -728,14 +725,14 @@ static inline int lquota_chkquota(quota_interface_t *interface,
 
 static inline int lquota_pending_commit(quota_interface_t *interface,
                                         struct obd_device *obd,
 
 static inline int lquota_pending_commit(quota_interface_t *interface,
                                         struct obd_device *obd,
-                                        unsigned int uid, unsigned int gid,
-                                        int pending, int isblk)
+                                        const unsigned int id[],
+                                        int pending[], int isblk)
 {
         int rc;
         ENTRY;
 
         QUOTA_CHECK_OP(interface, pending_commit);
 {
         int rc;
         ENTRY;
 
         QUOTA_CHECK_OP(interface, pending_commit);
-        rc = QUOTA_OP(interface, pending_commit)(obd, uid, gid, pending, isblk);
+        rc = QUOTA_OP(interface, pending_commit)(obd, id, pending, isblk);
         RETURN(rc);
 }
 #endif
         RETURN(rc);
 }
 #endif
index fde65cd..d051c90 100644 (file)
@@ -667,7 +667,7 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj,
         struct obd_device *obd = mdd->mdd_obd_dev;
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qids[MAXQUOTAS] = { 0, 0 };
         struct obd_device *obd = mdd->mdd_obd_dev;
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qids[MAXQUOTAS] = { 0, 0 };
-        int quota_opc = 0, rec_pending = 0;
+        int quota_opc = 0, rec_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         int rc;
         ENTRY;
 #endif
         int rc;
         ENTRY;
@@ -684,9 +684,8 @@ static int mdd_link(const struct lu_env *env, struct md_object *tgt_obj,
                         mdd_quota_wrapper(la_tmp, qids);
                         /* get block quota for parent */
                         lquota_chkquota(mds_quota_interface_ref, obd,
                         mdd_quota_wrapper(la_tmp, qids);
                         /* get block quota for parent */
                         lquota_chkquota(mds_quota_interface_ref, obd,
-                                        qids[USRQUOTA], qids[GRPQUOTA], 1,
-                                        &rec_pending, NULL, LQUOTA_FLAGS_BLK,
-                                        data, 1);
+                                        qids, rec_pending, 1, NULL,
+                                        LQUOTA_FLAGS_BLK, data, 1);
                 }
         }
 #endif
                 }
         }
 #endif
@@ -738,10 +737,8 @@ out_trans:
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
-                if (rec_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qids[USRQUOTA], qids[GRPQUOTA],
-                                              rec_pending, 1);
+                lquota_pending_commit(mds_quota_interface_ref, obd,
+                                      qids, rec_pending, 1);
                 /* Trigger dqacq for the parent owner. If failed,
                  * the next call for lquota_chkquota will process it. */
                 lquota_adjust(mds_quota_interface_ref, obd, 0, qids, rc,
                 /* Trigger dqacq for the parent owner. If failed,
                  * the next call for lquota_chkquota will process it. */
                 lquota_adjust(mds_quota_interface_ref, obd, 0, qids, rc,
@@ -960,7 +957,7 @@ static int mdd_name_insert(const struct lu_env *env,
         struct obd_device *obd = mdd->mdd_obd_dev;
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qids[MAXQUOTAS] = { 0, 0 };
         struct obd_device *obd = mdd->mdd_obd_dev;
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qids[MAXQUOTAS] = { 0, 0 };
-        int quota_opc = 0, rec_pending = 0;
+        int quota_opc = 0, rec_pending[MAXQUOTAS] = { 0, 0 };
         cfs_cap_t save = uc->mu_cap;
 #endif
         int rc;
         cfs_cap_t save = uc->mu_cap;
 #endif
         int rc;
@@ -979,8 +976,7 @@ static int mdd_name_insert(const struct lu_env *env,
                                 mdd_quota_wrapper(la_tmp, qids);
                                 /* get block quota for parent */
                                 lquota_chkquota(mds_quota_interface_ref, obd,
                                 mdd_quota_wrapper(la_tmp, qids);
                                 /* get block quota for parent */
                                 lquota_chkquota(mds_quota_interface_ref, obd,
-                                                qids[USRQUOTA], qids[GRPQUOTA],
-                                                1, &rec_pending, NULL,
+                                                qids, rec_pending, 1, NULL,
                                                 LQUOTA_FLAGS_BLK, data, 1);
                         }
                 } else {
                                                 LQUOTA_FLAGS_BLK, data, 1);
                         }
                 } else {
@@ -1027,11 +1023,8 @@ out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (mds->mds_quota) {
                 if (quota_opc) {
 #ifdef HAVE_QUOTA_SUPPORT
         if (mds->mds_quota) {
                 if (quota_opc) {
-                        if (rec_pending)
-                                lquota_pending_commit(mds_quota_interface_ref,
-                                                      obd, qids[USRQUOTA],
-                                                      qids[GRPQUOTA],
-                                                      rec_pending, 1);
+                        lquota_pending_commit(mds_quota_interface_ref,
+                                              obd, qids, rec_pending, 1);
                         /* Trigger dqacq for the parent owner. If failed,
                          * the next call for lquota_chkquota will process it*/
                         lquota_adjust(mds_quota_interface_ref, obd, 0, qids,
                         /* Trigger dqacq for the parent owner. If failed,
                          * the next call for lquota_chkquota will process it*/
                         lquota_adjust(mds_quota_interface_ref, obd, 0, qids,
@@ -1188,7 +1181,8 @@ static int mdd_rename_tgt(const struct lu_env *env,
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qcids[MAXQUOTAS] = { 0, 0 };
         unsigned int qpids[MAXQUOTAS] = { 0, 0 };
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qcids[MAXQUOTAS] = { 0, 0 };
         unsigned int qpids[MAXQUOTAS] = { 0, 0 };
-        int quota_opc = 0, rec_pending = 0;
+        int quota_copc = 0, quota_popc = 0;
+        int rec_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         int rc;
         ENTRY;
 #endif
         int rc;
         ENTRY;
@@ -1201,13 +1195,12 @@ static int mdd_rename_tgt(const struct lu_env *env,
                 if (!rc) {
                         void *data = NULL;
                         mdd_data_get(env, mdd_tpobj, &data);
                 if (!rc) {
                         void *data = NULL;
                         mdd_data_get(env, mdd_tpobj, &data);
-                        quota_opc = FSFILT_OP_LINK;
+                        quota_popc = FSFILT_OP_LINK;
                         mdd_quota_wrapper(la_tmp, qpids);
                         /* get block quota for target parent */
                         lquota_chkquota(mds_quota_interface_ref, obd,
                         mdd_quota_wrapper(la_tmp, qpids);
                         /* get block quota for target parent */
                         lquota_chkquota(mds_quota_interface_ref, obd,
-                                        qpids[USRQUOTA], qpids[GRPQUOTA], 1,
-                                        &rec_pending, NULL, LQUOTA_FLAGS_BLK,
-                                        data, 1);
+                                        qpids, rec_pending, 1, NULL,
+                                        LQUOTA_FLAGS_BLK, data, 1);
                 }
         }
 #endif
                 }
         }
 #endif
@@ -1271,7 +1264,7 @@ static int mdd_rename_tgt(const struct lu_env *env,
 #ifdef HAVE_QUOTA_SUPPORT
                 if (mds->mds_quota && ma->ma_valid & MA_INODE &&
                     ma->ma_attr.la_nlink == 0 && mdd_tobj->mod_count == 0) {
 #ifdef HAVE_QUOTA_SUPPORT
                 if (mds->mds_quota && ma->ma_valid & MA_INODE &&
                     ma->ma_attr.la_nlink == 0 && mdd_tobj->mod_count == 0) {
-                        quota_opc = FSFILT_OP_UNLINK_PARTIAL_CHILD;
+                        quota_copc = FSFILT_OP_UNLINK_PARTIAL_CHILD;
                         mdd_quota_wrapper(&ma->ma_attr, qcids);
                 }
 #endif
                         mdd_quota_wrapper(&ma->ma_attr, qcids);
                 }
 #endif
@@ -1292,17 +1285,16 @@ out_trans:
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (mds->mds_quota) {
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (mds->mds_quota) {
-                if (rec_pending)
+                if (quota_popc)
                         lquota_pending_commit(mds_quota_interface_ref, obd,
                         lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qpids[USRQUOTA],
-                                              qpids[GRPQUOTA],
-                                              rec_pending, 1);
-                if (quota_opc)
-                        /* Trigger dqrel/dqacq on the target owner of child and
-                         * parent. If failed, the next call for lquota_chkquota
+                                              qpids, rec_pending, 1);
+
+                if (quota_copc)
+                        /* Trigger dqrel on the target owner of child.
+                         * If failed, the next call for lquota_chkquota
                          * will process it. */
                          * will process it. */
-                        lquota_adjust(mds_quota_interface_ref, obd, qcids,
-                                      qpids, rc, quota_opc);
+                        lquota_adjust(mds_quota_interface_ref, obd, qcids, qpids,
+                                      rc, quota_copc);
         }
 #endif
         return rc;
         }
 #endif
         return rc;
@@ -1597,7 +1589,9 @@ static int mdd_create(const struct lu_env *env,
         unsigned int qcids[MAXQUOTAS] = { 0, 0 };
         unsigned int qpids[MAXQUOTAS] = { 0, 0 };
         int quota_opc = 0, block_count = 0;
         unsigned int qcids[MAXQUOTAS] = { 0, 0 };
         unsigned int qpids[MAXQUOTAS] = { 0, 0 };
         int quota_opc = 0, block_count = 0;
-        int inode_pending = 0, block_pending = 0, parent_pending = 0;
+        int inode_pending[MAXQUOTAS] = { 0, 0 };
+        int block_pending[MAXQUOTAS] = { 0, 0 };
+        int parent_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         ENTRY;
 
 #endif
         ENTRY;
 
@@ -1654,9 +1648,8 @@ static int mdd_create(const struct lu_env *env,
                         mdd_quota_wrapper(&ma->ma_attr, qcids);
                         mdd_quota_wrapper(la_tmp, qpids);
                         /* get file quota for child */
                         mdd_quota_wrapper(&ma->ma_attr, qcids);
                         mdd_quota_wrapper(la_tmp, qpids);
                         /* get file quota for child */
-                        lquota_chkquota(mds_quota_interface_ref, obd,
-                                        qcids[USRQUOTA], qcids[GRPQUOTA], 1,
-                                        &inode_pending, NULL, 0, NULL, 0);
+                        lquota_chkquota(mds_quota_interface_ref, obd, qcids,
+                                        inode_pending, 1, NULL, 0, NULL, 0);
                         switch (ma->ma_attr.la_mode & S_IFMT) {
                         case S_IFLNK:
                         case S_IFDIR:
                         switch (ma->ma_attr.la_mode & S_IFMT) {
                         case S_IFLNK:
                         case S_IFDIR:
@@ -1674,14 +1667,12 @@ static int mdd_create(const struct lu_env *env,
                         /* get block quota for child and parent */
                         if (block_count)
                                 lquota_chkquota(mds_quota_interface_ref, obd,
                         /* get block quota for child and parent */
                         if (block_count)
                                 lquota_chkquota(mds_quota_interface_ref, obd,
-                                                qcids[USRQUOTA], qcids[GRPQUOTA],
-                                                block_count,
-                                                &block_pending, NULL,
+                                                qcids, block_pending,
+                                                block_count, NULL,
                                                 LQUOTA_FLAGS_BLK, NULL, 0);
                         if (!same)
                                 lquota_chkquota(mds_quota_interface_ref, obd,
                                                 LQUOTA_FLAGS_BLK, NULL, 0);
                         if (!same)
                                 lquota_chkquota(mds_quota_interface_ref, obd,
-                                                qpids[USRQUOTA], qpids[GRPQUOTA], 1,
-                                                &parent_pending, NULL,
+                                                qpids, parent_pending, 1, NULL,
                                                 LQUOTA_FLAGS_BLK, NULL, 0);
                 }
         }
                                                 LQUOTA_FLAGS_BLK, NULL, 0);
                 }
         }
@@ -1852,18 +1843,12 @@ out_free:
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
-                if (inode_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qcids[USRQUOTA], qcids[GRPQUOTA],
-                                              inode_pending, 0);
-                if (block_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qcids[USRQUOTA], qcids[GRPQUOTA],
-                                              block_pending, 1);
-                if (parent_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qpids[USRQUOTA], qpids[GRPQUOTA],
-                                              parent_pending, 1);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qcids,
+                                      inode_pending, 0);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qcids,
+                                      block_pending, 1);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qpids,
+                                      parent_pending, 1);
                 /* Trigger dqacq on the owner of child and parent. If failed,
                  * the next call for lquota_chkquota will process it. */
                 lquota_adjust(mds_quota_interface_ref, obd, qcids, qpids, rc,
                 /* Trigger dqacq on the owner of child and parent. If failed,
                  * the next call for lquota_chkquota will process it. */
                 lquota_adjust(mds_quota_interface_ref, obd, qcids, qpids, rc,
@@ -1987,7 +1972,8 @@ static int mdd_rename(const struct lu_env *env,
         unsigned int qspids[MAXQUOTAS] = { 0, 0 };
         unsigned int qtcids[MAXQUOTAS] = { 0, 0 };
         unsigned int qtpids[MAXQUOTAS] = { 0, 0 };
         unsigned int qspids[MAXQUOTAS] = { 0, 0 };
         unsigned int qtcids[MAXQUOTAS] = { 0, 0 };
         unsigned int qtpids[MAXQUOTAS] = { 0, 0 };
-        int quota_opc = 0, rec_pending = 0;
+        int quota_copc = 0, quota_popc = 0;
+        int rec_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         ENTRY;
 
 #endif
         ENTRY;
 
@@ -2010,13 +1996,12 @@ static int mdd_rename(const struct lu_env *env,
                                 if (!rc) {
                                         void *data = NULL;
                                         mdd_data_get(env, mdd_tpobj, &data);
                                 if (!rc) {
                                         void *data = NULL;
                                         mdd_data_get(env, mdd_tpobj, &data);
-                                        quota_opc = FSFILT_OP_LINK;
+                                        quota_popc = FSFILT_OP_LINK;
                                         mdd_quota_wrapper(la_tmp, qtpids);
                                         /* get block quota for target parent */
                                         lquota_chkquota(mds_quota_interface_ref,
                                         mdd_quota_wrapper(la_tmp, qtpids);
                                         /* get block quota for target parent */
                                         lquota_chkquota(mds_quota_interface_ref,
-                                                        obd, qtpids[USRQUOTA],
-                                                        qtpids[GRPQUOTA], 1,
-                                                        &rec_pending, NULL,
+                                                        obd, qtpids,
+                                                        rec_pending, 1, NULL,
                                                         LQUOTA_FLAGS_BLK,
                                                         data, 1);
                                 }
                                                         LQUOTA_FLAGS_BLK,
                                                         data, 1);
                                 }
@@ -2146,7 +2131,7 @@ static int mdd_rename(const struct lu_env *env,
 #ifdef HAVE_QUOTA_SUPPORT
                 if (mds->mds_quota && ma->ma_valid & MA_INODE &&
                     ma->ma_attr.la_nlink == 0 && mdd_tobj->mod_count == 0) {
 #ifdef HAVE_QUOTA_SUPPORT
                 if (mds->mds_quota && ma->ma_valid & MA_INODE &&
                     ma->ma_attr.la_nlink == 0 && mdd_tobj->mod_count == 0) {
-                        quota_opc = FSFILT_OP_UNLINK_PARTIAL_CHILD;
+                        quota_copc = FSFILT_OP_UNLINK_PARTIAL_CHILD;
                         mdd_quota_wrapper(&ma->ma_attr, qtcids);
                 }
 #endif
                         mdd_quota_wrapper(&ma->ma_attr, qtcids);
                 }
 #endif
@@ -2230,22 +2215,23 @@ cleanup_unlocked:
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (mds->mds_quota) {
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (mds->mds_quota) {
-                if (rec_pending)
+                if (quota_popc)
                         lquota_pending_commit(mds_quota_interface_ref, obd,
                         lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qtpids[USRQUOTA],
-                                              qtpids[GRPQUOTA],
-                                              rec_pending, 1);
-                /* Trigger dqrel on the source owner of parent.
-                 * If failed, the next call for lquota_chkquota will
-                 * process it. */
-                lquota_adjust(mds_quota_interface_ref, obd, 0, qspids, rc,
-                              FSFILT_OP_UNLINK_PARTIAL_PARENT);
-                if (quota_opc)
-                        /* Trigger dqrel/dqacq on the target owner of child and
-                         * parent. If failed, the next call for lquota_chkquota
+                                              qtpids, rec_pending, 1);
+
+                if (quota_copc) {
+                        /* Trigger dqrel on the source owner of parent.
+                         * If failed, the next call for lquota_chkquota will
+                         * process it. */
+                        lquota_adjust(mds_quota_interface_ref, obd, 0, qspids, rc,
+                                      FSFILT_OP_UNLINK_PARTIAL_PARENT);
+
+                        /* Trigger dqrel on the target owner of child.
+                         * If failed, the next call for lquota_chkquota
                          * will process it. */
                         lquota_adjust(mds_quota_interface_ref, obd, qtcids,
                          * will process it. */
                         lquota_adjust(mds_quota_interface_ref, obd, qtcids,
-                                      qtpids, rc, quota_opc);
+                                      qtpids, rc, quota_copc);
+                }
         }
 #endif
         return rc;
         }
 #endif
         return rc;
index 9b657e1..fc67d61 100644 (file)
@@ -62,8 +62,8 @@ extern quota_interface_t *mds_quota_interface_ref;
 
 static inline void mdd_quota_wrapper(struct lu_attr *la, unsigned int *qids)
 {
 
 static inline void mdd_quota_wrapper(struct lu_attr *la, unsigned int *qids)
 {
-        qids[0] = la->la_uid;
-        qids[1] = la->la_gid;
+        qids[USRQUOTA] = la->la_uid;
+        qids[GRPQUOTA] = la->la_gid;
 }
 #endif
 
 }
 #endif
 
index 1b1ae53..79166fc 100644 (file)
@@ -1225,7 +1225,8 @@ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj,
         unsigned int qnids[MAXQUOTAS] = { 0, 0 };
         unsigned int qoids[MAXQUOTAS] = { 0, 0 };
         int quota_opc = 0, block_count = 0;
         unsigned int qnids[MAXQUOTAS] = { 0, 0 };
         unsigned int qoids[MAXQUOTAS] = { 0, 0 };
         int quota_opc = 0, block_count = 0;
-        int inode_pending = 0, block_pending = 0;
+        int inode_pending[MAXQUOTAS] = { 0, 0 };
+        int block_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         ENTRY;
 
 #endif
         ENTRY;
 
@@ -1269,20 +1270,17 @@ static int mdd_attr_set(const struct lu_env *env, struct md_object *obj,
                         mdd_quota_wrapper(la_copy, qnids);
                         mdd_quota_wrapper(la_tmp, qoids);
                         /* get file quota for new owner */
                         mdd_quota_wrapper(la_copy, qnids);
                         mdd_quota_wrapper(la_tmp, qoids);
                         /* get file quota for new owner */
-                        lquota_chkquota(mds_quota_interface_ref, obd,
-                                        qnids[USRQUOTA], qnids[GRPQUOTA], 1,
-                                        &inode_pending, NULL, 0, NULL, 0);
+                        lquota_chkquota(mds_quota_interface_ref, obd, qnids,
+                                        inode_pending, 1, NULL, 0, NULL, 0);
                         block_count = (la_tmp->la_blocks + 7) >> 3;
                         if (block_count) {
                                 void *data = NULL;
                                 mdd_data_get(env, mdd_obj, &data);
                                 /* get block quota for new owner */
                                 lquota_chkquota(mds_quota_interface_ref, obd,
                         block_count = (la_tmp->la_blocks + 7) >> 3;
                         if (block_count) {
                                 void *data = NULL;
                                 mdd_data_get(env, mdd_obj, &data);
                                 /* get block quota for new owner */
                                 lquota_chkquota(mds_quota_interface_ref, obd,
-                                                qnids[USRQUOTA],
-                                                qnids[GRPQUOTA],
-                                                block_count, &block_pending,
-                                                NULL, LQUOTA_FLAGS_BLK,
-                                                data, 1);
+                                                qnids, block_pending,
+                                                block_count, NULL,
+                                                LQUOTA_FLAGS_BLK, data, 1);
                         }
                 }
         }
                         }
                 }
         }
@@ -1335,14 +1333,10 @@ cleanup:
         }
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
         }
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
-                if (inode_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qnids[USRQUOTA], qnids[GRPQUOTA],
-                                              inode_pending, 0);
-                if (block_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qnids[USRQUOTA], qnids[GRPQUOTA],
-                                              block_pending, 1);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qnids,
+                                      inode_pending, 0);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qnids,
+                                      block_pending, 1);
                 /* Trigger dqrel/dqacq for original owner and new owner.
                  * If failed, the next call for lquota_chkquota will
                  * process it. */
                 /* Trigger dqrel/dqacq for original owner and new owner.
                  * If failed, the next call for lquota_chkquota will
                  * process it. */
@@ -1581,7 +1575,8 @@ static int mdd_object_create(const struct lu_env *env,
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qids[MAXQUOTAS] = { 0, 0 };
         int quota_opc = 0, block_count = 0;
         struct mds_obd *mds = &obd->u.mds;
         unsigned int qids[MAXQUOTAS] = { 0, 0 };
         int quota_opc = 0, block_count = 0;
-        int inode_pending = 0, block_pending = 0;
+        int inode_pending[MAXQUOTAS] = { 0, 0 };
+        int block_pending[MAXQUOTAS] = { 0, 0 };
 #endif
         int rc = 0;
         ENTRY;
 #endif
         int rc = 0;
         ENTRY;
@@ -1591,9 +1586,8 @@ static int mdd_object_create(const struct lu_env *env,
                 quota_opc = FSFILT_OP_CREATE_PARTIAL_CHILD;
                 mdd_quota_wrapper(&ma->ma_attr, qids);
                 /* get file quota for child */
                 quota_opc = FSFILT_OP_CREATE_PARTIAL_CHILD;
                 mdd_quota_wrapper(&ma->ma_attr, qids);
                 /* get file quota for child */
-                lquota_chkquota(mds_quota_interface_ref, obd, qids[USRQUOTA],
-                                qids[GRPQUOTA], 1, &inode_pending, NULL, 0,
-                                NULL, 0);
+                lquota_chkquota(mds_quota_interface_ref, obd, qids,
+                                inode_pending, 1, NULL, 0, NULL, 0);
                 switch (ma->ma_attr.la_mode & S_IFMT) {
                 case S_IFLNK:
                 case S_IFDIR:
                 switch (ma->ma_attr.la_mode & S_IFMT) {
                 case S_IFLNK:
                 case S_IFDIR:
@@ -1605,9 +1599,8 @@ static int mdd_object_create(const struct lu_env *env,
                 }
                 /* get block quota for child */
                 if (block_count)
                 }
                 /* get block quota for child */
                 if (block_count)
-                        lquota_chkquota(mds_quota_interface_ref, obd,
-                                        qids[USRQUOTA], qids[GRPQUOTA],
-                                        block_count, &block_pending, NULL,
+                        lquota_chkquota(mds_quota_interface_ref, obd, qids,
+                                        block_pending, block_count, NULL,
                                         LQUOTA_FLAGS_BLK, NULL, 0);
         }
 #endif
                                         LQUOTA_FLAGS_BLK, NULL, 0);
         }
 #endif
@@ -1675,18 +1668,14 @@ unlock:
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
 out_pending:
 #ifdef HAVE_QUOTA_SUPPORT
         if (quota_opc) {
-                if (inode_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qids[USRQUOTA], qids[GRPQUOTA],
-                                              inode_pending, 0);
-                if (block_pending)
-                        lquota_pending_commit(mds_quota_interface_ref, obd,
-                                              qids[USRQUOTA], qids[GRPQUOTA],
-                                              block_pending, 1);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qids,
+                                      inode_pending, 0);
+                lquota_pending_commit(mds_quota_interface_ref, obd, qids,
+                                      block_pending, 1);
                 /* Trigger dqacq on the owner of child. If failed,
                  * the next call for lquota_chkquota will process it. */
                 lquota_adjust(mds_quota_interface_ref, obd, qids, 0, rc,
                 /* Trigger dqacq on the owner of child. If failed,
                  * the next call for lquota_chkquota will process it. */
                 lquota_adjust(mds_quota_interface_ref, obd, qids, 0, rc,
-                              FSFILT_OP_CREATE_PARTIAL_CHILD);
+                              quota_opc);
         }
 #endif
         return rc;
         }
 #endif
         return rc;
index 3bd68f6..a45d9da 100644 (file)
@@ -571,8 +571,8 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa,
         struct filter_obd *fo = &obd->u.filter;
         void *wait_handle;
         int total_size = 0;
         struct filter_obd *fo = &obd->u.filter;
         void *wait_handle;
         int total_size = 0;
-        int rec_pending = 0;
-        unsigned int qcids[MAXQUOTAS] = {0, 0};
+        unsigned int qcids[MAXQUOTAS] = { oa->o_uid, oa->o_gid };
+        int rec_pending[MAXQUOTAS] = { 0, 0 };
         ENTRY;
 
         LASSERT(oti != NULL);
         ENTRY;
 
         LASSERT(oti != NULL);
@@ -584,9 +584,9 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa,
 
         /* we try to get enough quota to write here, and let ldiskfs
          * decide if it is out of quota or not b=14783 */
 
         /* we try to get enough quota to write here, and let ldiskfs
          * decide if it is out of quota or not b=14783 */
-        lquota_chkquota(filter_quota_interface_ref, obd, oa->o_uid,
-                        oa->o_gid, niocount, &rec_pending, oti,
-                        LQUOTA_FLAGS_BLK, (void *)inode, obj->ioo_bufcnt);
+        lquota_chkquota(filter_quota_interface_ref, obd, qcids, rec_pending,
+                        niocount, oti, LQUOTA_FLAGS_BLK, (void *)inode,
+                        obj->ioo_bufcnt);
 
         iobuf = filter_iobuf_get(&obd->u.filter, oti);
         if (IS_ERR(iobuf))
 
         iobuf = filter_iobuf_get(&obd->u.filter, oti);
         if (IS_ERR(iobuf))
@@ -731,9 +731,8 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa,
         fsfilt_check_slow(obd, now, "commitrw commit");
 
 cleanup:
         fsfilt_check_slow(obd, now, "commitrw commit");
 
 cleanup:
-        if (rec_pending)
-                lquota_pending_commit(filter_quota_interface_ref, obd, oa->o_uid,
-                                      oa->o_gid, rec_pending, 1);
+        lquota_pending_commit(filter_quota_interface_ref, obd, qcids,
+                              rec_pending, 1);
 
         filter_grant_commit(exp, niocount, res);
 
 
         filter_grant_commit(exp, niocount, res);
 
index e46a635..0a3bacd 100644 (file)
@@ -1443,10 +1443,12 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc)
 
         /* set/clear over quota flag for a uid/gid */
         if (lustre_msg_get_opc(req->rq_reqmsg) == OST_WRITE &&
 
         /* set/clear over quota flag for a uid/gid */
         if (lustre_msg_get_opc(req->rq_reqmsg) == OST_WRITE &&
-            body->oa.o_valid & (OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA))
-                lquota_setdq(quota_interface, cli, body->oa.o_uid,
-                             body->oa.o_gid, body->oa.o_valid,
+            body->oa.o_valid & (OBD_MD_FLUSRQUOTA | OBD_MD_FLGRPQUOTA)) {
+                unsigned int qid[MAXQUOTAS] = { body->oa.o_uid, body->oa.o_gid };
+
+                lquota_setdq(quota_interface, cli, qid, body->oa.o_valid,
                              body->oa.o_flags);
                              body->oa.o_flags);
+        }
 
         if (rc < 0)
                 RETURN(rc);
 
         if (rc < 0)
                 RETURN(rc);
@@ -2826,6 +2828,7 @@ int osc_queue_async_io(const struct lu_env *env,
         if ((cmd & OBD_BRW_WRITE) && !(cmd & OBD_BRW_NOQUOTA)) {
                 struct cl_object *obj;
                 struct cl_attr    attr; /* XXX put attr into thread info */
         if ((cmd & OBD_BRW_WRITE) && !(cmd & OBD_BRW_NOQUOTA)) {
                 struct cl_object *obj;
                 struct cl_attr    attr; /* XXX put attr into thread info */
+                unsigned int qid[MAXQUOTAS];
 
                 obj = cl_object_top(osc_oap2cl_page(oap)->cp_obj);
 
 
                 obj = cl_object_top(osc_oap2cl_page(oap)->cp_obj);
 
@@ -2833,8 +2836,10 @@ int osc_queue_async_io(const struct lu_env *env,
                 rc = cl_object_attr_get(env, obj, &attr);
                 cl_object_attr_unlock(obj);
 
                 rc = cl_object_attr_get(env, obj, &attr);
                 cl_object_attr_unlock(obj);
 
-                if (rc == 0 && lquota_chkdq(quota_interface, cli, attr.cat_uid,
-                                            attr.cat_gid) == NO_QUOTA)
+                qid[USRQUOTA] = attr.cat_uid;
+                qid[GRPQUOTA] = attr.cat_gid;
+                if (rc == 0 &&
+                    lquota_chkdq(quota_interface, cli, qid) == NO_QUOTA)
                         rc = -EDQUOT;
                 if (rc)
                         RETURN(rc);
                         rc = -EDQUOT;
                 if (rc)
                         RETURN(rc);
index abe57dd..1c20d86 100644 (file)
@@ -313,7 +313,7 @@ int filter_quota_adjust_qunit(struct obd_export *exp,
                               struct lustre_quota_ctxt *qctxt)
 {
         struct obd_device *obd = exp->exp_obd;
                               struct lustre_quota_ctxt *qctxt)
 {
         struct obd_device *obd = exp->exp_obd;
-        unsigned int uid = 0, gid = 0;
+        unsigned int id[MAXQUOTAS] = { 0, 0 };
         int rc = 0;
         ENTRY;
 
         int rc = 0;
         ENTRY;
 
@@ -325,12 +325,12 @@ int filter_quota_adjust_qunit(struct obd_export *exp,
                 RETURN(rc);
         }
         if (QAQ_IS_GRP(oqaq))
                 RETURN(rc);
         }
         if (QAQ_IS_GRP(oqaq))
-                gid = oqaq->qaq_id;
+                id[GRPQUOTA] = oqaq->qaq_id;
         else
         else
-                uid = oqaq->qaq_id;
+                id[USRQUOTA] = oqaq->qaq_id;
 
         if (rc > 0) {
 
         if (rc > 0) {
-                rc = qctxt_adjust_qunit(obd, qctxt, uid, gid, 1, 0, NULL);
+                rc = qctxt_adjust_qunit(obd, qctxt, id, 1, 0, NULL);
                 if (rc == -EDQUOT || rc == -EBUSY ||
                     rc == QUOTA_REQ_RETURNED || rc == -EAGAIN) {
                         CDEBUG(D_QUOTA, "rc: %d.\n", rc);
                 if (rc == -EDQUOT || rc == -EBUSY ||
                     rc == QUOTA_REQ_RETURNED || rc == -EAGAIN) {
                         CDEBUG(D_QUOTA, "rc: %d.\n", rc);
index 82a5762..b5fef27 100644 (file)
@@ -1019,11 +1019,10 @@ wait_completion:
 
 int
 qctxt_adjust_qunit(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
 
 int
 qctxt_adjust_qunit(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
-                   uid_t uid, gid_t gid, __u32 isblk, int wait,
+                   const unsigned int id[], __u32 isblk, int wait,
                    struct obd_trans_info *oti)
 {
         int rc = 0, i = USRQUOTA;
                    struct obd_trans_info *oti)
 {
         int rc = 0, i = USRQUOTA;
-        __u32 id[MAXQUOTAS] = { uid, gid };
         struct qunit_data qdata[MAXQUOTAS];
         ENTRY;
 
         struct qunit_data qdata[MAXQUOTAS];
         ENTRY;
 
index ad4f9a4..a1961cf 100644 (file)
@@ -198,7 +198,7 @@ int filter_quota_ctl(struct obd_device *unused, struct obd_export *exp,
                 break;
         case Q_INITQUOTA:
                 {
                 break;
         case Q_INITQUOTA:
                 {
-                unsigned int uid = 0, gid = 0;
+                unsigned int id[MAXQUOTAS] = { 0, 0 };
 
                 /* Initialize quota limit to MIN_QLIMIT */
                 LASSERT(oqctl->qc_dqblk.dqb_valid == QIF_BLIMITS);
 
                 /* Initialize quota limit to MIN_QLIMIT */
                 LASSERT(oqctl->qc_dqblk.dqb_valid == QIF_BLIMITS);
@@ -231,12 +231,12 @@ int filter_quota_ctl(struct obd_device *unused, struct obd_export *exp,
 adjust:
                 /* Trigger qunit pre-acquire */
                 if (oqctl->qc_type == USRQUOTA)
 adjust:
                 /* Trigger qunit pre-acquire */
                 if (oqctl->qc_type == USRQUOTA)
-                        uid = oqctl->qc_id;
+                        id[USRQUOTA] = oqctl->qc_id;
                 else
                 else
-                        gid = oqctl->qc_id;
+                        id[GRPQUOTA] = oqctl->qc_id;
 
                 rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt,
 
                 rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt,
-                                        uid, gid, 1, 0, NULL);
+                                        id, 1, 0, NULL);
                 if (rc == -EDQUOT || rc == -EBUSY) {
                         CDEBUG(D_QUOTA, "rc: %d.\n", rc);
                         rc = 0;
                 if (rc == -EDQUOT || rc == -EBUSY) {
                         CDEBUG(D_QUOTA, "rc: %d.\n", rc);
                         rc = 0;
index 60d7038..dff4ce4 100644 (file)
@@ -252,13 +252,12 @@ static int filter_quota_getflag(struct obd_device *obd, struct obdo *oa)
  * check whether the left quota of certain uid and gid can satisfy a block_write
  * or inode_create rpc. When need to acquire quota, return QUOTA_RET_ACQUOTA
  */
  * check whether the left quota of certain uid and gid can satisfy a block_write
  * or inode_create rpc. When need to acquire quota, return QUOTA_RET_ACQUOTA
  */
-static int quota_check_common(struct obd_device *obd, unsigned int uid,
-                              unsigned int gid, int count, int cycle, int isblk,
-                              struct inode *inode, int frags, int *pending)
+static int quota_check_common(struct obd_device *obd, const unsigned int id[],
+                              int pending[], int count, int cycle, int isblk,
+                              struct inode *inode, int frags)
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         int i;
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         int i;
-        __u32 id[MAXQUOTAS] = { uid, gid };
         struct qunit_data qdata[MAXQUOTAS];
         int mb = 0;
         int rc = 0, rc2[2] = { 0, 0 };
         struct qunit_data qdata[MAXQUOTAS];
         int mb = 0;
         int rc = 0, rc2[2] = { 0, 0 };
@@ -292,16 +291,24 @@ static int quota_check_common(struct obd_device *obd, unsigned int uid,
                 if (!lqs)
                         continue;
 
                 if (!lqs)
                         continue;
 
+                if (IS_ERR(lqs)) {
+                        CERROR("can not find lqs for check_common: "
+                               "[id %u] [%c] [isblk %d] [count %d] [rc %ld]\n",
+                               id[i], i % 2 ? 'g': 'u', isblk, count,
+                               PTR_ERR(lqs));
+                        RETURN(PTR_ERR(lqs));
+                }
+
                 rc2[i] = compute_remquota(obd, qctxt, &qdata[i], isblk);
                 spin_lock(&lqs->lqs_lock);
                 if (!cycle) {
                         if (isblk) {
                 rc2[i] = compute_remquota(obd, qctxt, &qdata[i], isblk);
                 spin_lock(&lqs->lqs_lock);
                 if (!cycle) {
                         if (isblk) {
-                                *pending = count * CFS_PAGE_SIZE;
+                                pending[i] = count * CFS_PAGE_SIZE;
                                 /* in order to complete this write, we need extra
                                  * meta blocks. This function can get it through
                                  * data needed to be written b=16542 */
                                 if (inode) {
                                 /* in order to complete this write, we need extra
                                  * meta blocks. This function can get it through
                                  * data needed to be written b=16542 */
                                 if (inode) {
-                                        mb = *pending;
+                                        mb = pending[i];
                                         rc = fsfilt_get_mblk(obd, qctxt->lqc_sb,
                                                              &mb, inode,frags);
                                         if (rc)
                                         rc = fsfilt_get_mblk(obd, qctxt->lqc_sb,
                                                              &mb, inode,frags);
                                         if (rc)
@@ -309,12 +316,12 @@ static int quota_check_common(struct obd_device *obd, unsigned int uid,
                                                        "can't get extra "
                                                        "meta blocks.\n");
                                         else
                                                        "can't get extra "
                                                        "meta blocks.\n");
                                         else
-                                                *pending += mb;
+                                                pending[i] += mb;
                                 }
                                 }
-                                lqs->lqs_bwrite_pending += *pending;
+                                lqs->lqs_bwrite_pending += pending[i];
                         } else {
                         } else {
-                                *pending = count;
-                                lqs->lqs_iwrite_pending += *pending;
+                                pending[i] = count;
+                                lqs->lqs_iwrite_pending += pending[i];
                         }
                 }
 
                         }
                 }
 
@@ -335,11 +342,11 @@ static int quota_check_common(struct obd_device *obd, unsigned int uid,
                                 qdata[i].qd_count += lqs->lqs_ino_rec;
                 }
 
                                 qdata[i].qd_count += lqs->lqs_ino_rec;
                 }
 
-
-                CDEBUG(D_QUOTA, "count: %d, lqs pending: %lu, qd_count: "LPU64
-                       ", metablocks: %d, isblk: %d, pending: %d.\n", count,
+                CDEBUG(D_QUOTA, "[id %u] [%c] [isblk %d] [count %d]"
+                       " [lqs pending: %lu] [qd_count: "LPU64"] [metablocks: %d]"
+                       " [pending: %d]\n", id[i], i % 2 ? 'g': 'u', isblk, count,
                        isblk ? lqs->lqs_bwrite_pending : lqs->lqs_iwrite_pending,
                        isblk ? lqs->lqs_bwrite_pending : lqs->lqs_iwrite_pending,
-                       qdata[i].qd_count, mb, isblk, *pending);
+                       qdata[i].qd_count, mb, pending[i]);
                 if (rc2[i] == QUOTA_RET_OK) {
                         if (isblk && qdata[i].qd_count < lqs->lqs_bwrite_pending)
                                 rc2[i] = QUOTA_RET_ACQUOTA;
                 if (rc2[i] == QUOTA_RET_OK) {
                         if (isblk && qdata[i].qd_count < lqs->lqs_bwrite_pending)
                                 rc2[i] = QUOTA_RET_ACQUOTA;
@@ -371,9 +378,8 @@ static int quota_check_common(struct obd_device *obd, unsigned int uid,
                 RETURN(rc);
 }
 
                 RETURN(rc);
 }
 
-static int quota_chk_acq_common(struct obd_device *obd, unsigned int uid,
-                                unsigned int gid, int count, int *pending,
-                                quota_acquire acquire,
+static int quota_chk_acq_common(struct obd_device *obd, const unsigned int id[],
+                                int pending[], int count, quota_acquire acquire,
                                 struct obd_trans_info *oti, int isblk,
                                 struct inode *inode, int frags)
 {
                                 struct obd_trans_info *oti, int isblk,
                                 struct inode *inode, int frags)
 {
@@ -386,14 +392,14 @@ static int quota_chk_acq_common(struct obd_device *obd, unsigned int uid,
         ENTRY;
 
         CDEBUG(D_QUOTA, "check quota for %s\n", obd->obd_name);
         ENTRY;
 
         CDEBUG(D_QUOTA, "check quota for %s\n", obd->obd_name);
-        *pending = 0;
+        pending[USRQUOTA] = pending[GRPQUOTA] = 0;
         /* Unfortunately, if quota master is too busy to handle the
          * 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);
         /* Unfortunately, if quota master is too busy to handle the
          * 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,
-                                        inode, frags, pending)) &
+        while ((rc = quota_check_common(obd, id, pending, count, cycle, isblk,
+                                        inode, frags)) &
                QUOTA_RET_ACQUOTA) {
 
                 spin_lock(&qctxt->lqc_lock);
                QUOTA_RET_ACQUOTA) {
 
                 spin_lock(&qctxt->lqc_lock);
@@ -419,7 +425,7 @@ static int quota_chk_acq_common(struct obd_device *obd, unsigned int uid,
                         OBD_FAIL_TIMEOUT(OBD_FAIL_OST_HOLD_WRITE_RPC, 90);
                 /* after acquire(), we should run quota_check_common again
                  * so that we confirm there are enough quota to finish write */
                         OBD_FAIL_TIMEOUT(OBD_FAIL_OST_HOLD_WRITE_RPC, 90);
                 /* after acquire(), we should run quota_check_common again
                  * so that we confirm there are enough quota to finish write */
-                rc = acquire(obd, uid, gid, oti, isblk);
+                rc = acquire(obd, id, oti, isblk);
 
                 /* please reference to dqacq_completion for the below */
                 /* a new request is finished, try again */
 
                 /* please reference to dqacq_completion for the below */
                 /* a new request is finished, try again */
@@ -484,15 +490,14 @@ static int quota_chk_acq_common(struct obd_device *obd, unsigned int uid,
  * when a block_write or inode_create rpc is finished, adjust the record for
  * pending blocks and inodes
  */
  * when a block_write or inode_create rpc is finished, adjust the record for
  * pending blocks and inodes
  */
-static int quota_pending_commit(struct obd_device *obd, unsigned int uid,
-                                unsigned int gid, int pending, int isblk)
+static int quota_pending_commit(struct obd_device *obd, const unsigned int id[],
+                                int pending[], int isblk)
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         struct timeval work_start;
         struct timeval work_end;
         long timediff;
         int i;
 {
         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];
         ENTRY;
 
         struct qunit_data qdata[MAXQUOTAS];
         ENTRY;
 
@@ -505,6 +510,10 @@ static int quota_pending_commit(struct obd_device *obd, unsigned int uid,
         for (i = 0; i < MAXQUOTAS; i++) {
                 struct lustre_qunit_size *lqs = NULL;
 
         for (i = 0; i < MAXQUOTAS; i++) {
                 struct lustre_qunit_size *lqs = NULL;
 
+                LASSERT(pending[i] >= 0);
+                if (pending[i] == 0)
+                        continue;
+
                 qdata[i].qd_id = id[i];
                 qdata[i].qd_flags = i;
                 if (isblk)
                 qdata[i].qd_id = id[i];
                 qdata[i].qd_flags = i;
                 if (isblk)
@@ -515,41 +524,43 @@ static int quota_pending_commit(struct obd_device *obd, unsigned int uid,
                         continue;
 
                 quota_search_lqs(&qdata[i], NULL, qctxt, &lqs);
                         continue;
 
                 quota_search_lqs(&qdata[i], NULL, qctxt, &lqs);
-                if (lqs) {
-                        int flag = 0;
-                        spin_lock(&lqs->lqs_lock);
-                        if (isblk) {
-                                if (lqs->lqs_bwrite_pending >= pending) {
-                                        lqs->lqs_bwrite_pending -= pending;
-                                        spin_unlock(&lqs->lqs_lock);
-                                        flag = 1;
-                                } else {
-                                        spin_unlock(&lqs->lqs_lock);
-                                        CDEBUG(D_ERROR,
-                                               "there are too many blocks!\n");
-                                }
-                        } else {
-                                if (lqs->lqs_iwrite_pending >= pending) {
-                                        lqs->lqs_iwrite_pending -= pending;
-                                        spin_unlock(&lqs->lqs_lock);
-                                        flag = 1;
-                                } else {
-                                        spin_unlock(&lqs->lqs_lock);
-                                        CDEBUG(D_ERROR,
-                                               "there are too many files!\n");
-                                }
-                        }
-                        CDEBUG(D_QUOTA, "lqs pending: %lu, pending: %d, "
-                               "isblk: %d.\n",
-                               isblk ? lqs->lqs_bwrite_pending :
-                               lqs->lqs_iwrite_pending, pending, isblk);
+                if (lqs == NULL || IS_ERR(lqs)) {
+                        CERROR("can not find lqs for pending_commit: "
+                               "[id %u] [%c] [pending %u] [isblk %d] (rc %ld), "
+                               "maybe cause unexpected lqs refcount error!\n",
+                               id[i], i % 2 ? 'g': 'u', pending[i], isblk,
+                               lqs ? PTR_ERR(lqs) : -1);
+                        continue;
+                }
 
 
-                        lqs_putref(lqs);
-                        /* When lqs_*_pening is changed back, we'll putref lqs
-                         * here b=14784 */
-                        if (flag)
-                                lqs_putref(lqs);
+                spin_lock(&lqs->lqs_lock);
+                if (isblk) {
+                        LASSERTF(lqs->lqs_bwrite_pending >= pending[i],
+                                 "there are too many blocks! [id %u] [%c] "
+                                 "[bwrite_pending %lu] [pending %u]\n",
+                                 id[i], i % 2 ? 'g' : 'u',
+                                 lqs->lqs_bwrite_pending, pending[i]);
+
+                        lqs->lqs_bwrite_pending -= pending[i];
+                } else {
+                        LASSERTF(lqs->lqs_iwrite_pending >= pending[i],
+                                "there are too many files! [id %u] [%c] "
+                                "[iwrite_pending %lu] [pending %u]\n",
+                                id[i], i % 2 ? 'g' : 'u',
+                                lqs->lqs_iwrite_pending, pending[i]);
+
+                        lqs->lqs_iwrite_pending -= pending[i];
                 }
                 }
+                CDEBUG(D_QUOTA, "id: %u, %c, lqs pending: %lu, pending: %d, "
+                       "isblk: %d.\n", id[i], i % 2 ? 'g' : 'u',
+                       isblk ? lqs->lqs_bwrite_pending: lqs->lqs_iwrite_pending,
+                       pending[i], isblk);
+                spin_unlock(&lqs->lqs_lock);
+
+                /* for quota_search_lqs in pending_commit */
+                lqs_putref(lqs);
+                /* for quota_search_lqs in quota_check */
+                lqs_putref(lqs);
         }
         do_gettimeofday(&work_end);
         timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
         }
         do_gettimeofday(&work_end);
         timediff = cfs_timeval_sub(&work_end, &work_start, NULL);
@@ -643,15 +654,14 @@ static int mds_quota_fs_cleanup(struct obd_device *obd)
         RETURN(0);
 }
 
         RETURN(0);
 }
 
-static int quota_acquire_common(struct obd_device *obd, unsigned int uid,
-                                unsigned int gid, struct obd_trans_info *oti,
-                                int isblk)
+static int quota_acquire_common(struct obd_device *obd, const unsigned int id[],
+                                struct obd_trans_info *oti, int isblk)
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         int rc;
         ENTRY;
 
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         int rc;
         ENTRY;
 
-        rc = qctxt_adjust_qunit(obd, qctxt, uid, gid, isblk, 1, oti);
+        rc = qctxt_adjust_qunit(obd, qctxt, id, isblk, 1, oti);
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
@@ -738,7 +748,7 @@ static void free_qinfo(struct osc_quota_info *oqi)
         OBD_SLAB_FREE(oqi, qinfo_cachep, sizeof(*oqi));
 }
 
         OBD_SLAB_FREE(oqi, qinfo_cachep, sizeof(*oqi));
 }
 
-int osc_quota_chkdq(struct client_obd *cli, unsigned int uid, unsigned int gid)
+int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[])
 {
         unsigned int id;
         int cnt, rc = QUOTA_OK;
 {
         unsigned int id;
         int cnt, rc = QUOTA_OK;
@@ -748,7 +758,7 @@ int osc_quota_chkdq(struct client_obd *cli, unsigned int uid, unsigned int gid)
         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                 struct osc_quota_info *oqi = NULL;
 
         for (cnt = 0; cnt < MAXQUOTAS; cnt++) {
                 struct osc_quota_info *oqi = NULL;
 
-                id = (cnt == USRQUOTA) ? uid : gid;
+                id = (cnt == USRQUOTA) ? qid[USRQUOTA] : qid[GRPQUOTA];
                 oqi = find_qinfo(cli, id, cnt);
                 if (oqi) {
                         rc = NO_QUOTA;
                 oqi = find_qinfo(cli, id, cnt);
                 if (oqi) {
                         rc = NO_QUOTA;
@@ -760,7 +770,7 @@ int osc_quota_chkdq(struct client_obd *cli, unsigned int uid, unsigned int gid)
         RETURN(rc);
 }
 
         RETURN(rc);
 }
 
-int osc_quota_setdq(struct client_obd *cli, unsigned int uid, unsigned int gid,
+int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[],
                     obd_flag valid, obd_flag flags)
 {
         unsigned int id;
                     obd_flag valid, obd_flag flags)
 {
         unsigned int id;
@@ -776,7 +786,7 @@ int osc_quota_setdq(struct client_obd *cli, unsigned int uid, unsigned int gid,
                     OBD_MD_FLUSRQUOTA : OBD_MD_FLGRPQUOTA)))
                         continue;
 
                     OBD_MD_FLUSRQUOTA : OBD_MD_FLGRPQUOTA)))
                         continue;
 
-                id = (cnt == USRQUOTA) ? uid : gid;
+                id = (cnt == USRQUOTA) ? qid[USRQUOTA] : qid[GRPQUOTA];
                 noquota = (cnt == USRQUOTA) ?
                     (flags & OBD_FL_NO_USRQUOTA) : (flags & OBD_FL_NO_GRPQUOTA);
 
                 noquota = (cnt == USRQUOTA) ?
                     (flags & OBD_FL_NO_USRQUOTA) : (flags & OBD_FL_NO_GRPQUOTA);
 
index 8856af3..3d50ad5 100644 (file)
 void qunit_cache_cleanup(void);
 int qunit_cache_init(void);
 int qctxt_adjust_qunit(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
 void qunit_cache_cleanup(void);
 int qunit_cache_init(void);
 int qctxt_adjust_qunit(struct obd_device *obd, struct lustre_quota_ctxt *qctxt,
-                       uid_t uid, gid_t gid, __u32 isblk, int wait,
+                       const unsigned int id[], __u32 isblk, int wait,
                        struct obd_trans_info *oti);
 int qctxt_wait_pending_dqacq(struct lustre_quota_ctxt *qctxt, unsigned int id,
                              unsigned short type, int isblk);
                        struct obd_trans_info *oti);
 int qctxt_wait_pending_dqacq(struct lustre_quota_ctxt *qctxt, unsigned int id,
                              unsigned short type, int isblk);
@@ -118,10 +118,10 @@ void dqacq_interrupt(struct lustre_quota_ctxt *qctxt);
 int lustre_dquot_init(void);
 void lustre_dquot_exit(void);
 int dqacq_handler(struct obd_device *obd, struct qunit_data *qdata, int opc);
 int lustre_dquot_init(void);
 void lustre_dquot_exit(void);
 int dqacq_handler(struct obd_device *obd, struct qunit_data *qdata, int opc);
-int mds_quota_adjust(struct obd_device *obd, unsigned int qcids[],
-                     unsigned int qpids[], int rc, int opc);
-int filter_quota_adjust(struct obd_device *obd, unsigned int qcids[],
-                        unsigned int qpids[], int rc, int opc);
+int mds_quota_adjust(struct obd_device *obd, const unsigned int qcids[],
+                     const unsigned int qpids[], int rc, int opc);
+int filter_quota_adjust(struct obd_device *obd, const unsigned int qcids[],
+                        const unsigned int qpids[], int rc, int opc);
 int init_admin_quotafiles(struct obd_device *obd, struct obd_quotactl *oqctl);
 int mds_quota_get_version(struct obd_device *obd, lustre_quota_version_t *ver);
 int mds_quota_invalidate(struct obd_device *obd, struct obd_quotactl *oqctl);
 int init_admin_quotafiles(struct obd_device *obd, struct obd_quotactl *oqctl);
 int mds_quota_get_version(struct obd_device *obd, lustre_quota_version_t *ver);
 int mds_quota_invalidate(struct obd_device *obd, struct obd_quotactl *oqctl);
index 339a6c5..beb55df 100644 (file)
@@ -259,7 +259,7 @@ int dqacq_adjust_qunit_sz(struct obd_device *obd, qid_t id, int type,
         struct lov_obd *lov = &lov_mds_obd->u.lov;
         __u32 ost_num = lov->desc.ld_tgt_count, mdt_num = 1;
         struct quota_adjust_qunit *oqaq = NULL;
         struct lov_obd *lov = &lov_mds_obd->u.lov;
         __u32 ost_num = lov->desc.ld_tgt_count, mdt_num = 1;
         struct quota_adjust_qunit *oqaq = NULL;
-        unsigned int uid = 0, gid = 0;
+        unsigned int qid[MAXQUOTAS] = { 0, 0 };
         struct lustre_quota_info *info = &mds->mds_quota_info;
         struct lustre_dquot *dquot = NULL;
         int adjust_res = 0;
         struct lustre_quota_info *info = &mds->mds_quota_info;
         struct lustre_dquot *dquot = NULL;
         int adjust_res = 0;
@@ -305,13 +305,13 @@ int dqacq_adjust_qunit_sz(struct obd_device *obd, qid_t id, int type,
         }
 
         if (type)
         }
 
         if (type)
-                gid = dquot->dq_id;
+                qid[GRPQUOTA] = dquot->dq_id;
         else
         else
-                uid = dquot->dq_id;
+                qid[USRQUOTA] = dquot->dq_id;
 
         up(&dquot->dq_sem);
 
 
         up(&dquot->dq_sem);
 
-        rc = qctxt_adjust_qunit(obd, qctxt, uid, gid, is_blk, 0, NULL);
+        rc = qctxt_adjust_qunit(obd, qctxt, qid, is_blk, 0, NULL);
         if (rc == -EDQUOT || rc == -EBUSY) {
                 CDEBUG(D_QUOTA, "rc: %d.\n", rc);
                 rc = 0;
         if (rc == -EDQUOT || rc == -EBUSY) {
                 CDEBUG(D_QUOTA, "rc: %d.\n", rc);
                 rc = 0;
@@ -471,8 +471,8 @@ out:
         return rc;
 }
 
         return rc;
 }
 
-int mds_quota_adjust(struct obd_device *obd, unsigned int qcids[],
-                     unsigned int qpids[], int rc, int opc)
+int mds_quota_adjust(struct obd_device *obd, const unsigned int qcids[],
+                     const unsigned int qpids[], int rc, int opc)
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         int rc2 = 0;
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         int rc2 = 0;
@@ -484,67 +484,53 @@ int mds_quota_adjust(struct obd_device *obd, unsigned int qcids[],
         switch (opc) {
         case FSFILT_OP_SETATTR:
                 /* release file quota on original owner */
         switch (opc) {
         case FSFILT_OP_SETATTR:
                 /* release file quota on original owner */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 0, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 0, 0, NULL);
                 /* release block quota on original owner */
                 /* release block quota on original owner */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
                 /* acquire file quota on current owner */
                 /* acquire file quota on current owner */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
                 /* acquire block quota on current owner */
                 /* acquire block quota on current owner */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
                 break;
         case FSFILT_OP_UNLINK_PARTIAL_CHILD:
                 /* release file quota on child */
                 break;
         case FSFILT_OP_UNLINK_PARTIAL_CHILD:
                 /* release file quota on child */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
                 /* rlease block quota on child */
                 /* rlease block quota on child */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
                 break;
         case FSFILT_OP_CREATE_PARTIAL_CHILD:
                 /* acquire file quota on child */
                 break;
         case FSFILT_OP_CREATE_PARTIAL_CHILD:
                 /* acquire file quota on child */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
                 /* acquire block quota on child */
                 /* acquire block quota on child */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
                 break;
         case FSFILT_OP_LINK:
                 /* acquire block quota on parent */
                 break;
         case FSFILT_OP_LINK:
                 /* acquire block quota on parent */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
                 break;
         case FSFILT_OP_UNLINK:
                 /* release block quota on parent */
                 break;
         case FSFILT_OP_UNLINK:
                 /* release block quota on parent */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
                 /* release file quota on child */
                 /* release file quota on child */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
                 if (qpids[0] != qcids[0] || qpids[1] != qcids[1])
                         /* release block quota on child */
                 if (qpids[0] != qcids[0] || qpids[1] != qcids[1])
                         /* release block quota on child */
-                        rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0],
-                                                  qcids[1], 1, 0, NULL);
+                        rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0,
+                                                  NULL);
                 break;
         case FSFILT_OP_UNLINK_PARTIAL_PARENT:
                 /* release block quota on parent */
                 break;
         case FSFILT_OP_UNLINK_PARTIAL_PARENT:
                 /* release block quota on parent */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
                 break;
         case FSFILT_OP_CREATE:
                 /* acquire block quota on parent */
                 break;
         case FSFILT_OP_CREATE:
                 /* acquire block quota on parent */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
                 /* acquire file quota on child */
                 /* acquire file quota on child */
-                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 0, 0,
-                                          NULL);
+                rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 0, 0, NULL);
                 if (qpids[0] != qcids[0] || qpids[1] != qcids[1])
                         /* acquire block quota on child */
                 if (qpids[0] != qcids[0] || qpids[1] != qcids[1])
                         /* acquire block quota on child */
-                        rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids[0],
-                                                  qcids[1], 1, 0, NULL);
+                        rc2 |= qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0,
+                                                  NULL);
                 break;
         default:
                 LBUG();
                 break;
         default:
                 LBUG();
@@ -558,8 +544,8 @@ int mds_quota_adjust(struct obd_device *obd, unsigned int qcids[],
         RETURN(0);
 }
 
         RETURN(0);
 }
 
-int filter_quota_adjust(struct obd_device *obd, unsigned int qcids[],
-                        unsigned int qpids[], int rc, int opc)
+int filter_quota_adjust(struct obd_device *obd, const unsigned int qcids[],
+                        const unsigned int qpids[], int rc, int opc)
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         int rc2 = 0;
 {
         struct lustre_quota_ctxt *qctxt = &obd->u.obt.obt_qctxt;
         int rc2 = 0;
@@ -571,17 +557,14 @@ int filter_quota_adjust(struct obd_device *obd, unsigned int qcids[],
         switch (opc) {
         case FSFILT_OP_SETATTR:
                 /* acquire/release block quota on original & current owner */
         switch (opc) {
         case FSFILT_OP_SETATTR:
                 /* acquire/release block quota on original & current owner */
-                rc = qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
-                                        NULL);
-                rc2 = qctxt_adjust_qunit(obd, qctxt, qpids[0], qpids[1], 1, 0,
-                                         NULL);
+                rc = qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
+                rc2 = qctxt_adjust_qunit(obd, qctxt, qpids, 1, 0, NULL);
                 break;
         case FSFILT_OP_UNLINK:
                 /* release block quota on this owner */
         case FSFILT_OP_CREATE: /* XXX for write operation on obdfilter */
                 /* acquire block quota on this owner */
                 break;
         case FSFILT_OP_UNLINK:
                 /* release block quota on this owner */
         case FSFILT_OP_CREATE: /* XXX for write operation on obdfilter */
                 /* acquire block quota on this owner */
-                rc = qctxt_adjust_qunit(obd, qctxt, qcids[0], qcids[1], 1, 0,
-                                        NULL);
+                rc = qctxt_adjust_qunit(obd, qctxt, qcids, 1, 0, NULL);
                 break;
         default:
                 LBUG();
                 break;
         default:
                 LBUG();
@@ -1019,14 +1002,14 @@ int dquot_create_oqaq(struct lustre_quota_ctxt *qctxt,
 
         if ((type & LQUOTA_FLAGS_ADJBLK) && blimit) {
                 __u64 b_limitation =
 
         if ((type & LQUOTA_FLAGS_ADJBLK) && blimit) {
                 __u64 b_limitation =
-                        oqaq->qaq_bunit_sz * ost_num * shrink_qunit_limit;
+                        oqaq->qaq_bunit_sz * (ost_num + 1) * shrink_qunit_limit;
                 /* enlarge block qunit size */
                 while (blimit >
                        QUSG(dquot->dq_dqb.dqb_curspace + 2 * b_limitation, 1)) {
                         oqaq->qaq_bunit_sz =
                                 QUSG(oqaq->qaq_bunit_sz * cqs_factor, 1)
                                 << QUOTABLOCK_BITS;
                 /* enlarge block qunit size */
                 while (blimit >
                        QUSG(dquot->dq_dqb.dqb_curspace + 2 * b_limitation, 1)) {
                         oqaq->qaq_bunit_sz =
                                 QUSG(oqaq->qaq_bunit_sz * cqs_factor, 1)
                                 << QUOTABLOCK_BITS;
-                        b_limitation = oqaq->qaq_bunit_sz * ost_num *
+                        b_limitation = oqaq->qaq_bunit_sz * (ost_num + 1) *
                                 shrink_qunit_limit;
                 }
 
                                 shrink_qunit_limit;
                 }
 
@@ -1039,7 +1022,7 @@ int dquot_create_oqaq(struct lustre_quota_ctxt *qctxt,
                         do_div(oqaq->qaq_bunit_sz , cqs_factor);
                         oqaq->qaq_bunit_sz = QUSG(oqaq->qaq_bunit_sz, 1) <<
                                 QUOTABLOCK_BITS;
                         do_div(oqaq->qaq_bunit_sz , cqs_factor);
                         oqaq->qaq_bunit_sz = QUSG(oqaq->qaq_bunit_sz, 1) <<
                                 QUOTABLOCK_BITS;
-                        b_limitation = oqaq->qaq_bunit_sz * ost_num *
+                        b_limitation = oqaq->qaq_bunit_sz * (ost_num + 1) *
                                 shrink_qunit_limit;
                         if (oqaq->qaq_bunit_sz <  qctxt->lqc_cqs_least_bunit)
                                 break;
                                 shrink_qunit_limit;
                         if (oqaq->qaq_bunit_sz <  qctxt->lqc_cqs_least_bunit)
                                 break;
@@ -1105,7 +1088,7 @@ static int mds_init_slave_ilimits(struct obd_device *obd,
         /* XXX: for file limits only adjust local now */
         struct obd_device_target *obt = &obd->u.obt;
         struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt;
         /* XXX: for file limits only adjust local now */
         struct obd_device_target *obt = &obd->u.obt;
         struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt;
-        unsigned int uid = 0, gid = 0;
+        unsigned int id[MAXQUOTAS] = { 0, 0 };
         struct obd_quotactl *ioqc = NULL;
         int flag;
         int rc;
         struct obd_quotactl *ioqc = NULL;
         int flag;
         int rc;
@@ -1143,12 +1126,11 @@ static int mds_init_slave_ilimits(struct obd_device *obd,
 
         /* trigger local qunit pre-acquire */
         if (oqctl->qc_type == USRQUOTA)
 
         /* trigger local qunit pre-acquire */
         if (oqctl->qc_type == USRQUOTA)
-                uid = oqctl->qc_id;
+                id[USRQUOTA] = oqctl->qc_id;
         else
         else
-                gid = oqctl->qc_id;
+                id[GRPQUOTA] = oqctl->qc_id;
 
 
-        rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, uid, gid, 0, 0,
-                                NULL);
+        rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, id, 0, 0, NULL);
         if (rc == -EDQUOT || rc == -EBUSY) {
                 CDEBUG(D_QUOTA, "rc: %d.\n", rc);
                 rc = 0;
         if (rc == -EDQUOT || rc == -EBUSY) {
                 CDEBUG(D_QUOTA, "rc: %d.\n", rc);
                 rc = 0;
@@ -1174,7 +1156,7 @@ static int mds_init_slave_blimits(struct obd_device *obd,
         struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt;
         struct mds_obd *mds = &obd->u.mds;
         struct obd_quotactl *ioqc;
         struct lustre_quota_ctxt *qctxt = &obt->obt_qctxt;
         struct mds_obd *mds = &obd->u.mds;
         struct obd_quotactl *ioqc;
-        unsigned int uid = 0, gid = 0;
+        unsigned int id[MAXQUOTAS] = { 0, 0 };
         int rc, rc1 = 0;
         int flag;
         ENTRY;
         int rc, rc1 = 0;
         int flag;
         ENTRY;
@@ -1209,15 +1191,14 @@ static int mds_init_slave_blimits(struct obd_device *obd,
 
         /* trigger local qunit pre-acquire */
         if (oqctl->qc_type == USRQUOTA)
 
         /* trigger local qunit pre-acquire */
         if (oqctl->qc_type == USRQUOTA)
-                uid = oqctl->qc_id;
+                id[USRQUOTA] = oqctl->qc_id;
         else
         else
-                gid = oqctl->qc_id;
+                id[GRPQUOTA] = oqctl->qc_id;
 
         /* initialize all slave's limit */
         rc = obd_quotactl(mds->mds_osc_exp, ioqc);
 
 
         /* initialize all slave's limit */
         rc = obd_quotactl(mds->mds_osc_exp, ioqc);
 
-        rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, uid, gid, 1, 0,
-                                NULL);
+        rc = qctxt_adjust_qunit(obd, &obd->u.obt.obt_qctxt, id, 1, 0, NULL);
         if (rc == -EDQUOT || rc == -EBUSY) {
                 CDEBUG(D_QUOTA, "rc: %d.\n", rc);
                 rc = 0;
         if (rc == -EDQUOT || rc == -EBUSY) {
                 CDEBUG(D_QUOTA, "rc: %d.\n", rc);
                 rc = 0;