From 046a965cf0f54265208e74566d181f1ee9a3a729 Mon Sep 17 00:00:00 2001 From: Johann Lombardi Date: Fri, 30 Sep 2011 06:12:59 -0700 Subject: [PATCH] LU-847 quota: move lmv/mdc/osc/lov quota code out of lquota All quota code was initially put into a separate kernel module since quota might be released under a different license. That's not relevant any more and we can now move the client-side quota code back to the regular lustre modules. This removes useless indirections and makes the code easier to read and to maintain. Change-Id: If898a46db9158edb8e4eaf855f1ed98db97330f0 Signed-off-by: Niu Yawei Signed-off-by: Johann Lombardi Reviewed-on: http://review.whamcloud.com/1613 Tested-by: Hudson Reviewed-by: Fan Yong Tested-by: Maloo --- lustre/include/lustre_quota.h | 40 ---- lustre/liblustre/lutil.c | 8 - lustre/lmv/lmv_obd.c | 96 ++++++++-- lustre/lov/lov_obd.c | 160 ++++++++++++++++ lustre/mdc/mdc_request.c | 102 ++++++++-- lustre/osc/Makefile.in | 2 +- lustre/osc/autoMakefile.am | 5 +- lustre/osc/osc_internal.h | 15 ++ lustre/osc/osc_quota.c | 378 ++++++++++++++++++++++++++++++++++++++ lustre/osc/osc_request.c | 31 +--- lustre/quota/quota_adjust_qunit.c | 90 --------- lustre/quota/quota_check.c | 137 -------------- lustre/quota/quota_ctl.c | 167 ----------------- lustre/quota/quota_interface.c | 265 -------------------------- 14 files changed, 734 insertions(+), 762 deletions(-) create mode 100644 lustre/osc/osc_quota.c diff --git a/lustre/include/lustre_quota.h b/lustre/include/lustre_quota.h index c1941d7..345f44b 100644 --- a/lustre/include/lustre_quota.h +++ b/lustre/include/lustre_quota.h @@ -657,41 +657,6 @@ static inline int lquota_adjust(quota_interface_t *interface, RETURN(ret); } -static inline int lquota_chkdq(quota_interface_t *interface, - struct client_obd *cli, const unsigned int qid[]) -{ - int rc; - ENTRY; - - QUOTA_CHECK_OP(interface, chkdq); - rc = QUOTA_OP(interface, chkdq)(cli, qid); - RETURN(rc); -} - -static inline int lquota_setdq(quota_interface_t *interface, - 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, qid, valid, flags); - RETURN(rc); -} - -static inline int lquota_poll_check(quota_interface_t *interface, - struct obd_export *exp, - struct if_quotacheck *qchk) -{ - int rc; - ENTRY; - - QUOTA_CHECK_OP(interface, poll_check); - rc = QUOTA_OP(interface, poll_check)(exp, qchk); - RETURN(rc); -} - static inline int lquota_setinfo(quota_interface_t *interface, struct obd_device *obd, void *data) @@ -773,11 +738,6 @@ static inline int lquota_pending_commit(quota_interface_t *interface, #endif #ifndef __KERNEL__ -extern quota_interface_t osc_quota_interface; -extern quota_interface_t lov_quota_interface; -extern quota_interface_t mdc_quota_interface; -extern quota_interface_t lmv_quota_interface; - #ifndef MAXQUOTAS #define MAXQUOTAS 2 #endif diff --git a/lustre/liblustre/lutil.c b/lustre/liblustre/lutil.c index dead71b..b312841 100644 --- a/lustre/liblustre/lutil.c +++ b/lustre/liblustre/lutil.c @@ -77,14 +77,6 @@ void *inter_module_get(char *arg) return ldlm_namespace_cleanup; else if (!strcmp(arg, "ldlm_replay_locks")) return ldlm_replay_locks; - else if (!strcmp(arg, "mdc_quota_interface")) - return &mdc_quota_interface; - else if (!strcmp(arg, "lmv_quota_interface")) - return &lmv_quota_interface; - else if (!strcmp(arg, "osc_quota_interface")) - return &osc_quota_interface; - else if (!strcmp(arg, "lov_quota_interface")) - return &lov_quota_interface; else return NULL; } diff --git a/lustre/lmv/lmv_obd.c b/lustre/lmv/lmv_obd.c index 88ffcc1..daefddd 100644 --- a/lustre/lmv/lmv_obd.c +++ b/lustre/lmv/lmv_obd.c @@ -3097,6 +3097,83 @@ int lmv_revalidate_lock(struct obd_export *exp, struct lookup_intent *it, RETURN(rc); } +/** + * For lmv, only need to send request to master MDT, and the master MDT will + * process with other slave MDTs. The only exception is Q_GETOQUOTA for which + * we directly fetch data from the slave MDTs. + */ +int lmv_quotactl(struct obd_device *unused, struct obd_export *exp, + struct obd_quotactl *oqctl) +{ + struct obd_device *obd = class_exp2obd(exp); + struct lmv_obd *lmv = &obd->u.lmv; + struct lmv_tgt_desc *tgt = &lmv->tgts[0]; + int rc = 0, i; + __u64 curspace, curinodes; + ENTRY; + + if (!lmv->desc.ld_tgt_count || !tgt->ltd_active) { + CERROR("master lmv inactive\n"); + RETURN(-EIO); + } + + if (oqctl->qc_cmd != Q_GETOQUOTA) { + rc = obd_quotactl(tgt->ltd_exp, oqctl); + RETURN(rc); + } + + curspace = curinodes = 0; + for (i = 0; i < lmv->desc.ld_tgt_count; i++) { + int err; + tgt = &lmv->tgts[i]; + + if (tgt->ltd_exp == NULL) + continue; + if (!tgt->ltd_active) { + CDEBUG(D_HA, "mdt %d is inactive.\n", i); + continue; + } + + err = obd_quotactl(tgt->ltd_exp, oqctl); + if (err) { + CERROR("getquota on mdt %d failed. %d\n", i, err); + if (!rc) + rc = err; + } else { + curspace += oqctl->qc_dqblk.dqb_curspace; + curinodes += oqctl->qc_dqblk.dqb_curinodes; + } + } + oqctl->qc_dqblk.dqb_curspace = curspace; + oqctl->qc_dqblk.dqb_curinodes = curinodes; + + RETURN(rc); +} + +int lmv_quotacheck(struct obd_device *unused, struct obd_export *exp, + struct obd_quotactl *oqctl) +{ + struct obd_device *obd = class_exp2obd(exp); + struct lmv_obd *lmv = &obd->u.lmv; + struct lmv_tgt_desc *tgt; + int i, rc = 0; + ENTRY; + + for (i = 0, tgt = lmv->tgts; i < lmv->desc.ld_tgt_count; i++, tgt++) { + int err; + + if (!tgt->ltd_active) { + CERROR("lmv idx %d inactive\n", i); + RETURN(-EIO); + } + + err = obd_quotacheck(tgt->ltd_exp, oqctl); + if (err && !rc) + rc = err; + } + + RETURN(rc); +} struct obd_ops lmv_obd_ops = { .o_owner = THIS_MODULE, @@ -3114,7 +3191,9 @@ struct obd_ops lmv_obd_ops = { .o_notify = lmv_notify, .o_get_uuid = lmv_get_uuid, .o_iocontrol = lmv_iocontrol, - .o_fid_delete = lmv_fid_delete + .o_fid_delete = lmv_fid_delete, + .o_quotacheck = lmv_quotacheck, + .o_quotactl = lmv_quotactl }; struct md_ops lmv_md_ops = { @@ -3151,9 +3230,6 @@ struct md_ops lmv_md_ops = { .m_revalidate_lock = lmv_revalidate_lock }; -static quota_interface_t *quota_interface; -extern quota_interface_t lmv_quota_interface; - int __init lmv_init(void) { struct lprocfs_static_vars lvars; @@ -3169,17 +3245,10 @@ int __init lmv_init(void) lprocfs_lmv_init_vars(&lvars); - cfs_request_module("lquota"); - quota_interface = PORTAL_SYMBOL_GET(lmv_quota_interface); - init_obd_quota_ops(quota_interface, &lmv_obd_ops); - rc = class_register_type(&lmv_obd_ops, &lmv_md_ops, lvars.module_vars, LUSTRE_LMV_NAME, NULL); - if (rc) { - if (quota_interface) - PORTAL_SYMBOL_PUT(lmv_quota_interface); + if (rc) cfs_mem_cache_destroy(lmv_object_cache); - } return rc; } @@ -3187,9 +3256,6 @@ int __init lmv_init(void) #ifdef __KERNEL__ static void lmv_exit(void) { - if (quota_interface) - PORTAL_SYMBOL_PUT(lmv_quota_interface); - class_unregister_type(LUSTRE_LMV_NAME); LASSERTF(cfs_atomic_read(&lmv_object_count) == 0, diff --git a/lustre/lov/lov_obd.c b/lustre/lov/lov_obd.c index a70e64a..ed9f2b0 100644 --- a/lustre/lov/lov_obd.c +++ b/lustre/lov/lov_obd.c @@ -2827,6 +2827,163 @@ void lov_stripe_unlock(struct lov_stripe_md *md) } EXPORT_SYMBOL(lov_stripe_unlock); +static int lov_quotactl(struct obd_device *obd, struct obd_export *exp, + struct obd_quotactl *oqctl) +{ + struct lov_obd *lov = &obd->u.lov; + struct lov_tgt_desc *tgt; + __u64 curspace = 0; + __u64 bhardlimit = 0; + int i, rc = 0; + ENTRY; + + if (oqctl->qc_cmd != LUSTRE_Q_QUOTAON && + oqctl->qc_cmd != LUSTRE_Q_QUOTAOFF && + oqctl->qc_cmd != Q_GETOQUOTA && + oqctl->qc_cmd != Q_INITQUOTA && + oqctl->qc_cmd != LUSTRE_Q_SETQUOTA && + oqctl->qc_cmd != Q_FINVALIDATE) { + CERROR("bad quota opc %x for lov obd", oqctl->qc_cmd); + RETURN(-EFAULT); + } + + /* for lov tgt */ + obd_getref(obd); + for (i = 0; i < lov->desc.ld_tgt_count; i++) { + int err; + + tgt = lov->lov_tgts[i]; + + if (!tgt) + continue; + + if (!tgt->ltd_active || tgt->ltd_reap) { + if (oqctl->qc_cmd == Q_GETOQUOTA && + lov->lov_tgts[i]->ltd_activate) { + rc = -EREMOTEIO; + CERROR("ost %d is inactive\n", i); + } else { + CDEBUG(D_HA, "ost %d is inactive\n", i); + } + continue; + } + + err = obd_quotactl(tgt->ltd_exp, oqctl); + if (err) { + if (tgt->ltd_active && !rc) + rc = err; + continue; + } + + if (oqctl->qc_cmd == Q_GETOQUOTA) { + curspace += oqctl->qc_dqblk.dqb_curspace; + bhardlimit += oqctl->qc_dqblk.dqb_bhardlimit; + } + } + obd_putref(obd); + + if (oqctl->qc_cmd == Q_GETOQUOTA) { + oqctl->qc_dqblk.dqb_curspace = curspace; + oqctl->qc_dqblk.dqb_bhardlimit = bhardlimit; + } + RETURN(rc); +} + +static int lov_quotacheck(struct obd_device *obd, struct obd_export *exp, + struct obd_quotactl *oqctl) +{ + struct lov_obd *lov = &obd->u.lov; + int i, rc = 0; + ENTRY; + + obd_getref(obd); + + for (i = 0; i < lov->desc.ld_tgt_count; i++) { + if (!lov->lov_tgts[i]) + continue; + + /* Skip quota check on the administratively disabled OSTs. */ + if (!lov->lov_tgts[i]->ltd_activate) { + CWARN("lov idx %d was administratively disabled, " + "skip quotacheck on it.\n", i); + continue; + } + + if (!lov->lov_tgts[i]->ltd_active) { + CERROR("lov idx %d inactive\n", i); + rc = -EIO; + goto out; + } + } + + for (i = 0; i < lov->desc.ld_tgt_count; i++) { + int err; + + if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_activate) + continue; + + err = obd_quotacheck(lov->lov_tgts[i]->ltd_exp, oqctl); + if (err && !rc) + rc = err; + } + +out: + obd_putref(obd); + + RETURN(rc); +} + +int lov_quota_adjust_qunit(struct obd_export *exp, + struct quota_adjust_qunit *oqaq, + struct lustre_quota_ctxt *qctxt, + struct ptlrpc_request_set *rqset) +{ + struct obd_device *obd = class_exp2obd(exp); + struct lov_obd *lov = &obd->u.lov; + int i, err, rc = 0; + unsigned no_set = 0; + ENTRY; + + if (!QAQ_IS_ADJBLK(oqaq)) { + CERROR("bad qaq_flags %x for lov obd.\n", oqaq->qaq_flags); + RETURN(-EFAULT); + } + + if (rqset == NULL) { + rqset = ptlrpc_prep_set(); + if (!rqset) + RETURN(-ENOMEM); + no_set = 1; + } + + obd_getref(obd); + for (i = 0; i < lov->desc.ld_tgt_count; i++) { + + if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) { + CDEBUG(D_HA, "ost %d is inactive\n", i); + continue; + } + + err = obd_quota_adjust_qunit(lov->lov_tgts[i]->ltd_exp, oqaq, + NULL, rqset); + if (err) { + if (lov->lov_tgts[i]->ltd_active && !rc) + rc = err; + continue; + } + } + + err = ptlrpc_set_wait(rqset); + if (!rc) + rc = err; + + /* Destroy the set if none was provided by the caller */ + if (no_set) + ptlrpc_set_destroy(rqset); + + obd_putref(obd); + RETURN(rc); +} struct obd_ops lov_obd_ops = { .o_owner = THIS_MODULE, @@ -2869,6 +3026,9 @@ struct obd_ops lov_obd_ops = { .o_pool_del = lov_pool_del, .o_getref = lov_getref, .o_putref = lov_putref, + .o_quotactl = lov_quotactl, + .o_quotacheck = lov_quotacheck, + .o_quota_adjust_qunit = lov_quota_adjust_qunit, }; static quota_interface_t *quota_interface; diff --git a/lustre/mdc/mdc_request.c b/lustre/mdc/mdc_request.c index be881f7..834f013 100644 --- a/lustre/mdc/mdc_request.c +++ b/lustre/mdc/mdc_request.c @@ -68,9 +68,6 @@ struct mdc_renew_capa_args { renew_capa_cb_t ra_cb; }; -static quota_interface_t *quota_interface; -extern quota_interface_t mdc_quota_interface; - static int mdc_cleanup(struct obd_device *obd); int mdc_unpack_capa(struct obd_export *exp, struct ptlrpc_request *req, @@ -1362,6 +1359,90 @@ static int mdc_ioc_changelog_send(struct obd_device *obd, static int mdc_ioc_hsm_ct_start(struct obd_export *exp, struct lustre_kernelcomm *lk); +static int mdc_quotacheck(struct obd_device *unused, struct obd_export *exp, + struct obd_quotactl *oqctl) +{ + struct client_obd *cli = &exp->exp_obd->u.cli; + struct ptlrpc_request *req; + struct obd_quotactl *body; + int rc; + ENTRY; + + req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), + &RQF_MDS_QUOTACHECK, LUSTRE_MDS_VERSION, + MDS_QUOTACHECK); + if (req == NULL) + RETURN(-ENOMEM); + + body = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL); + *body = *oqctl; + + ptlrpc_request_set_replen(req); + + /* the next poll will find -ENODATA, that means quotacheck is + * going on */ + cli->cl_qchk_stat = -ENODATA; + rc = ptlrpc_queue_wait(req); + if (rc) + cli->cl_qchk_stat = rc; + ptlrpc_req_finished(req); + RETURN(rc); +} + +static int mdc_quota_poll_check(struct obd_export *exp, + struct if_quotacheck *qchk) +{ + struct client_obd *cli = &exp->exp_obd->u.cli; + int rc; + ENTRY; + + qchk->obd_uuid = cli->cl_target_uuid; + memcpy(qchk->obd_type, LUSTRE_MDS_NAME, strlen(LUSTRE_MDS_NAME)); + + rc = cli->cl_qchk_stat; + /* the client is not the previous one */ + if (rc == CL_NOT_QUOTACHECKED) + rc = -EINTR; + RETURN(rc); +} + +static int mdc_quotactl(struct obd_device *unused, struct obd_export *exp, + struct obd_quotactl *oqctl) +{ + struct ptlrpc_request *req; + struct obd_quotactl *oqc; + int rc; + ENTRY; + + req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), + &RQF_MDS_QUOTACTL, LUSTRE_MDS_VERSION, + MDS_QUOTACTL); + if (req == NULL) + RETURN(-ENOMEM); + + oqc = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL); + *oqc = *oqctl; + + ptlrpc_request_set_replen(req); + ptlrpc_at_set_req_timeout(req); + req->rq_no_resend = 1; + + rc = ptlrpc_queue_wait(req); + if (rc) + CERROR("ptlrpc_queue_wait failed, rc: %d\n", rc); + + if (req->rq_repmsg && + (oqc = req_capsule_server_get(&req->rq_pill, &RMF_OBD_QUOTACTL))) { + *oqctl = *oqc; + } else if (!rc) { + CERROR ("Can't unpack obd_quotactl\n"); + rc = -EPROTO; + } + ptlrpc_req_finished(req); + + RETURN(rc); +} + static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, void *karg, void *uarg) { @@ -1420,8 +1501,7 @@ static int mdc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, } #endif case OBD_IOC_POLL_QUOTACHECK: - rc = lquota_poll_check(quota_interface, exp, - (struct if_quotacheck *)karg); + rc = mdc_quota_poll_check(exp, (struct if_quotacheck *)karg); GOTO(out, rc); case OBD_IOC_PING_TARGET: rc = ptlrpc_obd_ping(obd); @@ -2303,6 +2383,8 @@ struct obd_ops mdc_obd_ops = { .o_get_info = mdc_get_info, .o_process_config = mdc_process_config, .o_get_uuid = mdc_get_uuid, + .o_quotactl = mdc_quotactl, + .o_quotacheck = mdc_quotacheck }; struct md_ops mdc_md_ops = { @@ -2346,24 +2428,14 @@ int __init mdc_init(void) struct lprocfs_static_vars lvars = { 0 }; lprocfs_mdc_init_vars(&lvars); - cfs_request_module("lquota"); - quota_interface = PORTAL_SYMBOL_GET(mdc_quota_interface); - init_obd_quota_ops(quota_interface, &mdc_obd_ops); - rc = class_register_type(&mdc_obd_ops, &mdc_md_ops, lvars.module_vars, LUSTRE_MDC_NAME, NULL); - if (rc && quota_interface) - PORTAL_SYMBOL_PUT(mdc_quota_interface); - RETURN(rc); } #ifdef __KERNEL__ static void /*__exit*/ mdc_exit(void) { - if (quota_interface) - PORTAL_SYMBOL_PUT(mdc_quota_interface); - class_unregister_type(LUSTRE_MDC_NAME); } diff --git a/lustre/osc/Makefile.in b/lustre/osc/Makefile.in index 40ffa16..34d6c6e 100644 --- a/lustre/osc/Makefile.in +++ b/lustre/osc/Makefile.in @@ -1,5 +1,5 @@ MODULES := osc -osc-objs := osc_request.o lproc_osc.o osc_create.o osc_dev.o osc_object.o osc_page.o osc_lock.o osc_io.o +osc-objs := osc_request.o lproc_osc.o osc_create.o osc_dev.o osc_object.o osc_page.o osc_lock.o osc_io.o osc_quota.o EXTRA_DIST = $(osc-objs:%.o=%.c) osc_internal.h osc_cl_internal.h diff --git a/lustre/osc/autoMakefile.am b/lustre/osc/autoMakefile.am index 9f6b33e..19c45a4 100644 --- a/lustre/osc/autoMakefile.am +++ b/lustre/osc/autoMakefile.am @@ -36,7 +36,7 @@ if LIBLUSTRE noinst_LIBRARIES = libosc.a -libosc_a_SOURCES = osc_request.c osc_create.c osc_internal.h osc_cl_internal.h osc_dev.c osc_object.c osc_page.c osc_lock.c osc_io.c +libosc_a_SOURCES = osc_request.c osc_create.c osc_internal.h osc_cl_internal.h osc_dev.c osc_object.c osc_page.c osc_lock.c osc_io.c osc_quota.c libosc_a_CPPFLAGS = $(LLCPPFLAGS) libosc_a_CFLAGS = $(LLCFLAGS) @@ -58,7 +58,8 @@ osc_SOURCES := \ osc_page.c \ osc_lock.c \ osc_io.c \ - osc_request.c + osc_request.c \ + osc_quota.c osc_CFLAGS := $(EXTRA_KCFLAGS) osc_LDFLAGS := $(EXTRA_KLDFLAGS) diff --git a/lustre/osc/osc_internal.h b/lustre/osc/osc_internal.h index 9b11a9d..8e79f7a 100644 --- a/lustre/osc/osc_internal.h +++ b/lustre/osc/osc_internal.h @@ -224,4 +224,19 @@ static inline struct osc_device *obd2osc_dev(const struct obd_device *d) int osc_dlm_lock_pageref(struct ldlm_lock *dlm); +int osc_quota_init(void); +int osc_quota_exit(void); +int osc_quota_cleanup(struct obd_device *obd); +int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], + obd_flag valid, obd_flag flags); +int osc_quota_chkdq(struct client_obd *cli, const unsigned int qid[]); +int osc_quotactl(struct obd_device *unused, struct obd_export *exp, + struct obd_quotactl *oqctl); +int osc_quotacheck(struct obd_device *unused, struct obd_export *exp, + struct obd_quotactl *oqctl); +int osc_quota_poll_check(struct obd_export *exp, struct if_quotacheck *qchk); +int osc_quota_adjust_qunit(struct obd_export *exp, + struct quota_adjust_qunit *oqaq, + struct lustre_quota_ctxt *qctxt, + struct ptlrpc_request_set *rqset); #endif /* OSC_INTERNAL_H */ diff --git a/lustre/osc/osc_quota.c b/lustre/osc/osc_quota.c new file mode 100644 index 0000000..69a9306 --- /dev/null +++ b/lustre/osc/osc_quota.c @@ -0,0 +1,378 @@ +/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*- + * vim:expandtab:shiftwidth=8:tabstop=8: + * + * GPL HEADER START + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 only, + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License version 2 for more details (a copy is included + * in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 021110-1307, USA + * + * GPL HEADER END + */ +/* + * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011 Whamcloud, Inc. + * + * Code originally extracted from quota directory + */ +#ifndef __KERNEL__ +# include +#endif + +#include +#include "osc_internal.h" + +struct osc_quota_info { + cfs_list_t oqi_hash; /* hash list */ + struct client_obd *oqi_cli; /* osc obd */ + unsigned int oqi_id; /* uid/gid of a file */ + short oqi_type; /* quota type */ +}; + +cfs_spinlock_t qinfo_list_lock = CFS_SPIN_LOCK_UNLOCKED; + +static cfs_list_t qinfo_hash[NR_DQHASH]; +/* SLAB cache for client quota context */ +cfs_mem_cache_t *qinfo_cachep = NULL; + +static inline int hashfn(struct client_obd *cli, unsigned long id, int type) + __attribute__((__const__)); + +static inline int hashfn(struct client_obd *cli, unsigned long id, int type) +{ + unsigned long tmp = ((unsigned long)cli>>6) ^ id; + tmp = (tmp * (MAXQUOTAS - type)) % NR_DQHASH; + return tmp; +} + +/* caller must hold qinfo_list_lock */ +static inline void insert_qinfo_hash(struct osc_quota_info *oqi) +{ + cfs_list_t *head = qinfo_hash + + hashfn(oqi->oqi_cli, oqi->oqi_id, oqi->oqi_type); + + LASSERT_SPIN_LOCKED(&qinfo_list_lock); + cfs_list_add(&oqi->oqi_hash, head); +} + +/* caller must hold qinfo_list_lock */ +static inline void remove_qinfo_hash(struct osc_quota_info *oqi) +{ + LASSERT_SPIN_LOCKED(&qinfo_list_lock); + cfs_list_del_init(&oqi->oqi_hash); +} + +/* caller must hold qinfo_list_lock */ +static inline struct osc_quota_info *find_qinfo(struct client_obd *cli, + unsigned int id, int type) +{ + struct osc_quota_info *oqi; + unsigned int hashent = hashfn(cli, id, type); + ENTRY; + + LASSERT_SPIN_LOCKED(&qinfo_list_lock); + cfs_list_for_each_entry(oqi, &qinfo_hash[hashent], oqi_hash) { + if (oqi->oqi_cli == cli && + oqi->oqi_id == id && oqi->oqi_type == type) + RETURN(oqi); + } + RETURN(NULL); +} + +static struct osc_quota_info *alloc_qinfo(struct client_obd *cli, + unsigned int id, int type) +{ + struct osc_quota_info *oqi; + ENTRY; + + OBD_SLAB_ALLOC(oqi, qinfo_cachep, CFS_ALLOC_IO, sizeof(*oqi)); + if(!oqi) + RETURN(NULL); + + CFS_INIT_LIST_HEAD(&oqi->oqi_hash); + oqi->oqi_cli = cli; + oqi->oqi_id = id; + oqi->oqi_type = type; + + RETURN(oqi); +} + +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, const unsigned int qid[]) +{ + unsigned int id; + int cnt, rc = QUOTA_OK; + ENTRY; + + cfs_spin_lock(&qinfo_list_lock); + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + struct osc_quota_info *oqi = NULL; + + id = (cnt == USRQUOTA) ? qid[USRQUOTA] : qid[GRPQUOTA]; + oqi = find_qinfo(cli, id, cnt); + if (oqi) { + rc = NO_QUOTA; + break; + } + } + cfs_spin_unlock(&qinfo_list_lock); + + if (rc == NO_QUOTA) + CDEBUG(D_QUOTA, "chkdq found noquota for %s %d\n", + cnt == USRQUOTA ? "user" : "group", id); + RETURN(rc); +} + +int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], + obd_flag valid, obd_flag flags) +{ + unsigned int id; + obd_flag noquota; + int cnt, rc = 0; + ENTRY; + + for (cnt = 0; cnt < MAXQUOTAS; cnt++) { + struct osc_quota_info *oqi = NULL, *old; + + if (!(valid & ((cnt == USRQUOTA) ? + OBD_MD_FLUSRQUOTA : OBD_MD_FLGRPQUOTA))) + continue; + + id = (cnt == USRQUOTA) ? qid[USRQUOTA] : qid[GRPQUOTA]; + noquota = (cnt == USRQUOTA) ? + (flags & OBD_FL_NO_USRQUOTA) : (flags & OBD_FL_NO_GRPQUOTA); + + if (noquota) { + oqi = alloc_qinfo(cli, id, cnt); + if (!oqi) { + rc = -ENOMEM; + CDEBUG(D_QUOTA, "setdq for %s %d failed, " + "(rc = %d)\n", + cnt == USRQUOTA ? "user" : "group", + id, rc); + break; + } + } + + cfs_spin_lock(&qinfo_list_lock); + old = find_qinfo(cli, id, cnt); + if (old && !noquota) + remove_qinfo_hash(old); + else if (!old && noquota) + insert_qinfo_hash(oqi); + cfs_spin_unlock(&qinfo_list_lock); + + if (old && !noquota) + CDEBUG(D_QUOTA, "setdq to remove for %s %d\n", + cnt == USRQUOTA ? "user" : "group", id); + else if (!old && noquota) + CDEBUG(D_QUOTA, "setdq to insert for %s %d\n", + cnt == USRQUOTA ? "user" : "group", id); + + if (old) { + if (noquota) + free_qinfo(oqi); + else + free_qinfo(old); + } + } + RETURN(rc); +} + +int osc_quota_cleanup(struct obd_device *obd) +{ + struct client_obd *cli = &obd->u.cli; + struct osc_quota_info *oqi, *n; + int i; + ENTRY; + + cfs_spin_lock(&qinfo_list_lock); + for (i = 0; i < NR_DQHASH; i++) { + cfs_list_for_each_entry_safe(oqi, n, &qinfo_hash[i], oqi_hash) { + if (oqi->oqi_cli != cli) + continue; + remove_qinfo_hash(oqi); + free_qinfo(oqi); + } + } + cfs_spin_unlock(&qinfo_list_lock); + + RETURN(0); +} + +int osc_quota_init() +{ + int i; + ENTRY; + + LASSERT(qinfo_cachep == NULL); + qinfo_cachep = cfs_mem_cache_create("osc_quota_info", + sizeof(struct osc_quota_info), + 0, 0); + if (!qinfo_cachep) + RETURN(-ENOMEM); + + for (i = 0; i < NR_DQHASH; i++) + CFS_INIT_LIST_HEAD(qinfo_hash + i); + + RETURN(0); +} + +int osc_quota_exit() +{ + struct osc_quota_info *oqi, *n; + int i, rc; + ENTRY; + + cfs_spin_lock(&qinfo_list_lock); + for (i = 0; i < NR_DQHASH; i++) { + cfs_list_for_each_entry_safe(oqi, n, &qinfo_hash[i], oqi_hash) { + remove_qinfo_hash(oqi); + free_qinfo(oqi); + } + } + cfs_spin_unlock(&qinfo_list_lock); + + rc = cfs_mem_cache_destroy(qinfo_cachep); + LASSERTF(rc == 0, "couldn't destory qinfo_cachep slab\n"); + qinfo_cachep = NULL; + + RETURN(0); +} + +int osc_quotactl(struct obd_device *unused, struct obd_export *exp, + struct obd_quotactl *oqctl) +{ + struct ptlrpc_request *req; + struct obd_quotactl *oqc; + int rc; + ENTRY; + + req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), + &RQF_OST_QUOTACTL, LUSTRE_OST_VERSION, + OST_QUOTACTL); + if (req == NULL) + RETURN(-ENOMEM); + + oqc = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL); + *oqc = *oqctl; + + ptlrpc_request_set_replen(req); + ptlrpc_at_set_req_timeout(req); + req->rq_no_resend = 1; + + rc = ptlrpc_queue_wait(req); + if (rc) + CERROR("ptlrpc_queue_wait failed, rc: %d\n", rc); + + if (req->rq_repmsg && + (oqc = req_capsule_server_get(&req->rq_pill, &RMF_OBD_QUOTACTL))) { + *oqctl = *oqc; + } else if (!rc) { + CERROR ("Can't unpack obd_quotactl\n"); + rc = -EPROTO; + } + ptlrpc_req_finished(req); + + RETURN(rc); +} + +int osc_quotacheck(struct obd_device *unused, struct obd_export *exp, + struct obd_quotactl *oqctl) +{ + struct client_obd *cli = &exp->exp_obd->u.cli; + struct ptlrpc_request *req; + struct obd_quotactl *body; + int rc; + ENTRY; + + req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), + &RQF_OST_QUOTACHECK, LUSTRE_OST_VERSION, + OST_QUOTACHECK); + if (req == NULL) + RETURN(-ENOMEM); + + body = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL); + *body = *oqctl; + + ptlrpc_request_set_replen(req); + + /* the next poll will find -ENODATA, that means quotacheck is + * going on */ + cli->cl_qchk_stat = -ENODATA; + rc = ptlrpc_queue_wait(req); + if (rc) + cli->cl_qchk_stat = rc; + ptlrpc_req_finished(req); + RETURN(rc); +} + +int osc_quota_poll_check(struct obd_export *exp, struct if_quotacheck *qchk) +{ + struct client_obd *cli = &exp->exp_obd->u.cli; + int rc; + ENTRY; + + qchk->obd_uuid = cli->cl_target_uuid; + memcpy(qchk->obd_type, LUSTRE_OST_NAME, strlen(LUSTRE_OST_NAME)); + + rc = cli->cl_qchk_stat; + /* the client is not the previous one */ + if (rc == CL_NOT_QUOTACHECKED) + rc = -EINTR; + RETURN(rc); +} + +int osc_quota_adjust_qunit(struct obd_export *exp, + struct quota_adjust_qunit *oqaq, + struct lustre_quota_ctxt *qctxt, + struct ptlrpc_request_set *rqset) +{ + struct ptlrpc_request *req; + struct quota_adjust_qunit *oqa; + int rc = 0; + ENTRY; + + /* client don't support this kind of operation, abort it */ + if (!(exp->exp_connect_flags & OBD_CONNECT_CHANGE_QS)) { + CDEBUG(D_QUOTA, "osc: %s don't support change qunit size\n", + exp->exp_obd->obd_name); + RETURN(rc); + } + if (strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_OSC_NAME)) + RETURN(-EINVAL); + + LASSERT(rqset); + + req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), + &RQF_OST_QUOTA_ADJUST_QUNIT, + LUSTRE_OST_VERSION, + OST_QUOTA_ADJUST_QUNIT); + if (req == NULL) + RETURN(-ENOMEM); + + oqa = req_capsule_client_get(&req->rq_pill, &RMF_QUOTA_ADJUST_QUNIT); + *oqa = *oqaq; + + ptlrpc_request_set_replen(req); + + ptlrpc_set_add_req(rqset, req); + RETURN(rc); +} diff --git a/lustre/osc/osc_request.c b/lustre/osc/osc_request.c index f213c09..f4f2c7a 100644 --- a/lustre/osc/osc_request.c +++ b/lustre/osc/osc_request.c @@ -66,9 +66,6 @@ #include #include "osc_internal.h" -static quota_interface_t *quota_interface = NULL; -extern quota_interface_t osc_quota_interface; - static void osc_release_ppga(struct brw_page **ppga, obd_count count); static int brw_interpret(const struct lu_env *env, struct ptlrpc_request *req, void *data, int rc); @@ -1542,7 +1539,6 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) RETURN(-EPROTO); } -#ifdef HAVE_QUOTA_SUPPORT /* 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)) { @@ -1551,10 +1547,8 @@ static int osc_brw_fini_request(struct ptlrpc_request *req, int rc) CDEBUG(D_QUOTA, "setdq for [%u %u] with valid "LPX64", flags %x\n", body->oa.o_uid, body->oa.o_gid, body->oa.o_valid, body->oa.o_flags); - lquota_setdq(quota_interface, cli, qid, body->oa.o_valid, - body->oa.o_flags); + osc_quota_setdq(cli, qid, body->oa.o_valid, body->oa.o_flags); } -#endif osc_update_grant(cli, body); @@ -2978,7 +2972,7 @@ int osc_queue_async_io(const struct lu_env *env, struct obd_export *exp, qid[USRQUOTA] = attr.cat_uid; qid[GRPQUOTA] = attr.cat_gid; if (rc == 0 && - lquota_chkdq(quota_interface, cli, qid) == NO_QUOTA) + osc_quota_chkdq(cli, qid) == NO_QUOTA) rc = -EDQUOT; if (rc) RETURN(rc); @@ -3860,8 +3854,7 @@ static int osc_iocontrol(unsigned int cmd, struct obd_export *exp, int len, data->ioc_offset); GOTO(out, err); case OBD_IOC_POLL_QUOTACHECK: - err = lquota_poll_check(quota_interface, exp, - (struct if_quotacheck *)karg); + err = osc_quota_poll_check(exp, (struct if_quotacheck *)karg); GOTO(out, err); case OBD_IOC_PING_TARGET: err = ptlrpc_obd_ping(obd); @@ -4511,7 +4504,7 @@ int osc_cleanup(struct obd_device *obd) ENTRY; /* free memory of osc quota cache */ - lquota_cleanup(quota_interface, obd); + osc_quota_cleanup(obd); rc = client_obd_cleanup(obd); @@ -4580,6 +4573,9 @@ struct obd_ops osc_obd_ops = { .o_llog_init = osc_llog_init, .o_llog_finish = osc_llog_finish, .o_process_config = osc_process_config, + .o_quotactl = osc_quotactl, + .o_quotacheck = osc_quotacheck, + .o_quota_adjust_qunit = osc_quota_adjust_qunit, }; extern struct lu_kmem_descr osc_caches[]; @@ -4601,16 +4597,10 @@ int __init osc_init(void) lprocfs_osc_init_vars(&lvars); - cfs_request_module("lquota"); - quota_interface = PORTAL_SYMBOL_GET(osc_quota_interface); - lquota_init(quota_interface); - init_obd_quota_ops(quota_interface, &osc_obd_ops); - + osc_quota_init(); rc = class_register_type(&osc_obd_ops, NULL, lvars.module_vars, LUSTRE_OSC_NAME, &osc_device_type); if (rc) { - if (quota_interface) - PORTAL_SYMBOL_PUT(osc_quota_interface); lu_kmem_fini(osc_caches); RETURN(rc); } @@ -4632,10 +4622,7 @@ static void /*__exit*/ osc_exit(void) { lu_device_type_fini(&osc_device_type); - lquota_exit(quota_interface); - if (quota_interface) - PORTAL_SYMBOL_PUT(osc_quota_interface); - + osc_quota_exit(); class_unregister_type(LUSTRE_OSC_NAME); lu_kmem_fini(osc_caches); } diff --git a/lustre/quota/quota_adjust_qunit.c b/lustre/quota/quota_adjust_qunit.c index 45f8c38..3c64f69 100644 --- a/lustre/quota/quota_adjust_qunit.c +++ b/lustre/quota/quota_adjust_qunit.c @@ -285,93 +285,3 @@ int filter_quota_adjust_qunit(struct obd_export *exp, } #endif /* __KERNEL__ */ #endif - -int client_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - struct ptlrpc_request_set *rqset) -{ - struct ptlrpc_request *req; - struct quota_adjust_qunit *oqa; - int rc = 0; - ENTRY; - - /* client don't support this kind of operation, abort it */ - if (!(exp->exp_connect_flags & OBD_CONNECT_CHANGE_QS)) { - CDEBUG(D_QUOTA, "osc: %s don't support change qunit size\n", - exp->exp_obd->obd_name); - RETURN(rc); - } - if (strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_OSC_NAME)) - RETURN(-EINVAL); - - LASSERT(rqset); - - req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), - &RQF_OST_QUOTA_ADJUST_QUNIT, - LUSTRE_OST_VERSION, - OST_QUOTA_ADJUST_QUNIT); - if (req == NULL) - RETURN(-ENOMEM); - - oqa = req_capsule_client_get(&req->rq_pill, &RMF_QUOTA_ADJUST_QUNIT); - *oqa = *oqaq; - - ptlrpc_request_set_replen(req); - - ptlrpc_set_add_req(rqset, req); - RETURN (rc); -} - -int lov_quota_adjust_qunit(struct obd_export *exp, - struct quota_adjust_qunit *oqaq, - struct lustre_quota_ctxt *qctxt, - struct ptlrpc_request_set *rqset) -{ - struct obd_device *obd = class_exp2obd(exp); - struct lov_obd *lov = &obd->u.lov; - int i, err, rc = 0; - unsigned no_set = 0; - ENTRY; - - if (!QAQ_IS_ADJBLK(oqaq)) { - CERROR("bad qaq_flags %x for lov obd.\n", oqaq->qaq_flags); - RETURN(-EFAULT); - } - - - if (rqset == NULL) { - rqset = ptlrpc_prep_set(); - if (!rqset) - RETURN(-ENOMEM); - no_set = 1; - } - - obd_getref(obd); - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - - if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active) { - CDEBUG(D_HA, "ost %d is inactive\n", i); - continue; - } - - err = obd_quota_adjust_qunit(lov->lov_tgts[i]->ltd_exp, oqaq, - NULL, rqset); - if (err) { - if (lov->lov_tgts[i]->ltd_active && !rc) - rc = err; - continue; - } - } - - err = ptlrpc_set_wait(rqset); - if (!rc) - rc = err; - - /* Destroy the set if none was provided by the caller */ - if (no_set) - ptlrpc_set_destroy(rqset); - - obd_putref(obd); - RETURN(rc); -} diff --git a/lustre/quota/quota_check.c b/lustre/quota/quota_check.c index 599ea4c..51b11ef 100644 --- a/lustre/quota/quota_check.c +++ b/lustre/quota/quota_check.c @@ -197,140 +197,3 @@ out: #endif /* __KERNEL__ */ #endif /* HAVE_QUOTA_SUPPORT */ - -int client_quota_check(struct obd_device *unused, struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct client_obd *cli = &exp->exp_obd->u.cli; - struct ptlrpc_request *req; - struct obd_quotactl *body; - const struct req_format *rf; - int ver, opc, rc; - ENTRY; - - if (!strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_MDC_NAME)) { - rf = &RQF_MDS_QUOTACHECK; - ver = LUSTRE_MDS_VERSION; - opc = MDS_QUOTACHECK; - } else if (!strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_OSC_NAME)) { - rf = &RQF_OST_QUOTACHECK; - ver = LUSTRE_OST_VERSION; - opc = OST_QUOTACHECK; - } else { - RETURN(-EINVAL); - } - - req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), rf, ver, opc); - if (req == NULL) - RETURN(-ENOMEM); - - body = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL); - *body = *oqctl; - - ptlrpc_request_set_replen(req); - - /* the next poll will find -ENODATA, that means quotacheck is - * going on */ - cli->cl_qchk_stat = -ENODATA; - rc = ptlrpc_queue_wait(req); - if (rc) - cli->cl_qchk_stat = rc; - ptlrpc_req_finished(req); - RETURN(rc); -} - -int client_quota_poll_check(struct obd_export *exp, struct if_quotacheck *qchk) -{ - struct client_obd *cli = &exp->exp_obd->u.cli; - int rc; - ENTRY; - - rc = cli->cl_qchk_stat; - - /* the client is not the previous one */ - if (rc == CL_NOT_QUOTACHECKED) - rc = -EINTR; - - qchk->obd_uuid = cli->cl_target_uuid; - /* FIXME change strncmp to strcmp and save the strlen op */ - if (strncmp(exp->exp_obd->obd_type->typ_name, LUSTRE_OSC_NAME, - strlen(LUSTRE_OSC_NAME)) == 0) - memcpy(qchk->obd_type, LUSTRE_OST_NAME, - strlen(LUSTRE_OST_NAME)); - else if (strncmp(exp->exp_obd->obd_type->typ_name, LUSTRE_MDC_NAME, - strlen(LUSTRE_MDC_NAME)) == 0) - memcpy(qchk->obd_type, LUSTRE_MDS_NAME, - strlen(LUSTRE_MDS_NAME)); - - RETURN(rc); -} - -int lmv_quota_check(struct obd_device *unused, struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct obd_device *obd = class_exp2obd(exp); - struct lmv_obd *lmv = &obd->u.lmv; - struct lmv_tgt_desc *tgt; - int i, rc = 0; - ENTRY; - - for (i = 0, tgt = lmv->tgts; i < lmv->desc.ld_tgt_count; i++, tgt++) { - int err; - - if (!tgt->ltd_active) { - CERROR("lmv idx %d inactive\n", i); - RETURN(-EIO); - } - - err = obd_quotacheck(tgt->ltd_exp, oqctl); - if (err && !rc) - rc = err; - } - - RETURN(rc); -} - -int lov_quota_check(struct obd_device *unused, struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct obd_device *obd = class_exp2obd(exp); - struct lov_obd *lov = &obd->u.lov; - int i, rc = 0; - ENTRY; - - obd_getref(obd); - - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - if (!lov->lov_tgts[i]) - continue; - - /* Skip quota check on the administratively disabled OSTs. */ - if (!lov->lov_tgts[i]->ltd_activate) { - CWARN("lov idx %d was administratively disabled, " - "skip quotacheck on it.\n", i); - continue; - } - - if (!lov->lov_tgts[i]->ltd_active) { - CERROR("lov idx %d inactive\n", i); - rc = -EIO; - goto out; - } - } - - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - int err; - - if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_activate) - continue; - - err = obd_quotacheck(lov->lov_tgts[i]->ltd_exp, oqctl); - if (err && !rc) - rc = err; - } - -out: - obd_putref(obd); - - RETURN(rc); -} diff --git a/lustre/quota/quota_ctl.c b/lustre/quota/quota_ctl.c index bce3546..a946d27 100644 --- a/lustre/quota/quota_ctl.c +++ b/lustre/quota/quota_ctl.c @@ -290,170 +290,3 @@ adjust: } #endif /* __KERNEL__ */ #endif - -int client_quota_ctl(struct obd_device *unused, struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct ptlrpc_request *req; - struct obd_quotactl *oqc; - const struct req_format *rf; - int ver, opc, rc; - ENTRY; - - if (!strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_MDC_NAME)) { - rf = &RQF_MDS_QUOTACTL; - ver = LUSTRE_MDS_VERSION, - opc = MDS_QUOTACTL; - } else if (!strcmp(exp->exp_obd->obd_type->typ_name, LUSTRE_OSC_NAME)) { - rf = &RQF_OST_QUOTACTL; - ver = LUSTRE_OST_VERSION, - opc = OST_QUOTACTL; - } else { - RETURN(-EINVAL); - } - - req = ptlrpc_request_alloc_pack(class_exp2cliimp(exp), rf, ver, opc); - if (req == NULL) - RETURN(-ENOMEM); - - oqc = req_capsule_client_get(&req->rq_pill, &RMF_OBD_QUOTACTL); - *oqc = *oqctl; - - ptlrpc_request_set_replen(req); - ptlrpc_at_set_req_timeout(req); - req->rq_no_resend = 1; - - rc = ptlrpc_queue_wait(req); - if (rc) - CERROR("ptlrpc_queue_wait failed, rc: %d\n", rc); - - if (req->rq_repmsg && - (oqc = req_capsule_server_get(&req->rq_pill, &RMF_OBD_QUOTACTL))) { - *oqctl = *oqc; - } else if (!rc) { - CERROR ("Can't unpack obd_quotactl\n"); - rc = -EPROTO; - } - - EXIT; - - ptlrpc_req_finished(req); - - return rc; -} - -/** - * For lmv, only need to send request to master MDT, and the master MDT will - * process with other slave MDTs. - */ -int lmv_quota_ctl(struct obd_device *unused, struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct obd_device *obd = class_exp2obd(exp); - struct lmv_obd *lmv = &obd->u.lmv; - struct lmv_tgt_desc *tgt = &lmv->tgts[0]; - int rc = 0, i; - __u64 curspace; - __u64 curinodes; - ENTRY; - - if (!lmv->desc.ld_tgt_count || !tgt->ltd_active) { - CERROR("master lmv inactive\n"); - RETURN(-EIO); - } - - if (oqctl->qc_cmd != Q_GETOQUOTA) { - rc = obd_quotactl(tgt->ltd_exp, oqctl); - RETURN(rc); - } - - curspace = curinodes = 0; - for (i = 0; i < lmv->desc.ld_tgt_count; i++) { - int err; - tgt = &lmv->tgts[i]; - - if (tgt->ltd_exp == NULL) - continue; - if (!tgt->ltd_active) { - CDEBUG(D_HA, "mdt %d is inactive.\n", i); - continue; - } - - err = obd_quotactl(tgt->ltd_exp, oqctl); - if (err) { - CERROR("getquota on mdt %d failed. %d\n", i, err); - if (!rc) - rc = err; - } else { - curspace += oqctl->qc_dqblk.dqb_curspace; - curinodes += oqctl->qc_dqblk.dqb_curinodes; - } - } - oqctl->qc_dqblk.dqb_curspace = curspace; - oqctl->qc_dqblk.dqb_curinodes = curinodes; - - RETURN(rc); -} - -int lov_quota_ctl(struct obd_device *unused, struct obd_export *exp, - struct obd_quotactl *oqctl) -{ - struct obd_device *obd = class_exp2obd(exp); - struct lov_obd *lov = &obd->u.lov; - struct lov_tgt_desc *tgt; - __u64 curspace = 0; - __u64 bhardlimit = 0; - int i, rc = 0; - ENTRY; - - if (oqctl->qc_cmd != LUSTRE_Q_QUOTAON && - oqctl->qc_cmd != LUSTRE_Q_QUOTAOFF && - oqctl->qc_cmd != Q_GETOQUOTA && - oqctl->qc_cmd != Q_INITQUOTA && - oqctl->qc_cmd != LUSTRE_Q_SETQUOTA && - oqctl->qc_cmd != Q_FINVALIDATE) { - CERROR("bad quota opc %x for lov obd", oqctl->qc_cmd); - RETURN(-EFAULT); - } - - /* for lov tgt */ - obd_getref(obd); - for (i = 0; i < lov->desc.ld_tgt_count; i++) { - int err; - - tgt = lov->lov_tgts[i]; - - if (!tgt) - continue; - - if (!tgt->ltd_active || tgt->ltd_reap) { - if (oqctl->qc_cmd == Q_GETOQUOTA && - lov->lov_tgts[i]->ltd_activate) { - rc = -EREMOTEIO; - CERROR("ost %d is inactive\n", i); - } else { - CDEBUG(D_HA, "ost %d is inactive\n", i); - } - continue; - } - - err = obd_quotactl(tgt->ltd_exp, oqctl); - if (err) { - if (tgt->ltd_active && !rc) - rc = err; - continue; - } - - if (oqctl->qc_cmd == Q_GETOQUOTA) { - curspace += oqctl->qc_dqblk.dqb_curspace; - bhardlimit += oqctl->qc_dqblk.dqb_bhardlimit; - } - } - obd_putref(obd); - - if (oqctl->qc_cmd == Q_GETOQUOTA) { - oqctl->qc_dqblk.dqb_curspace = curspace; - oqctl->qc_dqblk.dqb_bhardlimit = bhardlimit; - } - RETURN(rc); -} diff --git a/lustre/quota/quota_interface.c b/lustre/quota/quota_interface.c index 01dc6ac..ea6d8ec 100644 --- a/lustre/quota/quota_interface.c +++ b/lustre/quota/quota_interface.c @@ -733,230 +733,6 @@ static int quota_acquire_common(struct obd_device *obd, const unsigned int id[], #endif /* HAVE_QUOTA_SUPPORT */ #endif /* __KERNEL__ */ -struct osc_quota_info { - cfs_list_t oqi_hash; /* hash list */ - struct client_obd *oqi_cli; /* osc obd */ - unsigned int oqi_id; /* uid/gid of a file */ - short oqi_type; /* quota type */ -}; - -cfs_spinlock_t qinfo_list_lock = CFS_SPIN_LOCK_UNLOCKED; - -static cfs_list_t qinfo_hash[NR_DQHASH]; -/* SLAB cache for client quota context */ -cfs_mem_cache_t *qinfo_cachep = NULL; - -static inline int hashfn(struct client_obd *cli, unsigned long id, int type) - __attribute__((__const__)); - -static inline int hashfn(struct client_obd *cli, unsigned long id, int type) -{ - unsigned long tmp = ((unsigned long)cli>>6) ^ id; - tmp = (tmp * (MAXQUOTAS - type)) % NR_DQHASH; - return tmp; -} - -/* caller must hold qinfo_list_lock */ -static inline void insert_qinfo_hash(struct osc_quota_info *oqi) -{ - cfs_list_t *head = qinfo_hash + - hashfn(oqi->oqi_cli, oqi->oqi_id, oqi->oqi_type); - - LASSERT_SPIN_LOCKED(&qinfo_list_lock); - cfs_list_add(&oqi->oqi_hash, head); -} - -/* caller must hold qinfo_list_lock */ -static inline void remove_qinfo_hash(struct osc_quota_info *oqi) -{ - LASSERT_SPIN_LOCKED(&qinfo_list_lock); - cfs_list_del_init(&oqi->oqi_hash); -} - -/* caller must hold qinfo_list_lock */ -static inline struct osc_quota_info *find_qinfo(struct client_obd *cli, - unsigned int id, int type) -{ - unsigned int hashent = hashfn(cli, id, type); - struct osc_quota_info *oqi; - ENTRY; - - LASSERT_SPIN_LOCKED(&qinfo_list_lock); - cfs_list_for_each_entry(oqi, &qinfo_hash[hashent], oqi_hash) { - if (oqi->oqi_cli == cli && - oqi->oqi_id == id && oqi->oqi_type == type) - return oqi; - } - RETURN(NULL); -} - -static struct osc_quota_info *alloc_qinfo(struct client_obd *cli, - unsigned int id, int type) -{ - struct osc_quota_info *oqi; - ENTRY; - - OBD_SLAB_ALLOC(oqi, qinfo_cachep, CFS_ALLOC_IO, sizeof(*oqi)); - if(!oqi) - RETURN(NULL); - - CFS_INIT_LIST_HEAD(&oqi->oqi_hash); - oqi->oqi_cli = cli; - oqi->oqi_id = id; - oqi->oqi_type = type; - - RETURN(oqi); -} - -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, const unsigned int qid[]) -{ - unsigned int id; - int cnt, rc = QUOTA_OK; - ENTRY; - - cfs_spin_lock(&qinfo_list_lock); - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - struct osc_quota_info *oqi = NULL; - - id = (cnt == USRQUOTA) ? qid[USRQUOTA] : qid[GRPQUOTA]; - oqi = find_qinfo(cli, id, cnt); - if (oqi) { - rc = NO_QUOTA; - break; - } - } - cfs_spin_unlock(&qinfo_list_lock); - - if (rc == NO_QUOTA) - CDEBUG(D_QUOTA, "chkdq found noquota for %s %d\n", - cnt == USRQUOTA ? "user" : "group", id); - RETURN(rc); -} - -int osc_quota_setdq(struct client_obd *cli, const unsigned int qid[], - obd_flag valid, obd_flag flags) -{ - unsigned int id; - obd_flag noquota; - int cnt, rc = 0; - ENTRY; - - - for (cnt = 0; cnt < MAXQUOTAS; cnt++) { - struct osc_quota_info *oqi = NULL, *old; - - if (!(valid & ((cnt == USRQUOTA) ? - OBD_MD_FLUSRQUOTA : OBD_MD_FLGRPQUOTA))) - continue; - - id = (cnt == USRQUOTA) ? qid[USRQUOTA] : qid[GRPQUOTA]; - noquota = (cnt == USRQUOTA) ? - (flags & OBD_FL_NO_USRQUOTA) : (flags & OBD_FL_NO_GRPQUOTA); - - if (noquota) { - oqi = alloc_qinfo(cli, id, cnt); - if (!oqi) { - rc = -ENOMEM; - CDEBUG(D_QUOTA, "setdq for %s %d failed, " - "(rc = %d)\n", - cnt == USRQUOTA ? "user" : "group", - id, rc); - break; - } - } - - cfs_spin_lock(&qinfo_list_lock); - old = find_qinfo(cli, id, cnt); - if (old && !noquota) - remove_qinfo_hash(old); - else if (!old && noquota) - insert_qinfo_hash(oqi); - cfs_spin_unlock(&qinfo_list_lock); - - if (old && !noquota) - CDEBUG(D_QUOTA, "setdq to remove for %s %d\n", - cnt == USRQUOTA ? "user" : "group", id); - else if (!old && noquota) - CDEBUG(D_QUOTA, "setdq to insert for %s %d\n", - cnt == USRQUOTA ? "user" : "group", id); - - if (old) { - if (noquota) - free_qinfo(oqi); - else - free_qinfo(old); - } - } - - RETURN(rc); -} - -int osc_quota_cleanup(struct obd_device *obd) -{ - struct client_obd *cli = &obd->u.cli; - struct osc_quota_info *oqi, *n; - int i; - ENTRY; - - cfs_spin_lock(&qinfo_list_lock); - for (i = 0; i < NR_DQHASH; i++) { - cfs_list_for_each_entry_safe(oqi, n, &qinfo_hash[i], oqi_hash) { - if (oqi->oqi_cli != cli) - continue; - remove_qinfo_hash(oqi); - free_qinfo(oqi); - } - } - cfs_spin_unlock(&qinfo_list_lock); - - RETURN(0); -} - -int osc_quota_init(void) -{ - int i; - ENTRY; - - LASSERT(qinfo_cachep == NULL); - qinfo_cachep = cfs_mem_cache_create("osc_quota_info", - sizeof(struct osc_quota_info), - 0, 0); - if (!qinfo_cachep) - RETURN(-ENOMEM); - - for (i = 0; i < NR_DQHASH; i++) - CFS_INIT_LIST_HEAD(qinfo_hash + i); - - RETURN(0); -} - -int osc_quota_exit(void) -{ - struct osc_quota_info *oqi, *n; - int i, rc; - ENTRY; - - cfs_spin_lock(&qinfo_list_lock); - for (i = 0; i < NR_DQHASH; i++) { - cfs_list_for_each_entry_safe(oqi, n, &qinfo_hash[i], oqi_hash) { - remove_qinfo_hash(oqi); - free_qinfo(oqi); - } - } - cfs_spin_unlock(&qinfo_list_lock); - - rc = cfs_mem_cache_destroy(qinfo_cachep); - LASSERTF(rc == 0, "couldn't destory qinfo_cachep slab\n"); - qinfo_cachep = NULL; - - RETURN(0); -} - #ifdef __KERNEL__ #ifdef HAVE_QUOTA_SUPPORT quota_interface_t mds_quota_interface = { @@ -993,35 +769,6 @@ quota_interface_t filter_quota_interface = { #endif #endif /* __KERNEL__ */ -quota_interface_t mdc_quota_interface = { - .quota_ctl = client_quota_ctl, - .quota_check = client_quota_check, - .quota_poll_check = client_quota_poll_check, -}; - -quota_interface_t lmv_quota_interface = { - .quota_ctl = lmv_quota_ctl, - .quota_check = lmv_quota_check, -}; - -quota_interface_t osc_quota_interface = { - .quota_ctl = client_quota_ctl, - .quota_check = client_quota_check, - .quota_poll_check = client_quota_poll_check, - .quota_init = osc_quota_init, - .quota_exit = osc_quota_exit, - .quota_chkdq = osc_quota_chkdq, - .quota_setdq = osc_quota_setdq, - .quota_cleanup = osc_quota_cleanup, - .quota_adjust_qunit = client_quota_adjust_qunit, -}; - -quota_interface_t lov_quota_interface = { - .quota_ctl = lov_quota_ctl, - .quota_check = lov_quota_check, - .quota_adjust_qunit = lov_quota_adjust_qunit, -}; - #ifdef __KERNEL__ cfs_proc_dir_entry_t *lquota_type_proc_dir = NULL; @@ -1047,19 +794,11 @@ static int __init init_lustre_quota(void) PORTAL_SYMBOL_REGISTER(filter_quota_interface); PORTAL_SYMBOL_REGISTER(mds_quota_interface); #endif - PORTAL_SYMBOL_REGISTER(mdc_quota_interface); - PORTAL_SYMBOL_REGISTER(lmv_quota_interface); - PORTAL_SYMBOL_REGISTER(osc_quota_interface); - PORTAL_SYMBOL_REGISTER(lov_quota_interface); return 0; } static void /*__exit*/ exit_lustre_quota(void) { - PORTAL_SYMBOL_UNREGISTER(mdc_quota_interface); - PORTAL_SYMBOL_UNREGISTER(lmv_quota_interface); - PORTAL_SYMBOL_UNREGISTER(osc_quota_interface); - PORTAL_SYMBOL_UNREGISTER(lov_quota_interface); #ifdef HAVE_QUOTA_SUPPORT PORTAL_SYMBOL_UNREGISTER(filter_quota_interface); PORTAL_SYMBOL_UNREGISTER(mds_quota_interface); @@ -1081,8 +820,4 @@ cfs_module(lquota, "1.0.0", init_lustre_quota, exit_lustre_quota); EXPORT_SYMBOL(mds_quota_interface); EXPORT_SYMBOL(filter_quota_interface); #endif -EXPORT_SYMBOL(mdc_quota_interface); -EXPORT_SYMBOL(lmv_quota_interface); -EXPORT_SYMBOL(osc_quota_interface); -EXPORT_SYMBOL(lov_quota_interface); #endif /* __KERNEL */ -- 1.8.3.1