static int lov_disconnect_obd(struct obd_device *obd, struct lov_tgt_desc *tgt)
{
- struct lov_obd *lov = &obd->u.lov;
- struct obd_device *osc_obd;
- int rc;
- ENTRY;
+ struct lov_obd *lov = &obd->u.lov;
+ struct obd_device *osc_obd;
+ int rc;
+ ENTRY;
- osc_obd = class_exp2obd(tgt->ltd_exp);
- CDEBUG(D_CONFIG, "%s: disconnecting target %s\n",
- obd->obd_name, osc_obd->obd_name);
+ osc_obd = class_exp2obd(tgt->ltd_exp);
+ CDEBUG(D_CONFIG, "%s: disconnecting target %s\n", obd->obd_name,
+ osc_obd ? osc_obd->obd_name : "<no obd>");
- if (tgt->ltd_active) {
- tgt->ltd_active = 0;
- lov->desc.ld_active_tgt_count--;
- tgt->ltd_exp->exp_obd->obd_inactive = 1;
- }
+ if (tgt->ltd_active) {
+ tgt->ltd_active = 0;
+ lov->desc.ld_active_tgt_count--;
+ tgt->ltd_exp->exp_obd->obd_inactive = 1;
+ }
if (osc_obd) {
if (lov->lov_tgts_kobj)
lov->targets_proc_entry);
}
- obd_register_observer(osc_obd, NULL);
+ obd_register_observer(osc_obd, NULL);
- rc = obd_disconnect(tgt->ltd_exp);
- if (rc) {
- CERROR("Target %s disconnect error %d\n",
- tgt->ltd_uuid.uuid, rc);
- rc = 0;
- }
+ rc = obd_disconnect(tgt->ltd_exp);
+ if (rc) {
+ CERROR("Target %s disconnect error %d\n",
+ tgt->ltd_uuid.uuid, rc);
+ rc = 0;
+ }
- tgt->ltd_exp = NULL;
- RETURN(0);
+ tgt->ltd_exp = NULL;
+ RETURN(0);
}
static int lov_disconnect(struct obd_export *exp)
continue;
/* Inactive targets may never have connected */
- if (lov->lov_tgts[i]->ltd_active ||
- atomic_read(&lov->lov_refcount))
+ if (lov->lov_tgts[i]->ltd_active)
/* We should never get here - these
* should have been removed in the
* disconnect. */
OBD_FREE_PTR(oqctl);
break;
}
- default: {
- int set = 0;
+ default: {
+ int set = 0;
- if (count == 0)
- RETURN(-ENOTTY);
+ if (count == 0)
+ RETURN(-ENOTTY);
- for (i = 0; i < count; i++) {
- int err;
- struct obd_device *osc_obd;
+ for (i = 0; i < count; i++) {
+ int err;
+ struct obd_device *osc_obd;
- /* OST was disconnected */
- if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_exp)
- continue;
+ /* OST was disconnected */
+ if (!lov->lov_tgts[i] || !lov->lov_tgts[i]->ltd_exp)
+ continue;
/* ll_umount_begin() sets force on lov, pass to osc */
osc_obd = class_exp2obd(lov->lov_tgts[i]->ltd_exp);
- osc_obd->obd_force = obd->obd_force;
+ if (osc_obd)
+ osc_obd->obd_force = obd->obd_force;
err = obd_iocontrol(cmd, lov->lov_tgts[i]->ltd_exp,
len, karg, uarg);
if (err) {
- if (lov->lov_tgts[i]->ltd_active) {
- CDEBUG(err == -ENOTTY ?
- D_IOCTL : D_WARNING,
- "iocontrol OSC %s on OST "
- "idx %d cmd %x: err = %d\n",
- lov_uuid2str(lov, i),
- i, cmd, err);
- if (!rc)
- rc = err;
- }
- } else {
- set = 1;
- }
- }
- if (!set && !rc)
- rc = -EIO;
- }
- }
+ if (lov->lov_tgts[i]->ltd_active) {
+ CDEBUG(err == -ENOTTY ?
+ D_IOCTL : D_WARNING,
+ "iocontrol OSC %s on OST idx %d cmd %x: err = %d\n",
+ lov_uuid2str(lov, i),
+ i, cmd, err);
+ if (!rc)
+ rc = err;
+ }
+ } else {
+ set = 1;
+ }
+ }
+ if (!set && !rc)
+ rc = -EIO;
+ }
+ }
- RETURN(rc);
+ RETURN(rc);
}
static int lov_get_info(const struct lu_env *env, struct obd_export *exp,
}
static int lov_quotactl(struct obd_device *obd, struct obd_export *exp,
- struct obd_quotactl *oqctl)
+ struct obd_quotactl *oqctl)
{
- struct lov_obd *lov = &obd->u.lov;
- struct lov_tgt_desc *tgt;
- __u64 curspace = 0;
- __u64 bhardlimit = 0;
- int i, rc = 0;
- ENTRY;
+ struct lov_obd *lov = &obd->u.lov;
+ struct lov_tgt_desc *tgt;
+ struct pool_desc *pool = NULL;
+ __u64 curspace = 0;
+ __u64 bhardlimit = 0;
+ int i, rc = 0;
+ ENTRY;
if (oqctl->qc_cmd != Q_GETOQUOTA &&
- oqctl->qc_cmd != LUSTRE_Q_SETQUOTA) {
- CERROR("%s: bad quota opc %x for lov obd\n",
- obd->obd_name, oqctl->qc_cmd);
- RETURN(-EFAULT);
+ oqctl->qc_cmd != LUSTRE_Q_SETQUOTA &&
+ oqctl->qc_cmd != LUSTRE_Q_GETQUOTAPOOL) {
+ rc = -EFAULT;
+ CERROR("%s: bad quota opc %x for lov obd: rc = %d\n",
+ obd->obd_name, oqctl->qc_cmd, rc);
+ RETURN(rc);
+ }
+
+ if (oqctl->qc_cmd == LUSTRE_Q_GETQUOTAPOOL) {
+ pool = lov_pool_find(obd, oqctl->qc_poolname);
+ if (!pool)
+ RETURN(-ENOENT);
+ /* Set Q_GETOQUOTA back as targets report it's own
+ * usage and doesn't care about pools */
+ oqctl->qc_cmd = Q_GETOQUOTA;
}
/* for lov tgt */
if (!tgt)
continue;
- if (!tgt->ltd_active || tgt->ltd_reap) {
- if (oqctl->qc_cmd == Q_GETOQUOTA &&
- lov->lov_tgts[i]->ltd_activate) {
+ if (pool &&
+ tgt_check_index(tgt->ltd_index, &pool->pool_obds))
+ continue;
+
+ if (!tgt->ltd_active || tgt->ltd_reap) {
+ if (oqctl->qc_cmd == Q_GETOQUOTA &&
+ lov->lov_tgts[i]->ltd_activate) {
rc = -ENETDOWN;
- CERROR("ost %d is inactive\n", i);
- } else {
- CDEBUG(D_HA, "ost %d is inactive\n", i);
- }
- continue;
- }
+ CERROR("%s: ost %d is inactive: rc = %d\n",
+ obd->obd_name, i, rc);
+ } else {
+ CDEBUG(D_HA, "ost %d is inactive\n", i);
+ }
+ continue;
+ }
err = obd_quotactl(tgt->ltd_exp, oqctl);
if (err) {
}
}
lov_tgts_putref(obd);
+ if (pool)
+ lov_pool_putref(pool);
if (oqctl->qc_cmd == Q_GETOQUOTA) {
oqctl->qc_dqblk.dqb_curspace = curspace;