- struct page *page;
- unsigned long index = 0;
- int err = 0;
-
- ENTRY;
- CDEBUG(D_INODE, "src: ino %Ld blocks %Ld, size %Ld, dst: ino %Ld\n",
- src->o_id, src->o_blocks, src->o_size, dst->o_id);
- page = alloc_page(GFP_USER);
- if ( !page ) {
- EXIT;
- return -ENOMEM;
- }
-
- lck_page(page);
-
- /* XXX with brw vector I/O, we could batch up reads and writes here,
- * all we need to do is allocate multiple pages to handle the I/Os
- * and arrays to handle the request parameters.
- */
- while (index < ((src->o_size + PAGE_SIZE - 1) >> PAGE_SHIFT)) {
- obd_count num_oa = 1;
- obd_count num_buf = 1;
- char *buf;
- obd_size brw_count = PAGE_SIZE;
- obd_off brw_offset = (page->index) << PAGE_SHIFT;
- obd_flag flagr = 0;
- obd_flag flagw = OBD_BRW_CREATE;
-
- page->index = index;
- buf = (char *)page_address(page);
- err = OBP(src_conn->oc_dev, brw)(READ, src_conn, num_oa, &src,
- &num_buf, &buf, &brw_count,
- &brw_offset, &flagr);
-
- if ( err ) {
- EXIT;
- break;
- }
- CDEBUG(D_INODE, "Read page %ld ...\n", page->index);
-
- err = OBP(dst_conn->oc_dev, brw)(WRITE, dst_conn, num_oa, &dst,
- &num_buf, &buf, &brw_count,
- &brw_offset, &flagw);
-
- /* XXX should handle dst->o_size, dst->o_blocks here */
- if ( err ) {
- EXIT;
- break;
- }
-
- CDEBUG(D_INODE, "Wrote page %ld ...\n", page->index);
-
- index++;
- }
- dst->o_size = src->o_size;
- dst->o_blocks = src->o_blocks;
- dst->o_valid |= (OBD_MD_FLSIZE | OBD_MD_FLBLOCKS);
- UnlockPage(page);
- __free_page(page);
-
- EXIT;
- return err;
+ int i;
+
+ for (i = 0; i < obddev->obd_multi_count; i++) {
+ int rc;
+ struct obd_device *obd = class_conn2obd(&obddev->obd_multi_conn[i]);
+
+ if (!obd) {
+ CERROR("no such device [i %d]\n", i);
+ RETURN(-EINVAL);
+ }
+
+ rc = obd_disconnect(&obddev->obd_multi_conn[i]);
+ if (rc)
+ CERROR("disconnect failure %d\n", obd->obd_minor);
+ }
+ return 0;