/* obd_mount.c */
void lustre_register_client_fill_super(int (*cfs)(struct super_block *sb));
void lustre_common_put_super(struct super_block *sb);
-int class_manual_cleanup(struct obd_device *obd, char *flags);
struct lustre_mount_info *lustre_get_mount(char *name);
int lustre_put_mount(char *name);
void class_fail_export(struct obd_export *exp);
void class_disconnect_exports(struct obd_device *obddev);
void class_disconnect_stale_exports(struct obd_device *obddev);
-/* generic operations shared by various OBD types */
-int class_multi_setup(struct obd_device *obddev, uint32_t len, void *data);
-int class_multi_cleanup(struct obd_device *obddev);
+void class_manual_cleanup(struct obd_device *obd, char *flags);
/* obdo.c */
#ifdef __KERNEL__
struct obd_device *obd = class_exp2obd(exp);
struct lov_obd *lov = &obd->u.lov;
struct lov_tgt_desc *tgt;
+ char flags[3]="";
int rc, i;
ENTRY;
RETURN(rc);
for (i = 0, tgt = lov->tgts; i < lov->desc.ld_tgt_count; i++, tgt++) {
- if (tgt->ltd_exp)
- lov_disconnect_obd(obd, tgt);
+ if (tgt->ltd_exp) {
+ /* Disconnect and delete from list */
+ lov_del_obd(obd, obd->obd_uuid, i, tgt->ltd_gen);
+ /* Cleanup the osc now - can't do it from
+ lov_cleanup because we lose our only reference to
+ it right now. */
+ /* Use lov's force/fail flags. */
+ if (obd->obd_force)
+ strcat(flags, "F");
+ if (obd->obd_fail)
+ strcat(flags, "A");
+ class_manual_cleanup(tgt->ltd_exp->exp_obd, flags);
+ }
}
RETURN(rc);
/* Allocate space for target list */
if (desc->ld_tgt_count)
count = desc->ld_tgt_count;
- lov->bufsize = sizeof(struct lov_tgt_desc) * count;
+ lov->bufsize = sizeof(struct lov_tgt_desc) * max(count, 1);
OBD_ALLOC(lov->tgts, lov->bufsize);
if (lov->tgts == NULL) {
CERROR("Out of memory\n");
int mds_lov_clean(struct obd_device *obd)
{
struct mds_obd *mds = &obd->u.mds;
-
+ struct obd_device *osc = mds->mds_osc_obd;
+ char flags[3]="";
+ ENTRY;
+
if (mds->mds_profile) {
- char * cln_prof;
- struct config_llog_instance cfg;
- struct lvfs_run_ctxt saved;
- int len = strlen(mds->mds_profile) + sizeof("-clean") + 1;
+ class_del_profile(mds->mds_profile);
+ OBD_FREE(mds->mds_profile, strlen(mds->mds_profile) + 1);
+ mds->mds_profile = NULL;
+ }
- OBD_ALLOC(cln_prof, len);
- sprintf(cln_prof, "%s-clean", mds->mds_profile);
+ /* There better be a lov */
+ if (!osc)
+ RETURN(0);
- cfg.cfg_instance = NULL;
- cfg.cfg_uuid = mds->mds_lov_uuid;
+ obd_register_observer(osc, NULL);
- push_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
- class_config_parse_llog(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT),
- cln_prof, &cfg);
- pop_ctxt(&saved, &obd->obd_lvfs_ctxt, NULL);
+ /* Give lov our same shutdown flags */
+ /* Could probably use osc->obd_force = obd->obd_force safely */
+ if (obd->obd_force)
+ strcat(flags, "F");
+ if (obd->obd_fail)
+ strcat(flags, "A");
+
+ /* Cleanup the lov */
+ obd_disconnect(mds->mds_osc_exp);
+ class_manual_cleanup(osc, flags);
+ mds->mds_osc_exp = NULL;
- OBD_FREE(cln_prof, len);
- OBD_FREE(mds->mds_profile, strlen(mds->mds_profile) + 1);
- mds->mds_profile = NULL;
- }
RETURN(0);
}
switch (stage) {
case 1:
- mds_lov_set_cleanup_flags(obd);
target_cleanup_recovery(obd);
break;
case 2:
- mds_lov_disconnect(obd);
mds_lov_clean(obd);
llog_cleanup(llog_get_context(obd, LLOG_CONFIG_ORIG_CTXT));
rc = obd_llog_finish(obd, 0);
/* mds/mds_lov.c */
int mds_lov_connect(struct obd_device *obd, char * lov_name);
-int mds_lov_disconnect(struct obd_device *obd);
-void mds_lov_set_cleanup_flags(struct obd_device *);
int mds_lov_write_objids(struct obd_device *obd);
void mds_lov_update_objids(struct obd_device *obd, obd_id *ids);
int mds_lov_set_nextid(struct obd_device *obd);
void lustre_dquot_exit(void);
int dqacq_handler(struct obd_device *obd, struct qunit_data *qdata, int opc);
void mds_adjust_qunit(struct obd_device *obd, uid_t cuid, gid_t cgid,
- uid_t puid, gid_t pgid, int rc);
+ uid_t puid, gid_t pgid, int rc);
int init_admin_quotafiles(struct obd_device *obd, struct obd_quotactl *oqctl);
int mds_quota_on(struct obd_device *obd, struct obd_quotactl *oqctl);
int mds_quota_off(struct obd_device *obd, struct obd_quotactl *oqctl);
RETURN(rc);
}
-int mds_lov_disconnect(struct obd_device *obd)
-{
- struct mds_obd *mds = &obd->u.mds;
- int rc = 0;
- ENTRY;
-
- if (!IS_ERR(mds->mds_osc_obd) && mds->mds_osc_exp != NULL) {
- obd_register_observer(mds->mds_osc_obd, NULL);
-
- /* The actual disconnect of the mds_lov will be called from
- * class_disconnect_exports from mds_lov_clean. So we have to
- * ensure that class_cleanup doesn't fail due to the extra ref
- * we're holding now. The mechanism to do that already exists -
- * the obd_force flag. We'll drop the final ref to the
- * mds_osc_exp in mds_cleanup. */
- mds->mds_osc_obd->obd_force = 1;
- }
-
- RETURN(rc);
-}
-
-/* for consistency, let's make the lov and the lov's
- * osc's see the same cleanup flags as our mds */
-void mds_lov_set_cleanup_flags(struct obd_device *obd)
-{
- struct mds_obd *mds = &obd->u.mds;
- struct lov_obd *lov;
-
- if (IS_ERR(mds->mds_osc_obd) || (mds->mds_osc_exp == NULL))
- return;
-
- lov = &mds->mds_osc_obd->u.lov;
- mds->mds_osc_obd->obd_force = obd->obd_force;
- mds->mds_osc_obd->obd_fail = obd->obd_fail;
- if (lov->tgts) {
- struct obd_export *osc_exp;
- int i;
- spin_lock(&lov->lov_lock);
- for (i = 0; i < lov->desc.ld_tgt_count; i++) {
- if (lov->tgts[i].ltd_exp != NULL) {
- osc_exp = lov->tgts[i].ltd_exp;
- osc_exp->exp_obd->obd_force = obd->obd_force;
- osc_exp->exp_obd->obd_fail = obd->obd_fail;
- }
- }
- spin_unlock(&lov->lov_lock);
- }
-}
-
int mds_iocontrol(unsigned int cmd, struct obd_export *exp, int len,
void *karg, void *uarg)
{
EXPORT_SYMBOL(class_setup);
EXPORT_SYMBOL(class_cleanup);
EXPORT_SYMBOL(class_detach);
+EXPORT_SYMBOL(class_manual_cleanup);
#ifdef LPROCFS
int obd_proc_read_version(char *page, char **start, off_t off, int count,
RETURN(rc);
}
+
+/* Cleanup and detach */
+void class_manual_cleanup(struct obd_device *obd, char *flags)
+{
+ struct lustre_cfg *lcfg;
+ struct lustre_cfg_bufs bufs;
+ int err;
+ ENTRY;
+
+ CERROR("Manual cleanup of %s (flags='%s')\n", obd->obd_name, flags);
+
+ lustre_cfg_bufs_reset(&bufs, obd->obd_name);
+ lustre_cfg_bufs_set_string(&bufs, 1, flags);
+ lcfg = lustre_cfg_new(LCFG_CLEANUP, &bufs);
+
+ err = class_process_config(lcfg);
+ if (err)
+ CERROR("cleanup failed %d: %s\n", err, obd->obd_name);
+
+ /* the lcfg is almost the same for both ops */
+ lcfg->lcfg_command = LCFG_DETACH;
+ err = class_process_config(lcfg);
+ lustre_cfg_free(lcfg);
+ if (err)
+ CERROR("detach failed %d: %s\n", err, obd->obd_name);
+ EXIT;
+}
+
class_manual_cleanup(obd, NULL);
}
-//FIXME move to obd_config.c
-int class_manual_cleanup(struct obd_device *obd, char *flags)
-{
- int err, rc = 0;
-
- if (!obd)
- return 0;
-
- err = do_lcfg(obd->obd_name, 0, LCFG_CLEANUP, flags, 0, 0, 0);
- if (err) {
- CERROR("cleanup failed (%d): %s\n", err, obd->obd_name);
- rc = err;
- }
-
- err = do_lcfg(obd->obd_name, 0, LCFG_DETACH, 0, 0, 0, 0);
- if (err) {
- CERROR("detach failed (%d): %s\n", err, obd->obd_name);
- if (!rc)
- rc = err;
- }
-
- return(rc);
-}
-
-
/***************** mount **************/
struct lustre_sb_info *lustre_init_sbi(struct super_block *sb)
}
CERROR("stopping %s\n", logname);
- err = class_manual_cleanup(obd, flags);
- if (err) {
- CERROR("failed to cleanup %s: %d\n", logname, err);
- }
+ class_manual_cleanup(obd, flags);
+
OBD_FREE(dirent, sizeof(*dirent));
}
EXPORT_SYMBOL(lustre_register_client_fill_super);
EXPORT_SYMBOL(lustre_common_put_super);
EXPORT_SYMBOL(lustre_get_process_log);
-EXPORT_SYMBOL(class_manual_cleanup);
EXPORT_SYMBOL(lustre_get_mount);
EXPORT_SYMBOL(lustre_put_mount);