int dump_ioo(struct obd_ioobj *nb);
int dump_req(struct ptlrpc_request *req);
int dump_obdo(struct obdo *oa);
+int page_debug_setup(void *addr, int len, __u64 off, __u64 id);
+int page_debug_check(char *who, void *addr, int len, __u64 off, __u64 id);
#endif
int (*o_cancel)(struct lustre_handle *, struct lov_stripe_md *md, __u32 mode, struct lustre_handle *);
};
+/* FIXME: for 64-bit arch */
+#define LPU64 "%Lu"
+#define LPD64 "%Ld"
+#define LPX64 "%Lx"
+
#endif
#define DEBUG_SUBSYSTEM D_OTHER
+#define EXPORT_SYMTAB
#include <linux/obd_ost.h>
#include <linux/lustre_debug.h>
+#include <linux/lustre_net.h>
int dump_ioo(struct obd_ioobj *ioo)
{
}
/* XXX assumes only a single page in request */
+/*
int dump_req(struct ptlrpc_request *req)
{
struct ost_body *body = lustre_msg_buf(req->rq_reqmsg, 0);
struct obd_ioobj *ioo = lustre_msg_buf(req->rq_reqmsg, 1);
//struct niobuf *nb = lustre_msg_buf(req->rq_reqmsg, 2);
- CERROR("ost_body: connid = %d, data = %d\n", body->connid, body->data);
dump_obdo(&body->oa);
//dump_niobuf(nb);
dump_ioo(ioo);
return -EINVAL;
}
+*/
+#define LPDS sizeof(__u64)
+int page_debug_setup(void *addr, int len, __u64 off, __u64 id)
+{
+ LASSERT(addr);
+
+ off = HTON__u64(off);
+ id = HTON__u64(id);
+ memcpy(addr, (char *)&off, LPDS);
+ memcpy(addr + LPDS, (char *)&id, LPDS);
+
+ addr += len - LPDS - LPDS;
+ memcpy(addr, (char *)&off, LPDS);
+ memcpy(addr + LPDS, (char *)&id, LPDS);
+
+ return 0;
+}
+
+int page_debug_check(char *who, void *addr, int end, __u64 off, __u64 id)
+{
+ __u64 ne_off;
+ int err = 0;
+
+ LASSERT(addr);
+
+ ne_off = HTON__u64(off);
+ id = HTON__u64(id);
+ if (memcmp(addr, (char *)&ne_off, LPDS)) {
+ CERROR("%s: for offset "LPU64" off: "LPX64" != "LPX64"\n",
+ who, off, *(__u64 *)addr, ne_off);
+ err = -EINVAL;
+ }
+ if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
+ CERROR("%s: for offset "LPU64" id: "LPX64" != "LPX64"\n",
+ who, off, *(__u64 *)(addr + LPDS), id);
+ err = -EINVAL;
+ }
+
+ addr += end - LPDS - LPDS;
+ if (memcmp(addr, (char *)&ne_off, LPDS)) {
+ CERROR("%s: for offset "LPU64" end off: "LPX64" != "LPX64"\n",
+ who, off, *(__u64 *)addr, ne_off);
+ err = -EINVAL;
+ }
+ if (memcmp(addr + LPDS, (char *)&id, LPDS)) {
+ CERROR("%s: for offset "LPU64" end id: "LPX64" != "LPX64"\n",
+ who, off, *(__u64 *)(addr + LPDS), id);
+ err = -EINVAL;
+ }
+
+ return err;
+}
+#undef LPDS
+
+EXPORT_SYMBOL(dump_lniobuf);
+EXPORT_SYMBOL(dump_rniobuf);
+EXPORT_SYMBOL(dump_ioo);
+//EXPORT_SYMBOL(dump_req);
+EXPORT_SYMBOL(dump_obdo);
+EXPORT_SYMBOL(page_debug_setup);
+EXPORT_SYMBOL(page_debug_check);
MODULE = obdclass
modulefs_DATA = obdclass.o
EXTRA_PROGRAMS = obdclass
-obdclass_SOURCES = genops.c proc_lustre.c class_obd.c sysctl.c page.c uuid.c
+LINX=page.c debug.c
+obdclass_SOURCES = genops.c proc_lustre.c class_obd.c sysctl.c uuid.c $(LINX)
+
+debug.c:
+ test -e debug.c || ln -sf $(top_srcdir)/lib/debug.c
page.c:
test -e page.c || ln -sf $(top_srcdir)/lib/page.c
#include <linux/obd_support.h>
#include <linux/obd_class.h>
+#include <linux/lustre_debug.h>
#include <linux/smp_lock.h>
struct semaphore obd_conf_sem; /* serialize configuration commands */
int len = 0;
struct obd_ioctl_data *data;
struct obd_device *obd = filp->private_data;
+
struct lustre_handle conn;
int rw = OBD_BRW_READ;
int err = 0;
struct lov_stripe_md smd;
struct io_cb_data *cbd = ll_init_cb();
obd_count pages = 0;
- struct brw_page *pga;
+ struct brw_page *pga, *pgp;
int j;
unsigned long off;
- void *from;
-
+ __u64 id;
+
if (!cbd)
- GOTO(out, -ENOMEM);
+ GOTO(out, err = -ENOMEM);
obd_data2conn(&conn, data);
- pages = data->ioc_plen1 / PAGE_SIZE;
+ pages = data->ioc_count / PAGE_SIZE;
CDEBUG(D_INODE, "BRW %s with %d pages\n",
rw == OBD_BRW_READ ? "read" : "write", pages);
}
memset(&smd, 0, sizeof(smd));
- smd.lmd_object_id = data->ioc_obdo1.o_id;
+ id = smd.lmd_object_id = data->ioc_obdo1.o_id;
- from = (&data->ioc_pbuf1)[0];
off = data->ioc_offset;
- for (j = 0; j < pages;
- j++, off += PAGE_SIZE, from += PAGE_SIZE) {
+ for (j = 0, pgp = pga; j < pages; j++, off += PAGE_SIZE, pgp++){
unsigned long to;
to = __get_free_pages(GFP_KERNEL, 0);
if (!to) {
- /* ||
- copy_from_user((void
- *)to,from,PAGE_SIZE))
- free_pages(to, 0);
- */
CERROR("no memory for brw pages\n");
GOTO(brw_cleanup, err = -ENOMEM);
}
- pga[j].pg = virt_to_page(to);
- pga[j].count = PAGE_SIZE;
- pga[j].off = off;
- pga[j].flag = 0;
+ pgp->pg = virt_to_page(to);
+ pgp->count = PAGE_SIZE;
+ pgp->off = off;
+ pgp->flag = 0;
+
+ if (rw == OBD_BRW_WRITE) {
+ void *addr = kmap(pgp->pg);
+
+ LASSERT(addr == (void *)to);
+
+ page_debug_setup(addr, PAGE_SIZE, off, id);
+ kunmap(pgp->pg);
+ }
}
err = obd_brw(rw, &conn, &smd, j, pga, ll_sync_io_cb, cbd);
EXIT;
brw_cleanup:
- for (j = 0; j < pages; j++)
- if (pga[j].pg != NULL)
- __free_pages(pga[j].pg, 0);
+ for (j = 0, pgp = pga; j < pages; j++) {
+ if (pgp->pg != NULL) {
+ void *addr = kmap(pgp->pg);
+
+ page_debug_check("test_brw", addr, PAGE_SIZE,
+ pgp->off, id);
+ kunmap(pgp->pg);
+
+ __free_pages(pgp->pg, 0);
+ }
+ }
brw_free:
OBD_FREE(pga, pages * sizeof(*pga));
GOTO(out, err);
* by Peter Braam <braam@clusterfs.com>
*/
-static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.22 2002/08/12 22:25:53 pschwan Exp $";
-#define OBDECHO_VERSION "$Revision: 1.22 $"
+static char rcsid[] __attribute ((unused)) = "$Id: echo.c,v 1.23 2002/08/19 21:51:33 adilger Exp $";
+#define OBDECHO_VERSION "$Revision: 1.23 $"
#define EXPORT_SYMTAB
#include <linux/obd_support.h>
#include <linux/obd_class.h>
#include <linux/obd_echo.h>
+#include <linux/lustre_debug.h>
#include <linux/lustre_dlm.h>
extern struct obd_device obd_dev[MAX_OBD_DEVICES];
int len;
int attrs = atomic_read (&echo_getattrs);
int pages = atomic_read (&echo_page_rws);
-
+
*eof = 1;
if (off != 0)
return (0);
-
+
len = sprintf (page, "%d %d\n", pages, attrs);
-
+
*start = page;
return (len);
}
/* Ignore what we've been asked to write, and just zero the stats counters */
atomic_set (&echo_page_rws, 0);
atomic_set (&echo_getattrs, 0);
-
+
return (count);
}
void
echo_proc_init(void)
{
- struct proc_dir_entry *entry = create_proc_entry (ECHO_PROC_STAT, S_IFREG | S_IRUGO | S_IWUSR, NULL);
+ struct proc_dir_entry *entry;
+
+ entry = create_proc_entry(ECHO_PROC_STAT, S_IFREG|S_IRUGO|S_IWUSR,NULL);
- if (entry == NULL)
- {
+ if (entry == NULL) {
CERROR("couldn't create proc entry %s\n", ECHO_PROC_STAT);
return;
}
entry->write_proc = echo_proc_write;
}
-void
-echo_proc_fini(void)
+void echo_proc_fini(void)
{
remove_proc_entry(ECHO_PROC_STAT, 0);
}
return rc;
}
-static int echo_getattr(struct lustre_handle *conn, struct obdo *oa,
+static int echo_getattr(struct lustre_handle *conn, struct obdo *oa,
struct lov_stripe_md *md)
{
memcpy(oa, &OA, sizeof(*oa));
for (j = 0 ; j < obj->ioo_bufcnt ; j++, nb++, r++) {
unsigned long address;
- address = get_zeroed_page(GFP_KERNEL);
+ address = __get_free_pages(GFP_KERNEL, 0);
if (!address) {
- CERROR("can't get new page %d/%d for id %Ld\n",
- j, obj->ioo_bufcnt,
- (unsigned long long)obj->ioo_id);
+ CERROR("can't get page %d/%d for id "LPU64"\n",
+ j, obj->ioo_bufcnt, obj->ioo_id);
GOTO(preprw_cleanup, rc = -ENOMEM);
}
echo_pages++;
r->page = virt_to_page(address);
r->addr = kmap(r->page);
r->len = nb->len;
+
+ if (cmd & OBD_BRW_READ)
+ page_debug_setup(r->addr, r->len, r->offset,
+ obj->ioo_id);
}
}
CDEBUG(D_PAGE, "%ld pages allocated after prep\n", echo_pages);
!(addr = (unsigned long)page_address(page)) ||
!kern_addr_valid(addr)) {
- CERROR("bad page %p, id %Ld (%d), buf %d/%d\n",
- page, (unsigned long long)obj->ioo_id, i,
- j, obj->ioo_bufcnt);
+ CERROR("bad page "LPU64":%p, buf %d/%d\n",
+ obj->ioo_id, page, j,obj->ioo_bufcnt);
GOTO(commitrw_cleanup, rc = -EFAULT);
}
atomic_inc (&echo_page_rws);
-
+
+ if (cmd & OBD_BRW_WRITE)
+ page_debug_check("echo", (void *)addr,PAGE_SIZE,
+ r->offset, obj->ioo_id);
+
kunmap(page);
__free_pages(page, 0);
echo_pages--;
printk(KERN_INFO "Echo OBD driver " OBDECHO_VERSION " info@clusterfs.com\n");
echo_proc_init();
-
+
return class_register_type(&echo_obd_ops, OBD_ECHO_DEVICENAME);
}
static void __exit obdecho_exit(void)
{
echo_proc_fini ();
-
+
CERROR("%ld prep/commitrw pages leaked\n", echo_pages);
class_unregister_type(OBD_ECHO_DEVICENAME);
}
MODULE_AUTHOR("Cluster Filesystems Inc. <info@clusterfs.com>");
MODULE_DESCRIPTION("Lustre Testing Echo OBD driver " OBDECHO_VERSION);
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL");
module_init(obdecho_init);
module_exit(obdecho_exit);
"usage: test_getattr <count> [verbose]"},
{"test_brw", jt_obd_test_brw, 0,
"perform count number of bulk read/writes\n"
- "usage: test_brw <count> [write [verbose [pages [obdos]]]]"},
+ "usage: test_brw <count> [write [verbose [pages [objid]]]]"},
{"test_ldlm", jt_obd_test_ldlm, 0, "perform lock manager test\n"
"usage: test_ldlm"},
{"ldlm_regress_start", jt_obd_ldlm_regress_start, 0,
{
struct obd_ioctl_data data;
struct timeval start, next_time;
- char *bulk, *b;
- int pages = 1, obdos = 1, count, next_count;
+ int pages = 1, objid = 3, count, next_count;
int verbose = 1, write = 0, rw;
- int i, o, p;
+ long long offset;
+ int i;
int len;
int rc = 0;
if (argc >= 5)
pages = strtoul(argv[4], NULL, 0);
if (argc >= 6)
- obdos = strtoul(argv[5], NULL, 0);
-
- if (obdos != 1 && obdos != 2) {
- fprintf(stderr, "error: %s: only 1 or 2 obdos supported\n",
- cmdname(argv[0]));
- return -2;
- }
+ objid = strtoul(argv[5], NULL, 0);
len = pages * PAGE_SIZE;
- bulk = calloc(obdos, len);
- if (!bulk) {
- fprintf(stderr, "error: %s: no memory allocating %dx%d pages\n",
- cmdname(argv[0]), obdos, pages);
- return -2;
- }
IOCINIT(data);
- data.ioc_obdo1.o_id = 2;
+ data.ioc_obdo1.o_id = objid;
data.ioc_count = len;
data.ioc_offset = 0;
- data.ioc_plen1 = len;
- data.ioc_pbuf1 = bulk;
- if (obdos > 1) {
- data.ioc_obdo2.o_id = 3;
- data.ioc_plen2 = len;
- data.ioc_pbuf2 = bulk + len;
- }
gettimeofday(&start, NULL);
next_time.tv_sec = start.tv_sec - verbose;
next_time.tv_usec = start.tv_usec;
if (verbose != 0)
- printf("%s: %s %d (%dx%d pages) (testing only): %s",
+ printf("%s: %s %dx%d pages (testing only): %s",
cmdname(argv[0]), write ? "writing" : "reading",
- count, obdos, pages, ctime(&start.tv_sec));
-
- /*
- * We will put in the start time (and loop count inside the loop)
- * at the beginning of each page so that we will be able to validate
- * (at some later time) whether the data actually made it or not.
- *
- * XXX we do not currently use any of this memory in OBD_IOC_BRW_*
- * just to avoid the overhead of the copy_{to,from}_user. It
- * can be fixed if we ever need to send real data around.
- */
- for (o = 0, b = bulk; o < obdos; o++)
- for (p = 0; p < pages; p++, b += PAGE_SIZE)
- memcpy(b, &start, sizeof(start));
+ count, pages, ctime(&start.tv_sec));
rw = write ? OBD_IOC_BRW_WRITE : OBD_IOC_BRW_READ;
- for (i = 1, next_count = verbose; i <= count; i++) {
- if (write) {
- b = bulk + sizeof(struct timeval);
- for (o = 0; o < obdos; o++)
- for (p = 0; p < pages; p++, b += PAGE_SIZE)
- memcpy(b, &count, sizeof(count));
- }
-
+ for (i = 1, next_count = verbose, offset = 0; i <= count; i++) {
rc = ioctl(fd, rw, &data);
SHMEM_BUMP();
if (rc) {
(verbose, &next_time, i, &next_count, count))
printf("%s: %s number %d\n", cmdname(argv[0]),
write ? "write" : "read", i);
- }
- free(bulk);
+ data.ioc_offset += len;
+ }
if (!rc) {
struct timeval end;
--i;
if (verbose != 0)
- printf("%s: %s %dx%dx%d pages in %.4gs (%.4g pg/s): %s",
+ printf("%s: %s %dx%d pages in %.4gs (%.4g pg/s): %s",
cmdname(argv[0]), write ? "wrote" : "read",
- obdos, pages, i, diff,
- (double)obdos * i * pages / diff,
+ i, pages, diff, (double)i * pages / diff,
ctime(&end.tv_sec));
}
return rc;
{"setattr", jt_obd_setattr, 0, "setattr <id> <mode>"},
{"newconn", jt_obd_newconn, 0, "newconn [newuuid]"},
{"test_getattr", jt_obd_test_getattr, 0, "test_getattr <count> [verbose]"},
- {"test_brw", jt_obd_test_brw, 0, "test_brw <count> [write [verbose]]"},
+ {"test_brw", jt_obd_test_brw, 0, "test_brw <count> [write [verbose [pages [objid]]]]"},
{"test_ldlm", jt_obd_test_ldlm, 0, "test lock manager (no args)"},
{"dump_ldlm", jt_obd_dump_ldlm, 0, "dump all lock manager state (no args)"},