};
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);
/**
* 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, 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);
/**
* 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
/**
/**
* 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);
/**
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;
}
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);
}
#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;
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);
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
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;
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
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,
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;
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 {
#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,
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;
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
#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
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;
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;
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:
/* 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);
}
}
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,
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;
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);
}
#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
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;
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
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;
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);
}
}
}
}
#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. */
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;
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:
}
/* 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
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;
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);
/* 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))
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);
/* 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);
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);
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);
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;
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);
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;
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);
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;
* 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 };
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)
"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];
}
}
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;
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)
{
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);
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 */
* 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;
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)
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);
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);
}
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;
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;
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_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);
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);
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);
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;
}
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;
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;
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();
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;
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();
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;
}
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;
/* 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;
/* 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;
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;
/* 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;