obd_async_recov:1; /* allow asyncronous orphan cleanup */
atomic_t obd_refcount;
cfs_waitq_t obd_refcount_waitq;
- cfs_proc_dir_entry_t *obd_proc_entry;
+ struct semaphore obd_setup_sem; /* for gating config stuff */
+ cfs_proc_dir_entry_t *obd_proc_entry;
struct list_head obd_exports;
int obd_num_exports;
struct ldlm_namespace *obd_namespace;
if (index < 0 || index >= LLOG_MAX_CTXTS)
RETURN(-EFAULT);
+ mutex_down(&obd->obd_setup_sem);
if (obd->obd_llog_ctxt[index]) {
/* mds_lov_update_mds might call here multiple times. So if the
LASSERT(ctxt->loc_obd == obd);
LASSERT(ctxt->loc_exp == disk_obd->obd_self_export);
LASSERT(ctxt->loc_logops == op);
- RETURN(0);
+ GOTO(out, rc = 0);
}
OBD_ALLOC(ctxt, sizeof(*ctxt));
if (!ctxt)
- RETURN(-ENOMEM);
+ GOTO(out, rc = -ENOMEM);
obd->obd_llog_ctxt[index] = ctxt;
ctxt->loc_obd = obd;
if (op->lop_setup)
rc = op->lop_setup(obd, index, disk_obd, count, logid);
-
+
+ if (rc) {
+ obd->obd_llog_ctxt[index] = NULL;
+ class_export_put(ctxt->loc_exp);
+ OBD_FREE(ctxt, sizeof(*ctxt));
+ }
+
+out:
+ mutex_up(&obd->obd_setup_sem);
RETURN(rc);
}
EXPORT_SYMBOL(llog_setup);
if (rc)
CERROR("llog_process with cat_cancel_cb failed: %d\n", rc);
out:
- if (ctxt && rc) {
- obd->obd_llog_ctxt[index] = NULL;
- OBD_FREE(ctxt, sizeof(*ctxt));
- }
RETURN(rc);
}
EXPORT_SYMBOL(llog_obd_origin_setup);
LASSERTF(strncmp(obd->obd_name, name, strlen(name)) == 0, "%p obd_name %s != %s\n",
obd, obd->obd_name, name);
+ sema_init(&obd->obd_setup_sem, 1);
CFS_INIT_LIST_HEAD(&obd->obd_exports);
CFS_INIT_LIST_HEAD(&obd->obd_exports_timed);
spin_lock_init(&obd->obd_dev_lock);
dump_exports(obd);
GOTO(out, err = -EBUSY);
}
+ /* refcounf - 3 might be the number of real exports
+ (excluding self export). But class_incref is called
+ by other things as well, so don't count on it. */
CDEBUG(D_IOCTL, "%s: forcing exports to disconnect: %d\n",
- obd->obd_name, atomic_read(&obd->obd_refcount) - 1);
+ obd->obd_name, atomic_read(&obd->obd_refcount) - 3);
dump_exports(obd);
class_disconnect_exports(obd);
}