X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=lustre%2Fquota%2Fqmt_dev.c;h=f785ac969696401c9e67dda5ed6eb11a1d52f4d4;hb=b0e8ab1a5f6f8d4a7c01241fec192ed50ad0b896;hp=e165ae713960f890048ac21a89308997f10c8140;hpb=50473b10366447d2a0754fecadca41b7e2ddb5e0;p=fs%2Flustre-release.git diff --git a/lustre/quota/qmt_dev.c b/lustre/quota/qmt_dev.c index e165ae7..f785ac9 100644 --- a/lustre/quota/qmt_dev.c +++ b/lustre/quota/qmt_dev.c @@ -21,7 +21,7 @@ * GPL HEADER END */ /* - * Copyright (c) 2012 Intel, Inc. + * Copyright (c) 2012, 2017, Intel Corporation. * Use is subject to license terms. * * Author: Johann Lombardi @@ -45,7 +45,7 @@ * The QMT device is currently set up by the MDT and should probably be moved * to a separate target in the future. Meanwhile, the MDT forwards all quota * requests to the QMT via a list of request handlers (see struct qmt_handlers - * in lquota.h). The QMT also borrows the LDLM namespace from the MDT. + * in lustre_quota.h). The QMT also borrows the LDLM namespace from the MDT. * * To bring up a QMT device, the following steps must be completed: * @@ -66,10 +66,6 @@ * mdt_quota_init() for more details. */ -#ifndef EXPORT_SYMTAB -# define EXPORT_SYMTAB -#endif - #define DEBUG_SUBSYSTEM S_LQUOTA #include @@ -99,14 +95,37 @@ static struct lu_device *qmt_device_fini(const struct lu_env *env, LASSERT(qmt != NULL); CDEBUG(D_QUOTA, "%s: initiating QMT shutdown\n", qmt->qmt_svname); + qmt->qmt_stopping = true; + + /* kill pool instances, if any */ + qmt_pool_fini(env, qmt); + + /* remove qmt proc entry */ + if (qmt->qmt_proc != NULL && !IS_ERR(qmt->qmt_proc)) { + lprocfs_remove(&qmt->qmt_proc); + qmt->qmt_proc = NULL; + } + + /* stop rebalance thread */ + if (!qmt->qmt_child->dd_rdonly) + qmt_stop_reba_thread(qmt); + + if (qmt->qmt_root) { + dt_object_put(env, qmt->qmt_root); + qmt->qmt_root = NULL; + } /* disconnect from OSD */ if (qmt->qmt_child_exp != NULL) { obd_disconnect(qmt->qmt_child_exp); qmt->qmt_child_exp = NULL; - qmt->qmt_child = NULL; + qmt->qmt_child = NULL; } + /* clear references to MDT namespace */ + ld->ld_obd->obd_namespace = NULL; + qmt->qmt_ns = NULL; + RETURN(NULL); } @@ -159,7 +178,7 @@ static int qmt_connect_to_osd(const struct lu_env *env, struct qmt_device *qmt, /* initialize site (although it isn't used anywhere) and lu_device * pointer to next device */ qmt->qmt_child = lu2dt_dev(qmt->qmt_child_exp->exp_obd->obd_lu_dev); - ld->ld_site = qmt->qmt_child_exp->exp_obd->obd_lu_dev->ld_site; + ld->ld_site = qmt->qmt_child_exp->exp_obd->obd_lu_dev->ld_site; EXIT; out: if (data) @@ -187,13 +206,19 @@ static int qmt_device_init0(const struct lu_env *env, struct qmt_device *qmt, struct lu_device_type *ldt, struct lustre_cfg *cfg) { struct lu_device *ld = qmt2lu_dev(qmt); - struct obd_device *obd; + struct obd_device *obd, *mdt_obd; + struct obd_type *type; + char *svname = lustre_cfg_string(cfg, 0); int rc; ENTRY; + if (svname == NULL) + RETURN(-EINVAL); + /* record who i am, it might be useful ... */ - strncpy(qmt->qmt_svname, lustre_cfg_string(cfg, 0), - sizeof(qmt->qmt_svname) - 1); + rc = strlcpy(qmt->qmt_svname, svname, sizeof(qmt->qmt_svname)); + if (rc >= sizeof(qmt->qmt_svname)) + RETURN(-E2BIG); /* look-up the obd_device associated with the qmt */ obd = class_name2obd(qmt->qmt_svname); @@ -204,11 +229,57 @@ static int qmt_device_init0(const struct lu_env *env, struct qmt_device *qmt, obd->obd_lu_dev = ld; ld->ld_obd = obd; + /* look-up the parent MDT to steal its ldlm namespace ... */ + mdt_obd = class_name2obd(lustre_cfg_string(cfg, 2)); + if (mdt_obd == NULL) + RETURN(-ENOENT); + + /* borrow MDT namespace. kind of a hack until we have our own namespace + * & service threads */ + LASSERT(mdt_obd->obd_namespace != NULL); + obd->obd_namespace = mdt_obd->obd_namespace; + qmt->qmt_ns = obd->obd_namespace; + /* connect to backend osd device */ rc = qmt_connect_to_osd(env, qmt, cfg); if (rc) GOTO(out, rc); + /* set up and start rebalance thread */ + INIT_LIST_HEAD(&qmt->qmt_reba_list); + spin_lock_init(&qmt->qmt_reba_lock); + if (!qmt->qmt_child->dd_rdonly) { + rc = qmt_start_reba_thread(qmt); + if (rc) { + CERROR("%s: failed to start rebalance thread (%d)\n", + qmt->qmt_svname, rc); + GOTO(out, rc); + } + } + + /* at the moment there is no linkage between lu_type and obd_type, so + * we lookup obd_type this way */ + type = class_search_type(LUSTRE_QMT_NAME); + LASSERT(type != NULL); + + /* put reference taken by class_search_type */ + kobject_put(&type->typ_kobj); + + /* register proc directory associated with this qmt */ + qmt->qmt_proc = lprocfs_register(qmt->qmt_svname, type->typ_procroot, + NULL, NULL); + if (IS_ERR(qmt->qmt_proc)) { + rc = PTR_ERR(qmt->qmt_proc); + CERROR("%s: failed to create qmt proc entry (%d)\n", + qmt->qmt_svname, rc); + GOTO(out, rc); + } + + /* initialize pool configuration */ + rc = qmt_pool_init(env, qmt); + if (rc) + GOTO(out, rc); + EXIT; out: if (rc) @@ -352,10 +423,14 @@ static int qmt_device_obd_disconnect(struct obd_export *exp) /* * obd device operations associated with the master target. */ -struct obd_ops qmt_obd_ops = { +static const struct obd_ops qmt_obd_ops = { .o_owner = THIS_MODULE, .o_connect = qmt_device_obd_connect, .o_disconnect = qmt_device_obd_disconnect, + .o_pool_new = qmt_pool_new, + .o_pool_rem = qmt_pool_rem, + .o_pool_add = qmt_pool_add, + .o_pool_del = qmt_pool_del, }; /* @@ -372,7 +447,26 @@ static int qmt_device_prepare(const struct lu_env *env, struct lu_device *parent, struct lu_device *ld) { - return 0; + struct qmt_device *qmt = lu2qmt_dev(ld); + struct dt_object *qmt_root; + int rc; + ENTRY; + + /* initialize quota master root directory where all index files will be + * stored */ + qmt_root = lquota_disk_dir_find_create(env, qmt->qmt_child, NULL, + QMT_DIR); + if (IS_ERR(qmt_root)) { + rc = PTR_ERR(qmt_root); + CERROR("%s: failed to create master quota directory (%d)\n", + qmt->qmt_svname, rc); + RETURN(rc); + } + + qmt->qmt_root = qmt_root; + /* initialize on-disk indexes associated with each pool */ + rc = qmt_pool_prepare(env, qmt, qmt_root, NULL); + RETURN(rc); } /* @@ -390,8 +484,8 @@ int qmt_glb_init(void) int rc; ENTRY; - rc = class_register_type(&qmt_obd_ops, NULL, NULL, LUSTRE_QMT_NAME, - &qmt_device_type); + rc = class_register_type(&qmt_obd_ops, NULL, true, NULL, + LUSTRE_QMT_NAME, &qmt_device_type); RETURN(rc); }