+/* Error codes:
+ *
+ * -EINVAL : UUID can't be found in the LOV's target list
+ * -ENOTCONN: The UUID is found, but the target connection is bad (!)
+ * -EBADF : The UUID is found, but the OBD is the wrong type (!)
+ * -EALREADY: The OSC is already marked (in)active
+ */
+static int lov_set_osc_active(struct lov_obd *lov, obd_uuid_t uuid,
+ int activate)
+{
+ struct obd_device *obd;
+ int i, rc = 0;
+ ENTRY;
+
+ CDEBUG(D_INFO, "Searching in lov %p for uuid %s (activate=%d)\n",
+ lov, uuid, activate);
+
+ spin_lock(&lov->lov_lock);
+ for (i = 0; i < lov->desc.ld_tgt_count; i++)
+ if (strncmp(uuid, lov->tgts[i].uuid,
+ sizeof(lov->tgts[i].uuid)) == 0)
+ break;
+
+ if (i == lov->desc.ld_tgt_count)
+ GOTO(out, rc = -EINVAL);
+
+ obd = class_conn2obd(&lov->tgts[i].conn);
+ if (obd == NULL) {
+ LBUG();
+ GOTO(out, rc = -ENOTCONN);
+ }
+
+ CDEBUG(D_INFO, "Found OBD %p type %s\n", obd, obd->obd_type->typ_name);
+ if (strcmp(obd->obd_type->typ_name, "osc") != 0) {
+ LBUG();
+ GOTO(out, rc = -EBADF);
+ }
+
+ if (lov->tgts[i].active == activate) {
+ CDEBUG(D_INFO, "OBD %p already %sactive!\n", obd,
+ activate ? "" : "in");
+ GOTO(out, rc = -EALREADY);
+ }
+
+ CDEBUG(D_INFO, "Marking OBD %p %sactive\n", obd, activate ? "" : "in");
+
+ lov->tgts[i].active = activate;
+ if (activate)
+ lov->desc.ld_active_tgt_count++;
+ else
+ lov->desc.ld_active_tgt_count--;
+
+ EXIT;
+ out:
+ spin_unlock(&lov->lov_lock);
+ return rc;
+}
+