#include <linux/iobuf.h>
#endif
#include <asm/div64.h>
+#include <linux/smp_lock.h>
#else
#include <liblustre.h>
#endif
static struct ec_object *
echo_find_object_locked (struct obd_device *obd, obd_id id)
{
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
struct ec_object *eco = NULL;
struct list_head *el;
echo_copyin_lsm (struct obd_device *obd, struct lov_stripe_md *lsm,
void *ulsm, int ulsm_nob)
{
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
int nob;
if (ulsm_nob < sizeof (*lsm))
static struct ec_object *
echo_allocate_object (struct obd_device *obd)
{
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
struct ec_object *eco;
int rc;
echo_free_object (struct ec_object *eco)
{
struct obd_device *obd = eco->eco_device;
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
LASSERT (eco->eco_refcount == 0);
obd_free_memmd(ec->ec_exp, &eco->eco_lsm);
struct obdo *oa, void *ulsm, int ulsm_nob,
struct obd_trans_info *oti)
{
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
struct ec_object *eco2;
struct ec_object *eco;
struct lov_stripe_md *lsm;
oa->o_id = ++last_object_id;
if (on_target) {
- /* XXX get some filter group constants */
- oa->o_gr = 2;
+ oa->o_gr = FILTER_GROUP_ECHO;
oa->o_valid |= OBD_MD_FLGROUP;
- rc = obd_create(ec->ec_exp, oa, &lsm, oti);
+ rc = obd_create(ec->ec_exp, oa, NULL, 0, &lsm, oti);
if (rc != 0)
goto failed;
echo_get_object (struct ec_object **ecop, struct obd_device *obd,
struct obdo *oa)
{
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
struct ec_object *eco;
struct ec_object *eco2;
int rc;
- if ((oa->o_valid & OBD_MD_FLID) == 0)
+ if ((oa->o_valid & OBD_MD_FLID) == 0 ||
+ oa->o_id == 0) /* disallow use of object id 0 */
{
CERROR ("No valid oid\n");
return (-EINVAL);
echo_put_object (struct ec_object *eco)
{
struct obd_device *obd = eco->eco_device;
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
/* Release caller's ref on the object.
* delete => mark for deletion when last ref goes
*offp = offset * stripe_size + woffset % stripe_size;
}
-static void echo_page_debug_setup(struct lov_stripe_md *lsm,
- struct page *page, int rw, obd_id id,
- obd_off offset, obd_off count)
+static void
+echo_client_page_debug_setup(struct lov_stripe_md *lsm,
+ struct page *page, int rw, obd_id id,
+ obd_off offset, obd_off count)
{
- void *addr;
- obd_off stripe_off;
- obd_id stripe_id;
+ char *addr;
+ obd_off stripe_off;
+ obd_id stripe_id;
+ int delta;
- if (id == 0)
- return;
+ /* no partial pages on the client */
+ LASSERT(count == PAGE_SIZE);
addr = kmap(page);
- if (rw == OBD_BRW_WRITE) {
- stripe_off = offset;
- stripe_id = id;
- echo_get_stripe_off_id(lsm, &stripe_off, &stripe_id);
- } else {
- stripe_off = 0xdeadbeef00c0ffeeULL;
- stripe_id = 0xdeadbeef00c0ffeeULL;
+ for (delta = 0; delta < PAGE_SIZE; delta += OBD_ECHO_BLOCK_SIZE) {
+ if (rw == OBD_BRW_WRITE) {
+ stripe_off = offset + delta;
+ stripe_id = id;
+ echo_get_stripe_off_id(lsm, &stripe_off, &stripe_id);
+ } else {
+ stripe_off = 0xdeadbeef00c0ffeeULL;
+ stripe_id = 0xdeadbeef00c0ffeeULL;
+ }
+ block_debug_setup(addr + delta, OBD_ECHO_BLOCK_SIZE,
+ stripe_off, stripe_id);
}
- page_debug_setup(addr, count, stripe_off, stripe_id);
kunmap(page);
}
-static int echo_page_debug_check(struct lov_stripe_md *lsm,
- struct page *page, obd_id id,
- obd_off offset, obd_off count)
+static int
+echo_client_page_debug_check(struct lov_stripe_md *lsm,
+ struct page *page, obd_id id,
+ obd_off offset, obd_off count)
{
- obd_off stripe_off = offset;
- obd_id stripe_id = id;
- void *addr;
- int rc;
+ obd_off stripe_off;
+ obd_id stripe_id;
+ char *addr;
+ int delta;
+ int rc;
+ int rc2;
- if (id == 0)
- return 0;
+ /* no partial pages on the client */
+ LASSERT(count == PAGE_SIZE);
addr = kmap(page);
- echo_get_stripe_off_id (lsm, &stripe_off, &stripe_id);
- rc = page_debug_check("test_brw", addr, count, stripe_off, stripe_id);
+
+ for (rc = delta = 0; delta < PAGE_SIZE; delta += OBD_ECHO_BLOCK_SIZE) {
+ stripe_off = offset + delta;
+ stripe_id = id;
+ echo_get_stripe_off_id (lsm, &stripe_off, &stripe_id);
+
+ rc2 = block_debug_check("test_brw",
+ addr + delta, OBD_ECHO_BLOCK_SIZE,
+ stripe_off, stripe_id);
+ if (rc2 != 0) {
+ CERROR ("Error in echo object "LPX64"\n", id);
+ rc = rc2;
+ }
+ }
+
kunmap(page);
return rc;
}
struct lov_stripe_md *lsm, obd_off offset,
obd_size count, struct obd_trans_info *oti)
{
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
obd_count npages;
struct brw_page *pga;
struct brw_page *pgp;
int verify = 0;
int gfp_mask;
- /* oa_id == 0 => speed test (no verification) else...
- * oa & 1 => use HIGHMEM
- */
- gfp_mask = ((oa->o_id & 1) == 0) ? GFP_KERNEL : GFP_HIGHUSER;
+ verify = ((oa->o_id) != ECHO_PERSISTENT_OBJID &&
+ (oa->o_valid & OBD_MD_FLFLAGS) != 0 &&
+ (oa->o_flags & OBD_FL_DEBUG_CHECK) != 0);
+
+ gfp_mask = ((oa->o_id & 2) == 0) ? GFP_KERNEL : GFP_HIGHUSER;
LASSERT(rw == OBD_BRW_WRITE || rw == OBD_BRW_READ);
goto out;
pgp->count = PAGE_SIZE;
- pgp->off = off;
+ pgp->disk_offset = pgp->page_offset = off;
pgp->flag = 0;
- echo_page_debug_setup(lsm, pgp->pg, rw, oa->o_id, off,
- pgp->count);
+ if (verify)
+ echo_client_page_debug_setup(lsm, pgp->pg, rw,
+ oa->o_id, off, pgp->count);
}
rc = obd_brw(rw, ec->ec_exp, oa, lsm, npages, pga, oti);
out:
- if (rc == 0 && rw == OBD_BRW_READ)
- verify = 1;
+ if (rc != 0 || rw != OBD_BRW_READ)
+ verify = 0;
for (i = 0, pgp = pga; i < npages; i++, pgp++) {
if (pgp->pg == NULL)
if (verify) {
int vrc;
- vrc = echo_page_debug_check(lsm, pgp->pg, oa->o_id,
- pgp->off, pgp->count);
+ vrc = echo_client_page_debug_check(lsm, pgp->pg, oa->o_id,
+ pgp->page_offset,
+ pgp->count);
if (vrc != 0 && rc == 0)
rc = vrc;
}
obd_off offset, obd_size count, char *buffer,
struct obd_trans_info *oti)
{
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
obd_count npages;
struct brw_page *pga;
struct brw_page *pgp;
for (i = 0, off = offset, pgp = pga;
i < npages;
i++, off += PAGE_SIZE, pgp++) {
- pgp->off = off;
+ pgp->disk_offset = pgp->page_offset = off;
pgp->pg = kiobuf->maplist[i];
pgp->count = PAGE_SIZE;
pgp->flag = 0;
struct list_head eap_item;
};
+#define EAP_FROM_COOKIE(c) \
+ (LASSERT(((struct echo_async_page *)(c))->eap_magic == EAP_MAGIC), \
+ (struct echo_async_page *)(c))
+
struct echo_async_state {
spinlock_t eas_lock;
obd_off eas_next_offset;
return rc;
};
-struct echo_async_page *eap_from_cookie(void *cookie)
-{
- struct echo_async_page *eap = cookie;
- if (eap->eap_magic != EAP_MAGIC)
- return ERR_PTR(-EINVAL);
- return eap;
-};
-
static int ec_ap_make_ready(void *data, int cmd)
{
/* our pages are issued ready */
}
static void ec_ap_fill_obdo(void *data, int cmd, struct obdo *oa)
{
- struct echo_async_page *eap;
- eap = eap_from_cookie(data);
- if (IS_ERR(eap))
- return;
+ struct echo_async_page *eap = EAP_FROM_COOKIE(data);
memcpy(oa, &eap->eap_eas->eas_oa, sizeof(*oa));
}
-static void ec_ap_completion(void *data, int cmd, int rc)
+
+static void ec_ap_completion(void *data, int cmd, struct obdo *oa, int rc)
{
- struct echo_async_page *eap = eap_from_cookie(data);
+ struct echo_async_page *eap = EAP_FROM_COOKIE(data);
struct echo_async_state *eas;
unsigned long flags;
- if (IS_ERR(eap))
- return;
eas = eap->eap_eas;
- if (cmd == OBD_BRW_READ)
- echo_page_debug_check(eas->eas_lsm, eap->eap_page,
- eas->eas_oa.o_id, eap->eap_off,
- PAGE_SIZE);
+ if (cmd == OBD_BRW_READ &&
+ eas->eas_oa.o_id != ECHO_PERSISTENT_OBJID &&
+ (eas->eas_oa.o_valid & OBD_MD_FLFLAGS) != 0 &&
+ (eas->eas_oa.o_flags & OBD_FL_DEBUG_CHECK) != 0)
+ echo_client_page_debug_check(eas->eas_lsm, eap->eap_page,
+ eas->eas_oa.o_id, eap->eap_off,
+ PAGE_SIZE);
spin_lock_irqsave(&eas->eas_lock, flags);
if (rc && !eas->eas_rc)
GOTO(out, rc = -ENOMEM);
page->private = 0;
- list_add_tail(&page->list, &pages);
+ list_add_tail(&PAGE_LIST(page), &pages);
OBD_ALLOC(eap, sizeof(*eap));
if (eap == NULL)
break;
}
- if (rw == OBD_BRW_WRITE)
- echo_page_debug_setup(lsm, eap->eap_page, rw, oa->o_id,
- eap->eap_off, PAGE_SIZE);
+ if (oa->o_id != ECHO_PERSISTENT_OBJID &&
+ (oa->o_valid & OBD_MD_FLFLAGS) != 0 &&
+ (oa->o_flags & OBD_FL_DEBUG_CHECK) != 0)
+ echo_client_page_debug_setup(lsm, eap->eap_page, rw,
+ oa->o_id,
+ eap->eap_off, PAGE_SIZE);
/* always asserts urgent, which isn't quite right */
rc = obd_queue_async_io(exp, lsm, NULL, eap->eap_cookie,
out:
list_for_each_safe(pos, n, &pages) {
- struct page *page = list_entry(pos, struct page, list);
+ struct page *page = list_entry(pos, struct page,
+ PAGE_LIST_ENTRY);
- list_del(&page->list);
+ list_del(&PAGE_LIST(page));
if (page->private != 0) {
eap = (struct echo_async_page *)page->private;
if (eap->eap_cookie != NULL)
struct niobuf_remote *rnb;
obd_off off;
obd_size npages, tot_pages;
- int i, ret = 0, err = 0;
+ int i, ret = 0;
ENTRY;
if (count <= 0 || (count & (PAGE_SIZE - 1)) != 0 ||
struct page *page = lnb[i].page;
/* read past eof? */
- if (page == NULL && lnb[i].rc == 0)
+ if (page == NULL && lnb[i].rc == 0)
+ continue;
+
+ if (oa->o_id == ECHO_PERSISTENT_OBJID ||
+ (oa->o_valid & OBD_MD_FLFLAGS) == 0 ||
+ (oa->o_flags & OBD_FL_DEBUG_CHECK) == 0)
continue;
- if (rw == OBD_BRW_WRITE)
- echo_page_debug_setup(lsm, page, rw, oa->o_id,
- rnb[i].offset,
- rnb[i].len);
+
+ if (rw == OBD_BRW_WRITE)
+ echo_client_page_debug_setup(lsm, page, rw,
+ oa->o_id,
+ rnb[i].offset,
+ rnb[i].len);
else
- echo_page_debug_check(lsm, page, oa->o_id,
- rnb[i].offset,
- rnb[i].len);
+ echo_client_page_debug_check(lsm, page,
+ oa->o_id,
+ rnb[i].offset,
+ rnb[i].len);
}
- ret = obd_commitrw(rw, exp, oa, 1, &ioo, npages, lnb, oti);
+ ret = obd_commitrw(rw, exp, oa, 1, &ioo, npages, lnb, oti, ret);
if (ret != 0)
GOTO(out, ret);
- if (err)
- GOTO(out, ret = err);
}
out:
RETURN(ret);
}
-int echo_client_brw_ioctl(int rw, struct obd_export *exp,
+int echo_client_brw_ioctl(int rw, struct obd_export *exp,
struct obd_ioctl_data *data)
{
struct obd_device *obd = class_exp2obd(exp);
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
struct obd_trans_info dummy_oti;
struct ec_object *eco;
int rc;
data->ioc_obdo1.o_valid &= ~OBD_MD_FLHANDLE;
data->ioc_obdo1.o_valid |= OBD_MD_FLGROUP;
- data->ioc_obdo1.o_gr = 2;
+ data->ioc_obdo1.o_gr = FILTER_GROUP_ECHO;
switch((long)data->ioc_pbuf1) {
case 1:
void *data, int flag)
{
struct ec_object *eco = (struct ec_object *)data;
- struct echo_client_obd *ec = &(eco->eco_device->u.echo_client);
+ struct echo_client_obd *ec = &(eco->eco_device->u.echocli);
struct lustre_handle lockh;
struct list_head *el;
int found = 0;
int mode, obd_off offset, obd_size nob)
{
struct obd_device *obd = exp->exp_obd;
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
struct lustre_handle *ulh = obdo_handle (oa);
struct ec_object *eco;
struct ec_lock *ecl;
ecl->ecl_mode = mode;
ecl->ecl_object = eco;
- ecl->ecl_extent.start = offset;
- ecl->ecl_extent.end = (nob == 0) ? ((obd_off) -1) : (offset + nob - 1);
+ ecl->ecl_policy.l_extent.start = offset;
+ ecl->ecl_policy.l_extent.end =
+ (nob == 0) ? ((obd_off) -1) : (offset + nob - 1);
flags = 0;
- rc = obd_enqueue(ec->ec_exp, eco->eco_lsm, NULL, LDLM_EXTENT,
- &ecl->ecl_extent,sizeof(ecl->ecl_extent), mode,
- &flags, echo_ldlm_callback, eco,
- &ecl->ecl_lock_handle);
+ rc = obd_enqueue(ec->ec_exp, eco->eco_lsm, LDLM_EXTENT,
+ &ecl->ecl_policy, mode, &flags, echo_ldlm_callback,
+ ldlm_completion_ast, NULL, eco, sizeof(struct ost_lvb),
+ lustre_swab_ost_lvb, &ecl->ecl_lock_handle);
if (rc != 0)
goto failed_1;
echo_client_cancel(struct obd_export *exp, struct obdo *oa)
{
struct obd_device *obd = exp->exp_obd;
- struct echo_client_obd *ec = &obd->u.echo_client;
+ struct echo_client_obd *ec = &obd->u.echocli;
struct lustre_handle *ulh = obdo_handle (oa);
struct ec_lock *ecl = NULL;
int found = 0;
int i;
ENTRY;
+ unlock_kernel();
+
memset(&dummy_oti, 0, sizeof(dummy_oti));
obd = exp->exp_obd;
- ec = &obd->u.echo_client;
+ ec = &obd->u.echocli;
switch (cmd) {
case OBD_IOC_CREATE: /* may create echo object */
rc = echo_get_object (&eco, obd, &data->ioc_obdo1);
if (rc == 0) {
oa = &data->ioc_obdo1;
- oa->o_gr = 2;
+ oa->o_gr = FILTER_GROUP_ECHO;
oa->o_valid |= OBD_MD_FLGROUP;
rc = obd_destroy(ec->ec_exp, oa, eco->eco_lsm,
&dummy_oti);
ldlm_lock_decref(&ack_lock->lock, ack_lock->mode);
}
+ lock_kernel();
+
return rc;
}
echo_client_setup(struct obd_device *obddev, obd_count len, void *buf)
{
struct lustre_cfg* lcfg = buf;
- struct echo_client_obd *ec = &obddev->u.echo_client;
+ struct echo_client_obd *ec = &obddev->u.echocli;
struct obd_device *tgt;
struct lustre_handle conn = {0, };
struct obd_uuid echo_uuid = { "ECHO_UUID" };
INIT_LIST_HEAD (&ec->ec_objects);
ec->ec_unique = 0;
- rc = obd_connect(&conn, tgt, &echo_uuid);
+ rc = obd_connect(&conn, tgt, &echo_uuid, NULL, FILTER_GROUP_ECHO);
if (rc) {
CERROR("fail to connect to device %s\n", lcfg->lcfg_inlbuf1);
return (rc);
{
struct list_head *el;
struct ec_object *eco;
- struct echo_client_obd *ec = &obddev->u.echo_client;
+ struct echo_client_obd *ec = &obddev->u.echocli;
int rc;
ENTRY;
}
static int echo_client_connect(struct lustre_handle *conn,
- struct obd_device *src, struct obd_uuid *cluuid)
+ struct obd_device *src,
+ struct obd_uuid *cluuid,
+ struct obd_connect_data *data,
+ unsigned long flags)
{
struct obd_export *exp;
int rc;
RETURN (rc);
}
-static int echo_client_disconnect(struct obd_export *exp, int flags)
+static int echo_client_disconnect(struct obd_export *exp,
+ unsigned long flags)
{
struct obd_device *obd;
struct echo_client_obd *ec;
GOTO(out, rc = -EINVAL);
obd = exp->exp_obd;
- ec = &obd->u.echo_client;
+ ec = &obd->u.echocli;
/* no more contention on export's lock list */
while (!list_empty (&exp->exp_ec_data.eced_locks)) {
}
static struct obd_ops echo_obd_ops = {
- o_owner: THIS_MODULE,
- o_setup: echo_client_setup,
- o_cleanup: echo_client_cleanup,
- o_iocontrol: echo_client_iocontrol,
- o_connect: echo_client_connect,
- o_disconnect: echo_client_disconnect
+ .o_owner = THIS_MODULE,
+ .o_setup = echo_client_setup,
+ .o_cleanup = echo_client_cleanup,
+ .o_iocontrol = echo_client_iocontrol,
+ .o_connect = echo_client_connect,
+ .o_disconnect = echo_client_disconnect
};
int echo_client_init(void)
struct lprocfs_static_vars lvars;
lprocfs_init_vars(echo, &lvars);
- return class_register_type(&echo_obd_ops, lvars.module_vars,
+ return class_register_type(&echo_obd_ops, NULL, lvars.module_vars,
OBD_ECHO_CLIENT_DEVICENAME);
}