ENTRY;
LASSERT(!obd->obd_recovering);
-
LASSERT(mds->mds_lov_objids != NULL);
+
+ /* obd->obd_dev_sem must be held so mds_lov_objids doesn't change */
+ LASSERT_SEM_LOCKED(&obd->obd_dev_sem);
rc = obd_set_info_async(mds->mds_osc_exp, strlen(KEY_NEXT_ID),
KEY_NEXT_ID,
/* If we added a target we have to reconnect the llogs */
/* We only _need_ to do this at first add (idx), or the first time
after recovery. However, it should now be safe to call anytime. */
- mutex_down(&obd->obd_dev_sem);
llog_cat_initialize(obd, NULL, mds->mds_lov_desc.ld_tgt_count, NULL);
- mutex_up(&obd->obd_dev_sem);
/*XXX this notifies the MDD until lov handling use old mds code */
if (obd->obd_upcall.onu_owner) {
int rc = 0;
ENTRY;
+ /* Don't let anyone else mess with mds_lov_objids now */
+ mutex_down(&obd->obd_dev_sem);
+
old_count = mds->mds_lov_desc.ld_tgt_count;
rc = mds_lov_update_desc(obd, mds->mds_osc_exp);
- if (rc)
- RETURN(rc);
+ if (rc)
+ GOTO(out, rc);
CDEBUG(D_CONFIG, "idx=%d, recov=%d/%d, cnt=%d/%d\n",
idx, obd->obd_recovering, obd->obd_async_recov, old_count,
mds->mds_lov_desc.ld_tgt_count);
/* idx is set as data from lov_notify. */
- if (idx != MDSLOV_NO_INDEX && !obd->obd_recovering) {
- if (idx >= mds->mds_lov_desc.ld_tgt_count) {
- CERROR("index %d > count %d!\n", idx,
- mds->mds_lov_desc.ld_tgt_count);
- RETURN(-EINVAL);
- }
-
- if (idx >= mds->mds_lov_objids_in_file) {
- /* We never read this lastid; ask the osc */
- obd_id lastid;
- __u32 size = sizeof(lastid);
- rc = obd_get_info(watched->obd_self_export,
- strlen("last_id"),
- "last_id", &size, &lastid);
- if (rc)
- RETURN(rc);
- mds->mds_lov_objids[idx] = lastid;
- mds->mds_lov_objids_dirty = 1;
- mds_lov_write_objids(obd);
- } else {
- /* We have read this lastid from disk; tell the osc.
- Don't call this during recovery. */
- rc = mds_lov_set_nextid(obd);
+ if (idx == MDSLOV_NO_INDEX || obd->obd_recovering)
+ GOTO(out, rc);
+
+ if (idx >= mds->mds_lov_desc.ld_tgt_count) {
+ CERROR("index %d > count %d!\n", idx,
+ mds->mds_lov_desc.ld_tgt_count);
+ GOTO(out, rc = -EINVAL);
+ }
+
+ if (idx >= mds->mds_lov_objids_in_file) {
+ /* We never read this lastid; ask the osc */
+ obd_id lastid;
+ __u32 size = sizeof(lastid);
+ rc = obd_get_info(watched->obd_self_export, strlen("last_id"),
+ "last_id", &size, &lastid);
+ if (rc)
+ GOTO(out, rc);
+ mds->mds_lov_objids[idx] = lastid;
+ mds->mds_lov_objids_dirty = 1;
+ mds_lov_write_objids(obd);
+ } else {
+ /* We have read this lastid from disk; tell the osc.
+ Don't call this during recovery. */
+ rc = mds_lov_set_nextid(obd);
+ if (rc) {
+ CERROR("Failed to set next id, idx=%d rc=%d\n", idx,rc);
+ /* Don't abort the rest of the sync */
+ rc = 0;
}
-
- CDEBUG(D_CONFIG, "last object "LPU64" from OST %d\n",
- mds->mds_lov_objids[idx], idx);
}
+ CDEBUG(D_CONFIG, "last object "LPU64" from OST %d rc=%d\n",
+ mds->mds_lov_objids[idx], idx, rc);
+out:
+ mutex_up(&obd->obd_dev_sem);
RETURN(rc);
}
/* Deny new client connections until we are sure we have some OSTs */
obd->obd_no_conn = 1;
+ mutex_down(&obd->obd_dev_sem);
rc = mds_lov_read_objids(obd);
if (rc) {
CERROR("cannot read %s: rc = %d\n", "lov_objids", rc);
"writing objids file: %d\n", rc);
}
}
+ mutex_up(&obd->obd_dev_sem);
/* I want to see a callback happen when the OBD moves to a
* "For General Use" state, and that's when we'll call
RETURN(rc);
err_reg:
+ mutex_up(&obd->obd_dev_sem);
obd_register_observer(mds->mds_osc_obd, NULL);
err_discon:
obd_disconnect(mds->mds_osc_exp);
uuid = &watched->u.cli.cl_target_uuid;
LASSERT(uuid);
+ OBD_RACE(OBD_FAIL_MDS_LOV_SYNC_RACE);
+
rc = mds_lov_update_mds(obd, watched, idx, uuid);
if (rc != 0) {
CERROR("%s failed at update_mds: %d\n", obd_uuid2str(uuid), rc);
NULL, NULL, uuid);
if (rc != 0) {
- CERROR("%s: failed at llog_origin_connect: %d\n",
- obd->obd_name, rc);
+ CERROR("%s failed at llog_origin_connect: %d\n",
+ obd_uuid2str(uuid), rc);
GOTO(out, rc);
}
}
EXIT;
out:
+ if (rc) {
+ /* Deactivate it for safety */
+ CERROR("%s sync failed %d, deactivating\n", obd_uuid2str(uuid),
+ rc);
+ if (!obd->obd_stopping && mds->mds_osc_obd &&
+ !mds->mds_osc_obd->obd_stopping && !watched->obd_stopping)
+ obd_notify(mds->mds_osc_obd, watched,
+ OBD_NOTIFY_INACTIVE, NULL);
+ }
+
class_decref(obd);
return rc;
}
/* We still have to fix the lov descriptor for ost's added
after the mdt in the config log. They didn't make it into
mds_lov_connect. */
+ mutex_down(&obd->obd_dev_sem);
rc = mds_lov_update_desc(obd, obd->u.mds.mds_osc_exp);
- if (rc)
+ if (rc) {
+ mutex_up(&obd->obd_dev_sem);
RETURN(rc);
+ }
/* We should update init llog here too for replay unlink and
* possiable llog init race when recovery complete */
- mutex_down(&obd->obd_dev_sem);
llog_cat_initialize(obd, NULL,
obd->u.mds.mds_lov_desc.ld_tgt_count,
&watched->u.cli.cl_target_uuid);
spin_lock(&oscc->oscc_lock);
oscc->oscc_flags &= ~OSCC_FLAG_CREATING;
- if (rc == -ENOSPC || rc == -EROFS) {
+ switch (rc) {
+ case 0: {
+ if (body) {
+ int diff = body->oa.o_id - oscc->oscc_last_id;
+
+ if (diff < oscc->oscc_grow_count)
+ oscc->oscc_grow_count =
+ max(diff/3, OST_MIN_PRECREATE);
+ else
+ oscc->oscc_flags &= ~OSCC_FLAG_LOW;
+ oscc->oscc_last_id = body->oa.o_id;
+ }
+ spin_unlock(&oscc->oscc_lock);
+ break;
+ }
+ case -ENOSPC:
+ case -EROFS: {
oscc->oscc_flags |= OSCC_FLAG_NOSPC;
if (body && rc == -ENOSPC) {
oscc->oscc_grow_count = OST_MIN_PRECREATE;
}
spin_unlock(&oscc->oscc_lock);
DEBUG_REQ(D_INODE, req, "OST out of space, flagging");
- } else if (rc != 0 && rc != -EIO) {
+ break;
+ }
+ case -EIO: {
+ /* filter always set body->oa.o_id as the last_id
+ * of filter (see filter_handle_precreate for detail)*/
+ if (body && body->oa.o_id > oscc->oscc_last_id)
+ oscc->oscc_last_id = body->oa.o_id;
+ spin_unlock(&oscc->oscc_lock);
+ break;
+ }
+ default: {
oscc->oscc_flags |= OSCC_FLAG_RECOVERING;
oscc->oscc_grow_count = OST_MIN_PRECREATE;
spin_unlock(&oscc->oscc_lock);
"Unknown rc %d from async create: failing oscc", rc);
ptlrpc_fail_import(req->rq_import,
lustre_msg_get_conn_cnt(req->rq_reqmsg));
- } else {
- if (rc == 0) {
- if (body) {
- int diff = body->oa.o_id - oscc->oscc_last_id;
-
- if (diff < oscc->oscc_grow_count)
- oscc->oscc_grow_count =
- max(diff/3, OST_MIN_PRECREATE);
- else
- oscc->oscc_flags &= ~OSCC_FLAG_LOW;
- oscc->oscc_last_id = body->oa.o_id;
- }
- } else {
- /* filter always set body->oa.o_id as the last_id
- * of filter (see filter_handle_precreate for detail)*/
- if (body && body->oa.o_id > oscc->oscc_last_id)
- oscc->oscc_last_id = body->oa.o_id;
- }
- spin_unlock(&oscc->oscc_lock);
-
+ }
}
CDEBUG(D_HA, "preallocated through id "LPU64" (next to use "LPU64")\n",