return;
}
-static void __lov_del_obd(struct obd_device *obd, __u32 index);
+static void __lov_del_obd(struct obd_device *obd, struct lov_tgt_desc *tgt);
void lov_putref(struct obd_device *obd)
{
struct lov_obd *lov = &obd->u.lov;
+
mutex_down(&lov->lov_lock);
/* ok to dec to 0 more than once -- ltd_exp's will be null */
if (atomic_dec_and_test(&lov->lov_refcount) && lov->lov_death_row) {
+ CFS_LIST_HEAD(kill);
int i;
+ struct lov_tgt_desc *tgt, *n;
CDEBUG(D_CONFIG, "destroying %d lov targets\n",
lov->lov_death_row);
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
- if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_reap)
+ tgt = lov->lov_tgts[i];
+
+ if (!tgt || !tgt->ltd_reap)
continue;
- /* Disconnect and delete from list */
- __lov_del_obd(obd, i);
+ list_add(&tgt->ltd_kill, &kill);
+ /* XXX - right now there is a dependency on ld_tgt_count
+ * being the maximum tgt index for computing the
+ * mds_max_easize. So we can't shrink it. */
+ lov_ost_pool_remove(&lov->lov_packed, i);
+ lov->lov_tgts[i] = NULL;
lov->lov_death_row--;
}
+ mutex_up(&lov->lov_lock);
+
+ list_for_each_entry_safe(tgt, n, &kill, ltd_kill) {
+ list_del(&tgt->ltd_kill);
+ /* Disconnect */
+ __lov_del_obd(obd, tgt);
+ }
+ } else {
+ mutex_up(&lov->lov_lock);
}
- mutex_up(&lov->lov_lock);
}
static int lov_set_osc_active(struct obd_device *obd, struct obd_uuid *uuid,
RETURN(0);
}
-static int lov_disconnect_obd(struct obd_device *obd, __u32 index)
+static int lov_disconnect_obd(struct obd_device *obd, struct lov_tgt_desc *tgt)
{
cfs_proc_dir_entry_t *lov_proc_dir;
struct lov_obd *lov = &obd->u.lov;
struct obd_device *osc_obd;
int rc;
-
ENTRY;
- if (lov->lov_tgts[index] == NULL)
- RETURN(-EINVAL);
-
- osc_obd = class_exp2obd(lov->lov_tgts[index]->ltd_exp);
+ osc_obd = class_exp2obd(tgt->ltd_exp);
CDEBUG(D_CONFIG, "%s: disconnecting target %s\n",
obd->obd_name, osc_obd->obd_name);
- if (lov->lov_tgts[index]->ltd_active) {
- lov->lov_tgts[index]->ltd_active = 0;
+ if (tgt->ltd_active) {
+ tgt->ltd_active = 0;
lov->desc.ld_active_tgt_count--;
- lov->lov_tgts[index]->ltd_exp->exp_obd->obd_inactive = 1;
+ tgt->ltd_exp->exp_obd->obd_inactive = 1;
}
lov_proc_dir = lprocfs_srch(obd->obd_proc_entry, "target_obds");
obd_register_observer(osc_obd, NULL);
- rc = obd_disconnect(lov->lov_tgts[index]->ltd_exp);
+ rc = obd_disconnect(tgt->ltd_exp);
if (rc) {
CERROR("Target %s disconnect error %d\n",
- lov_uuid2str(lov, index), rc);
+ tgt->ltd_uuid.uuid, rc);
rc = 0;
}
- qos_del_tgt(obd, index);
+ qos_del_tgt(obd, tgt);
- lov->lov_tgts[index]->ltd_exp = NULL;
+ tgt->ltd_exp = NULL;
RETURN(0);
}
RETURN(rc);
}
-/* We are holding lov_lock */
-static void __lov_del_obd(struct obd_device *obd, __u32 index)
+static void __lov_del_obd(struct obd_device *obd, struct lov_tgt_desc *tgt)
{
- struct lov_obd *lov = &obd->u.lov;
struct obd_device *osc_obd;
- struct lov_tgt_desc *tgt = lov->lov_tgts[index];
LASSERT(tgt);
LASSERT(tgt->ltd_reap);
osc_obd = class_exp2obd(tgt->ltd_exp);
CDEBUG(D_CONFIG, "Removing tgt %s : %s\n",
- lov_uuid2str(lov, index),
+ tgt->ltd_uuid.uuid,
osc_obd ? osc_obd->obd_name : "<no obd>");
if (tgt->ltd_exp)
- lov_disconnect_obd(obd, index);
-
- /* XXX - right now there is a dependency on ld_tgt_count being the
- * maximum tgt index for computing the mds_max_easize. So we can't
- * shrink it. */
+ lov_disconnect_obd(obd, tgt);
- lov_ost_pool_remove(&lov->lov_packed, index);
- lov->lov_tgts[index] = NULL;
OBD_FREE_PTR(tgt);
/* Manual cleanup - no cleanup logs to clean up the osc's. We must