-int gen_copy_data(struct obd_conn *dst_conn, struct obdo *dst,
- struct obd_conn *src_conn, struct obdo *src,
- obd_size count, obd_off offset)
-{
- struct page *page;
- unsigned long index = 0;
- int err = 0;
-
- ENTRY;
- CDEBUG(D_INFO, "src: ino %Ld blocks %Ld, size %Ld, dst: ino %Ld\n",
- (unsigned long long)src->o_id, (unsigned long long)src->o_blocks,
- (unsigned long long)src->o_size, (unsigned long long)dst->o_id);
- page = alloc_page(GFP_USER);
- if (page == NULL)
- 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;
- 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;
- err = OBP(src_conn->oc_dev, brw)(READ, src_conn, num_oa, &src,
- &num_buf, &page, &brw_count,
- &brw_offset, &flagr);
-
- if ( err ) {
- EXIT;
- break;
- }
- CDEBUG(D_INFO, "Read page %ld ...\n", page->index);
-
- err = OBP(dst_conn->oc_dev, brw)(WRITE, dst_conn, num_oa, &dst,
- &num_buf, &page, &brw_count,
- &brw_offset, &flagw);
-
- /* XXX should handle dst->o_size, dst->o_blocks here */
- if ( err ) {
- EXIT;
- break;
- }
-
- CDEBUG(D_INFO, "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);
-
- RETURN(err);
-}