From: fanyong Date: Thu, 28 May 2009 11:15:45 +0000 (+0000) Subject: Branch HEAD X-Git-Tag: v1_9_0_200~60 X-Git-Url: https://git.whamcloud.com/gitweb?a=commitdiff_plain;h=6dc53dbb70e05edeb40ca021b7d3df1203560147;p=fs%2Flustre-release.git Branch HEAD b=19447 i=tianzy i=andrew.perepechko Separate user and group pending when quota check/commit. --- diff --git a/lustre/include/lustre_quota.h b/lustre/include/lustre_quota.h index b4a2314..6f0105a 100644 --- a/lustre/include/lustre_quota.h +++ b/lustre/include/lustre_quota.h @@ -412,9 +412,8 @@ struct quotacheck_thread_args { }; 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); @@ -434,8 +433,8 @@ typedef struct { /** * 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, @@ -462,7 +461,7 @@ typedef struct { /** * 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); /** @@ -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 */ - 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 */ - 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 /** @@ -490,12 +489,12 @@ typedef struct { /** * 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 */ - int (*quota_setdq) (struct client_obd *, unsigned int, unsigned int, + int (*quota_setdq) (struct client_obd *, const unsigned int [], 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, - unsigned int qcids[], - unsigned int qpids[], + const unsigned int qcids[], + const unsigned int qpids[], 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, - 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); - 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, - 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); - rc = QUOTA_OP(interface, setdq)(cli, uid, gid, valid, flags); + rc = QUOTA_OP(interface, setdq)(cli, qid, valid, flags); 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, - 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; @@ -720,7 +717,7 @@ static inline int lquota_chkquota(quota_interface_t *interface, 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); @@ -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, - 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); - rc = QUOTA_OP(interface, pending_commit)(obd, uid, gid, pending, isblk); + rc = QUOTA_OP(interface, pending_commit)(obd, id, pending, isblk); RETURN(rc); } #endif diff --git a/lustre/mdd/mdd_dir.c b/lustre/mdd/mdd_dir.c index fde65cd..d051c90 100644 --- a/lustre/mdd/mdd_dir.c +++ b/lustre/mdd/mdd_dir.c @@ -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 }; - int quota_opc = 0, rec_pending = 0; + int quota_opc = 0, rec_pending[MAXQUOTAS] = { 0, 0 }; #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, - qids[USRQUOTA], qids[GRPQUOTA], 1, - &rec_pending, NULL, LQUOTA_FLAGS_BLK, - data, 1); + qids, rec_pending, 1, NULL, + LQUOTA_FLAGS_BLK, data, 1); } } #endif @@ -738,10 +737,8 @@ out_trans: 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, @@ -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 }; - 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; @@ -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, - qids[USRQUOTA], qids[GRPQUOTA], - 1, &rec_pending, NULL, + qids, rec_pending, 1, NULL, LQUOTA_FLAGS_BLK, data, 1); } } else { @@ -1027,11 +1023,8 @@ out_pending: #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, @@ -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 }; - int quota_opc = 0, rec_pending = 0; + int quota_copc = 0, quota_popc = 0; + int rec_pending[MAXQUOTAS] = { 0, 0 }; #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); - 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, - qpids[USRQUOTA], qpids[GRPQUOTA], 1, - &rec_pending, NULL, LQUOTA_FLAGS_BLK, - data, 1); + qpids, rec_pending, 1, NULL, + LQUOTA_FLAGS_BLK, data, 1); } } #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) { - quota_opc = FSFILT_OP_UNLINK_PARTIAL_CHILD; + quota_copc = FSFILT_OP_UNLINK_PARTIAL_CHILD; mdd_quota_wrapper(&ma->ma_attr, qcids); } #endif @@ -1292,17 +1285,16 @@ out_trans: out_pending: #ifdef HAVE_QUOTA_SUPPORT if (mds->mds_quota) { - if (rec_pending) + if (quota_popc) 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. */ - 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; @@ -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; - 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; @@ -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 */ - 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: @@ -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, - 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, - qpids[USRQUOTA], qpids[GRPQUOTA], 1, - &parent_pending, NULL, + qpids, parent_pending, 1, NULL, LQUOTA_FLAGS_BLK, NULL, 0); } } @@ -1852,18 +1843,12 @@ out_free: 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, @@ -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 }; - int quota_opc = 0, rec_pending = 0; + int quota_copc = 0, quota_popc = 0; + int rec_pending[MAXQUOTAS] = { 0, 0 }; #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); - 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, - obd, qtpids[USRQUOTA], - qtpids[GRPQUOTA], 1, - &rec_pending, NULL, + obd, qtpids, + rec_pending, 1, NULL, 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) { - quota_opc = FSFILT_OP_UNLINK_PARTIAL_CHILD; + quota_copc = FSFILT_OP_UNLINK_PARTIAL_CHILD; mdd_quota_wrapper(&ma->ma_attr, qtcids); } #endif @@ -2230,22 +2215,23 @@ cleanup_unlocked: out_pending: #ifdef HAVE_QUOTA_SUPPORT if (mds->mds_quota) { - if (rec_pending) + if (quota_popc) 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, - qtpids, rc, quota_opc); + qtpids, rc, quota_copc); + } } #endif return rc; diff --git a/lustre/mdd/mdd_internal.h b/lustre/mdd/mdd_internal.h index 9b657e1..fc67d61 100644 --- a/lustre/mdd/mdd_internal.h +++ b/lustre/mdd/mdd_internal.h @@ -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) { - qids[0] = la->la_uid; - qids[1] = la->la_gid; + qids[USRQUOTA] = la->la_uid; + qids[GRPQUOTA] = la->la_gid; } #endif diff --git a/lustre/mdd/mdd_object.c b/lustre/mdd/mdd_object.c index 1b1ae53..79166fc 100644 --- a/lustre/mdd/mdd_object.c +++ b/lustre/mdd/mdd_object.c @@ -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; - int inode_pending = 0, block_pending = 0; + int inode_pending[MAXQUOTAS] = { 0, 0 }; + int block_pending[MAXQUOTAS] = { 0, 0 }; #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 */ - 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, - 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) { - 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. */ @@ -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; - int inode_pending = 0, block_pending = 0; + int inode_pending[MAXQUOTAS] = { 0, 0 }; + int block_pending[MAXQUOTAS] = { 0, 0 }; #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 */ - 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: @@ -1605,9 +1599,8 @@ static int mdd_object_create(const struct lu_env *env, } /* 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 @@ -1675,18 +1668,14 @@ unlock: 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, - FSFILT_OP_CREATE_PARTIAL_CHILD); + quota_opc); } #endif return rc; diff --git a/lustre/obdfilter/filter_io_26.c b/lustre/obdfilter/filter_io_26.c index 3bd68f6..a45d9da 100644 --- a/lustre/obdfilter/filter_io_26.c +++ b/lustre/obdfilter/filter_io_26.c @@ -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; - 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); @@ -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 */ - 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)) @@ -731,9 +731,8 @@ int filter_commitrw_write(struct obd_export *exp, struct obdo *oa, 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); diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index e46a635..0a3bacd 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -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 && - 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); + } 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 */ + unsigned int qid[MAXQUOTAS]; 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); - 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); diff --git a/lustre/quota/quota_adjust_qunit.c b/lustre/quota/quota_adjust_qunit.c index abe57dd..1c20d86 100644 --- a/lustre/quota/quota_adjust_qunit.c +++ b/lustre/quota/quota_adjust_qunit.c @@ -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; - unsigned int uid = 0, gid = 0; + unsigned int id[MAXQUOTAS] = { 0, 0 }; int rc = 0; ENTRY; @@ -325,12 +325,12 @@ int filter_quota_adjust_qunit(struct obd_export *exp, RETURN(rc); } if (QAQ_IS_GRP(oqaq)) - gid = oqaq->qaq_id; + id[GRPQUOTA] = oqaq->qaq_id; else - uid = oqaq->qaq_id; + id[USRQUOTA] = oqaq->qaq_id; 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); diff --git a/lustre/quota/quota_context.c b/lustre/quota/quota_context.c index 82a5762..b5fef27 100644 --- a/lustre/quota/quota_context.c +++ b/lustre/quota/quota_context.c @@ -1019,11 +1019,10 @@ wait_completion: 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; - __u32 id[MAXQUOTAS] = { uid, gid }; struct qunit_data qdata[MAXQUOTAS]; ENTRY; diff --git a/lustre/quota/quota_ctl.c b/lustre/quota/quota_ctl.c index ad4f9a4..a1961cf 100644 --- a/lustre/quota/quota_ctl.c +++ b/lustre/quota/quota_ctl.c @@ -198,7 +198,7 @@ int filter_quota_ctl(struct obd_device *unused, struct obd_export *exp, 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); @@ -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) - uid = oqctl->qc_id; + id[USRQUOTA] = oqctl->qc_id; else - gid = oqctl->qc_id; + id[GRPQUOTA] = oqctl->qc_id; 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; diff --git a/lustre/quota/quota_interface.c b/lustre/quota/quota_interface.c index 60d7038..dff4ce4 100644 --- a/lustre/quota/quota_interface.c +++ b/lustre/quota/quota_interface.c @@ -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 */ -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; - __u32 id[MAXQUOTAS] = { uid, gid }; 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 (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) { - *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) { - mb = *pending; + mb = pending[i]; 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 - *pending += mb; + pending[i] += mb; } - lqs->lqs_bwrite_pending += *pending; + lqs->lqs_bwrite_pending += pending[i]; } 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; } - - 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, - 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; @@ -371,9 +378,8 @@ static int quota_check_common(struct obd_device *obd, unsigned int uid, 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) { @@ -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); - *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); - 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); @@ -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 */ - 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 */ @@ -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 */ -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; - __u32 id[MAXQUOTAS] = { uid, gid }; 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; + LASSERT(pending[i] >= 0); + if (pending[i] == 0) + continue; + 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); - 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); @@ -643,15 +654,14 @@ static int mds_quota_fs_cleanup(struct obd_device *obd) 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; - rc = qctxt_adjust_qunit(obd, qctxt, uid, gid, isblk, 1, oti); + rc = qctxt_adjust_qunit(obd, qctxt, id, isblk, 1, oti); RETURN(rc); } @@ -738,7 +748,7 @@ static void free_qinfo(struct osc_quota_info *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; @@ -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; - id = (cnt == USRQUOTA) ? uid : gid; + id = (cnt == USRQUOTA) ? qid[USRQUOTA] : qid[GRPQUOTA]; 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); } -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; @@ -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; - 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); diff --git a/lustre/quota/quota_internal.h b/lustre/quota/quota_internal.h index 8856af3..3d50ad5 100644 --- a/lustre/quota/quota_internal.h +++ b/lustre/quota/quota_internal.h @@ -101,7 +101,7 @@ 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); @@ -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 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); diff --git a/lustre/quota/quota_master.c b/lustre/quota/quota_master.c index 339a6c5..beb55df 100644 --- a/lustre/quota/quota_master.c +++ b/lustre/quota/quota_master.c @@ -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; - 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; @@ -305,13 +305,13 @@ int dqacq_adjust_qunit_sz(struct obd_device *obd, qid_t id, int type, } if (type) - gid = dquot->dq_id; + qid[GRPQUOTA] = dquot->dq_id; else - uid = dquot->dq_id; + qid[USRQUOTA] = dquot->dq_id; 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; @@ -471,8 +471,8 @@ out: 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; @@ -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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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 */ - 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(); @@ -558,8 +544,8 @@ int mds_quota_adjust(struct obd_device *obd, unsigned int qcids[], 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; @@ -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 */ - 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 */ - 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(); @@ -1019,14 +1002,14 @@ int dquot_create_oqaq(struct lustre_quota_ctxt *qctxt, 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; - b_limitation = oqaq->qaq_bunit_sz * ost_num * + b_limitation = oqaq->qaq_bunit_sz * (ost_num + 1) * 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; - 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; @@ -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; - unsigned int uid = 0, gid = 0; + unsigned int id[MAXQUOTAS] = { 0, 0 }; 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) - uid = oqctl->qc_id; + id[USRQUOTA] = oqctl->qc_id; 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; @@ -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; - unsigned int uid = 0, gid = 0; + unsigned int id[MAXQUOTAS] = { 0, 0 }; 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) - uid = oqctl->qc_id; + id[USRQUOTA] = oqctl->qc_id; else - gid = oqctl->qc_id; + id[GRPQUOTA] = oqctl->qc_id; /* 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;