* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
/* NULL watched means all osc's in the lov (only for syncs) */
/* sync event should be send lov idx as data */
struct lov_obd *lov = &obd->u.lov;
- struct obd_device *tgt_obd;
- int i;
+ int i, is_sync;
+
+ data = &i;
+ is_sync = (ev == OBD_NOTIFY_SYNC) ||
+ (ev == OBD_NOTIFY_SYNC_NONBLOCK);
+
obd_getref(obd);
for (i = 0; i < lov->desc.ld_tgt_count; i++) {
+ if (!lov->lov_tgts[i])
+ continue;
+
/* don't send sync event if target not
* connected/activated */
- if (!lov->lov_tgts[i] ||
- !lov->lov_tgts[i]->ltd_active)
- continue;
-
- if ((ev == OBD_NOTIFY_SYNC) ||
- (ev == OBD_NOTIFY_SYNC_NONBLOCK))
- data = &i;
-
- tgt_obd = class_exp2obd(lov->lov_tgts[i]->ltd_exp);
+ if (is_sync && !lov->lov_tgts[i]->ltd_active)
+ continue;
- rc = obd_notify_observer(obd, tgt_obd, ev, data);
+ rc = obd_notify_observer(obd, lov->lov_tgts[i]->ltd_obd,
+ ev, data);
if (rc) {
CERROR("%s: notify %s of %s failed %d\n",
obd->obd_name,
obd->obd_observer->obd_name,
- tgt_obd->obd_name, rc);
- break;
+ lov->lov_tgts[i]->ltd_obd->obd_name,
+ rc);
}
}
obd_putref(obd);
RETURN(rc);
}
-int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
- __u32 index, int gen, int active)
+static int lov_add_target(struct obd_device *obd, struct obd_uuid *uuidp,
+ __u32 index, int gen, int active)
{
struct lov_obd *lov = &obd->u.lov;
struct lov_tgt_desc *tgt;
RETURN(rc);
}
- memset(tgt, 0, sizeof(*tgt));
tgt->ltd_uuid = *uuidp;
tgt->ltd_obd = tgt_obd;
/* XXX - add a sanity check on the generation number. */
CDEBUG(D_CONFIG, "idx=%d ltd_gen=%d ld_tgt_count=%d\n",
index, tgt->ltd_gen, lov->desc.ld_tgt_count);
+ rc = obd_notify(obd, tgt_obd, OBD_NOTIFY_CREATE, &index);
+
if (lov->lov_connects == 0) {
/* lov_connect hasn't been called yet. We'll do the
lov_connect_obd on this target when that fn first runs,
lov->lov_pools_hash_body = cfs_hash_create("POOLS", HASH_POOLS_CUR_BITS,
HASH_POOLS_MAX_BITS,
- &pool_hash_operations, CFS_HASH_REHASH);
+ HASH_POOLS_BKT_BITS, 0,
+ CFS_HASH_MIN_THETA,
+ CFS_HASH_MAX_THETA,
+ &pool_hash_operations,
+ CFS_HASH_DEFAULT);
CFS_INIT_LIST_HEAD(&lov->lov_pool_list);
lov->lov_pool_count = 0;
rc = lov_ost_pool_init(&lov->lov_packed, 0);
if (rc)
- RETURN(rc);
+ GOTO(out_free_statfs, rc);
rc = lov_ost_pool_init(&lov->lov_qos.lq_rr.lqr_pool, 0);
- if (rc) {
- lov_ost_pool_free(&lov->lov_packed);
- RETURN(rc);
- }
+ if (rc)
+ GOTO(out_free_lov_packed, rc);
lprocfs_lov_init_vars(&lvars);
lprocfs_obd_setup(obd, lvars.obd_vars);
NULL, NULL);
RETURN(0);
+
+out_free_lov_packed:
+ lov_ost_pool_free(&lov->lov_packed);
+out_free_statfs:
+ OBD_FREE_PTR(lov->lov_qos.lq_statfs_data);
+ return rc;
}
static int lov_precleanup(struct obd_device *obd, enum obd_cleanup_stage stage)
* later in alloc_qos(), we will wait for those rpcs to complete if
* the osfs age is older than 2 * qos_maxage */
qos_statfs_update(exp->exp_obd,
- cfs_time_shift_64(-lov->desc.ld_qos_maxage) + CFS_HZ,
+ cfs_time_shift_64(-lov->desc.ld_qos_maxage +
+ OBD_STATFS_CACHE_SECONDS),
0);
rc = lov_prep_create_set(exp, &oinfo, ea, src_oa, oti, &set);
/* got statfs data */
rc = obd_statfs(osc_obd, &stat_buf,
- cfs_time_current_64() - CFS_HZ, 0);
+ cfs_time_shift_64(-OBD_STATFS_CACHE_SECONDS),
+ 0);
if (rc)
RETURN(rc);
if (cfs_copy_to_user(data->ioc_pbuf1, &stat_buf,
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;
+ /* ll_umount_begin() sets force flag but for lov, not
+ * osc. Let's pass it through */
+ osc_obd = class_exp2obd(lov->lov_tgts[i]->ltd_exp);
+ osc_obd->obd_force = obddev->obd_force;
err = obd_iocontrol(cmd, lov->lov_tgts[i]->ltd_exp,
len, karg, uarg);
if (err == -ENODATA && cmd == OBD_IOC_POLL_QUOTACHECK) {
} else if (KEY_IS(KEY_FIEMAP)) {
rc = lov_fiemap(lov, keylen, key, vallen, val, lsm);
GOTO(out, rc);
+ } else if (KEY_IS(KEY_CONNECT_FLAG)) {
+ struct lov_tgt_desc *tgt;
+ __u64 ost_idx = *((__u64*)val);
+
+ LASSERT(*vallen == sizeof(__u64));
+ LASSERT(ost_idx < lov->desc.ld_tgt_count);
+ tgt = lov->lov_tgts[ost_idx];
+
+ if (!tgt || !tgt->ltd_exp)
+ GOTO(out, rc = -ESRCH);
+
+ *((__u64*)val) = tgt->ltd_exp->exp_connect_flags;
+ GOTO(out, rc = 0);
}
rc = -EINVAL;