char *ostname);
int (*o_pool_rem)(struct obd_device *obd, char *poolname,
char *ostname);
+ void (*o_getref)(struct obd_device *obd);
+ void (*o_putref)(struct obd_device *obd);
/*
* NOTE: If adding ops, add another LPROCFS_OBD_OP_INIT() line
* to lprocfs_alloc_obd_stats() in obdclass/lprocfs_status.c.
RETURN(rc);
}
+static inline void obd_getref(struct obd_device *obd)
+{
+ ENTRY;
+ if (OBT(obd) && OBP(obd, getref)) {
+ OBD_COUNTER_INCREMENT(obd, getref);
+ OBP(obd, getref)(obd);
+ }
+ EXIT;
+}
+
+static inline void obd_putref(struct obd_device *obd)
+{
+ ENTRY;
+ if (OBT(obd) && OBP(obd, putref)) {
+ OBD_COUNTER_INCREMENT(obd, putref);
+ OBP(obd, putref)(obd);
+ }
+ EXIT;
+}
+
static inline int obd_init_export(struct obd_export *exp)
{
int rc = 0;
int rc;
ENTRY;
- lov_getref(obd);
+ obd_getref(obd);
tgt = obd->u.lov.lov_tgts[index];
LASSERT(tgt != NULL);
rc = PTR_ERR(cl);
}
}
- lov_putref(obd);
+ obd_putref(obd);
RETURN(rc);
}
int gen;
__u32 index;
- lov_getref(obd);
+ obd_getref(obd);
cmd = cfg->lcfg_command;
rc = lov_process_config_base(d->ld_obd, cfg, &index, &gen);
break;
}
}
- lov_putref(obd);
+ obd_putref(obd);
RETURN(rc);
}
#ifndef LOV_INTERNAL_H
#define LOV_INTERNAL_H
+#include <obd_class.h>
#include <lustre/lustre_user.h>
struct lov_lock_handles {
void lov_fix_desc_pattern(__u32 *val);
void lov_fix_desc_qos_maxage(__u32 *val);
int lov_get_stripecnt(struct lov_obd *lov, __u32 stripe_count);
-void lov_getref(struct obd_device *obd);
-void lov_putref(struct obd_device *obd);
int lov_connect_obd(struct obd_device *obd, __u32 index, int activate,
struct obd_connect_data *data);
int lov_setup(struct obd_device *obd, struct lustre_cfg *lcfg);
int i, rc = 0, err = 0;
ENTRY;
- lov_getref(obd);
+ obd_getref(obd);
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
struct obd_device *child;
struct llog_ctxt *cctxt;
err = rc;
}
}
- lov_putref(obd);
+ obd_putref(obd);
RETURN(err);
}
LASSERT(count == lsm->lsm_stripe_count);
lov = &obd->u.lov;
- lov_getref(obd);
+ obd_getref(obd);
for (i = 0; i < count; i++, cookies++) {
struct lov_oinfo *loi = lsm->lsm_oinfo[i];
struct obd_device *child =
rc = err;
}
}
- lov_putref(obd);
+ obd_putref(obd);
RETURN(rc);
}
if (rc)
GOTO(err_cleanup, rc);
- lov_getref(obd);
+ obd_getref(obd);
/* count may not match lov->desc.ld_tgt_count during dynamic ost add */
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_active)
rc);
break;
}
- lov_putref(obd);
+ obd_putref(obd);
GOTO(err_cleanup, rc);
err_cleanup:
if (rc) {
#include "lov_internal.h"
-
/* Keep a refcount of lov->tgt usage to prevent racing with addition/deletion.
Any function that expects lov_tgts to remain stationary must take a ref. */
-void lov_getref(struct obd_device *obd)
+static void lov_getref(struct obd_device *obd)
{
struct lov_obd *lov = &obd->u.lov;
static void __lov_del_obd(struct obd_device *obd, struct lov_tgt_desc *tgt);
-void lov_putref(struct obd_device *obd)
+static void lov_putref(struct obd_device *obd)
{
struct lov_obd *lov = &obd->u.lov;
if (data)
lov->lov_ocd = *data;
- lov_getref(obd);
+ obd_getref(obd);
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
tgt = lov->lov_tgts[i];
if (!tgt || obd_uuid_empty(&tgt->ltd_uuid))
obd->obd_name, rc);
}
}
- lov_putref(obd);
+ obd_putref(obd);
RETURN(0);
}
/* Let's hold another reference so lov_del_obd doesn't spin through
putref every time */
- lov_getref(obd);
+ obd_getref(obd);
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
if (lov->lov_tgts[i] && lov->lov_tgts[i]->ltd_exp) {
lov_del_target(obd, i, 0, lov->lov_tgts[i]->ltd_gen);
}
}
- lov_putref(obd);
+ obd_putref(obd);
out:
rc = class_disconnect(exp); /* bz 9811 */
CDEBUG(D_INFO, "Searching in lov %p for uuid %s (activate=%d)\n",
lov, uuid->uuid, activate);
- lov_getref(obd);
+ obd_getref(obd);
for (index = 0; index < lov->desc.ld_tgt_count; index++) {
tgt = lov->lov_tgts[index];
if (!tgt || !tgt->ltd_exp)
lov->lov_tgts[index]->ltd_qos.ltq_penalty = 0;
out:
- lov_putref(obd);
+ obd_putref(obd);
RETURN(index);
}
struct lov_obd *lov = &obd->u.lov;
struct obd_device *tgt_obd;
int i;
- lov_getref(obd);
+ obd_getref(obd);
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
/* don't send sync event if target not
* connected/activated */
break;
}
}
- lov_putref(obd);
+ obd_putref(obd);
}
RETURN(rc);
RETURN(0);
}
- lov_getref(obd);
+ obd_getref(obd);
rc = lov_connect_obd(obd, index, active, &lov->lov_ocd);
if (rc)
obd_uuid2str(&tgt->ltd_uuid));
lov_del_target(obd, index, 0, 0);
}
- lov_putref(obd);
+ obd_putref(obd);
RETURN(rc);
}
RETURN(-EINVAL);
}
- lov_getref(obd);
+ obd_getref(obd);
if (!lov->lov_tgts[index]) {
CERROR("LOV target at index %d is not setup.\n", index);
lov->lov_tgts[index]->ltd_reap = 1;
lov->lov_death_row++;
- /* we really delete it from lov_putref */
+ /* we really delete it from obd_putref */
out:
- lov_putref(obd);
+ obd_putref(obd);
RETURN(rc);
}
if (lov->lov_tgts) {
int i;
- lov_getref(obd);
+ obd_getref(obd);
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
if (!lov->lov_tgts[i])
continue;
atomic_read(&lov->lov_refcount));
lov_del_target(obd, i, 0, 0);
}
- lov_putref(obd);
+ obd_putref(obd);
OBD_FREE(lov->lov_tgts, sizeof(*lov->lov_tgts) *
lov->lov_tgt_size);
lov->lov_tgt_size = 0;
ost_uuid->uuid);
}
- lov_getref(export->exp_obd);
+ obd_getref(export->exp_obd);
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
struct lov_stripe_md obj_md;
struct lov_stripe_md *obj_mdp = &obj_md;
if (ost_uuid)
break;
}
- lov_putref(export->exp_obd);
+ obd_putref(export->exp_obd);
OBDO_FREE(tmp_oa);
RETURN(rc);
if (!lov->desc.ld_active_tgt_count)
RETURN(-EIO);
- lov_getref(exp->exp_obd);
+ obd_getref(exp->exp_obd);
/* Recreate a specific object id at the given OST index */
if ((src_oa->o_valid & OBD_MD_FLFLAGS) &&
(src_oa->o_flags & OBD_FL_RECREATE_OBJS)) {
}
rc = lov_fini_create_set(set, ea);
out:
- lov_putref(exp->exp_obd);
+ obd_putref(exp->exp_obd);
RETURN(rc);
}
}
lov = &exp->exp_obd->u.lov;
- lov_getref(exp->exp_obd);
+ obd_getref(exp->exp_obd);
rc = lov_prep_destroy_set(exp, &oinfo, oa, lsm, oti, &set);
if (rc)
GOTO(out, rc);
}
err = lov_fini_destroy_set(set);
out:
- lov_putref(exp->exp_obd);
+ obd_putref(exp->exp_obd);
RETURN(rc ? rc : err);
}
if (!vallen || !val)
RETURN(-EFAULT);
- lov_getref(obddev);
+ obd_getref(obddev);
if (KEY_IS(KEY_LOCK_TO_STRIPE)) {
struct {
rc = -EINVAL;
out:
- lov_putref(obddev);
+ obd_putref(obddev);
RETURN(rc);
}
RETURN(-ENOMEM);
}
- lov_getref(obddev);
+ obd_getref(obddev);
count = lov->desc.ld_tgt_count;
if (KEY_IS(KEY_NEXT_ID)) {
rc = err;
}
- lov_putref(obddev);
+ obd_putref(obddev);
if (no_set) {
err = ptlrpc_set_wait(set);
if (!rc)
.o_pool_rem = lov_pool_remove,
.o_pool_add = lov_pool_add,
.o_pool_del = lov_pool_del,
+ .o_getref = lov_getref,
+ .o_putref = lov_putref,
};
static quota_interface_t *quota_interface;
/* search ost in lov array */
- lov_getref(obd);
+ obd_getref(obd);
for (lov_idx = 0; lov_idx < lov->desc.ld_tgt_count; lov_idx++) {
if (!lov->lov_tgts[lov_idx])
continue;
EXIT;
out:
- lov_putref(obd);
+ obd_putref(obd);
lov_pool_putref(pool);
return rc;
}
obd_str2uuid(&ost_uuid, ostname);
- lov_getref(obd);
+ obd_getref(obd);
/* search ost in lov array, to get index */
for (lov_idx = 0; lov_idx < lov->desc.ld_tgt_count; lov_idx++) {
if (!lov->lov_tgts[lov_idx])
EXIT;
out:
- lov_putref(obd);
+ obd_putref(obd);
lov_pool_putref(pool);
return rc;
}
lqr = &(pool->pool_rr);
}
- lov_getref(exp->exp_obd);
+ obd_getref(exp->exp_obd);
/* wait for fresh statfs info if needed, the rpcs are sent in
* lov_create() */
if (rc == -EAGAIN)
rc = alloc_rr(lov, idx_arr, stripe_cnt, poolname, flags);
- lov_putref(exp->exp_obd);
+ obd_putref(exp->exp_obd);
RETURN(rc);
}
break;
#ifdef HAVE_QUOTA_SUPPORT
case MD_LOV_QUOTA:
- if (md->md_lu_dev.ld_obd->obd_recovering == 0)
+ if (md->md_lu_dev.ld_obd->obd_recovering == 0 &&
+ likely(md->md_lu_dev.ld_obd->obd_stopping == 0))
next->md_ops->mdo_quota.mqo_recovery(env, next);
break;
#endif
rc = ld->ld_ops->ldo_recovery_complete(env, ld);
#ifdef HAVE_QUOTA_SUPPORT
- next->md_ops->mdo_quota.mqo_recovery(env, next);
+ if (likely(obd->obd_stopping == 0))
+ next->md_ops->mdo_quota.mqo_recovery(env, next);
#endif
RETURN(rc);
}
LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_rem);
LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_add);
LPROCFS_OBD_OP_INIT(num_private_stats, stats, pool_del);
+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, getref);
+ LPROCFS_OBD_OP_INIT(num_private_stats, stats, putref);
}
int lprocfs_alloc_obd_stats(struct obd_device *obd, unsigned num_private_stats)
RETURN(-EFAULT);
}
+ obd_getref(obd);
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
int err;
bhardlimit += oqctl->qc_dqblk.dqb_bhardlimit;
}
}
+ obd_putref(obd);
if (oqctl->qc_cmd == Q_GETOQUOTA) {
oqctl->qc_dqblk.dqb_curspace = curspace;
{
struct qmaster_recov_thread_data *data = arg;
struct obd_device *obd = data->obd;
+ struct mds_obd *mds = &obd->u.mds;
+ struct lustre_quota_info *qinfo = &mds->mds_quota_info;
int rc = 0;
unsigned short type;
ENTRY;
ptlrpc_daemonize("qmaster_recovd");
+ class_incref(obd, "qmaster_recovd", obd);
complete(&data->comp);
for (type = USRQUOTA; type < MAXQUOTAS; type++) {
- struct mds_obd *mds = &obd->u.mds;
- struct lustre_quota_info *qinfo = &mds->mds_quota_info;
struct list_head id_list;
struct dquot_id *dqid, *tmp;
kfree(dqid);
}
}
+ class_decref(obd, "qmaster_recovd", obd);
RETURN(rc);
}