staticvoid__split_and_process_bio(structmapped_device*md,structbio*bio){structclone_infoci;interror=0;ci.map=dm_get_live_table(md);if(unlikely(!ci.map)){bio_io_error(bio);return;}ci.md=md;ci.io=alloc_io(md);ci.io->error=0;atomic_set(&ci.io->io_count,1);ci.io->bio=bio;ci.io->md=md;spin_lock_init(&ci.io->endio_lock);ci.sector=bio->bi_sector;ci.idx=bio->bi_idx;start_io_acct(ci.io);if(bio->bi_rw&REQ_FLUSH){ci.bio=&ci.md->flush_bio;ci.sector_count=0;error=__clone_and_map_empty_flush(&ci);/* dec_pending submits any data associated with flush */}else{ci.bio=bio;ci.sector_count=bio_sectors(bio);while(ci.sector_count&&!error)error=__clone_and_map(&ci);}/* drop the extra reference count */dec_pending(ci.io,error);
__clone_and_mapは, ti = dm_target_find_target(ci->map, ci->sector)を実行して, どのターゲットに処理を渡すかを計算します. そして, max = max_io_len(ci->sector, ti)によって, 「最長でどのくらい長いbioに分割出来るか」を計算します.
staticsector_tmax_io_len(sector_tsector,structdm_target*ti){sector_tlen=max_io_len_target_boundary(sector,ti);sector_toffset,max_len;/*
* Does the target need to split even further?
*/if(ti->max_io_len){offset=dm_target_offset(ti,sector);if(unlikely(ti->max_io_len&(ti->max_io_len-1)))max_len=sector_div(offset,ti->max_io_len);elsemax_len=offset&(ti->max_io_len-1);max_len=ti->max_io_len-max_len;if(len>max_len)len=max_len;}returnlen;}
staticvoid__map_bio(structdm_target*ti,structdm_target_io*tio){intr;sector_tsector;structmapped_device*md;structbio*clone=&tio->clone;clone->bi_end_io=clone_endio;clone->bi_private=tio;/*
* Map the clone. If r == 0 we don't need to do
* anything, the target has assumed ownership of
* this io.
*/atomic_inc(&tio->io->io_count);<<sector=clone->bi_sector;r=ti->type->map(ti,clone);if(r==DM_MAPIO_REMAPPED){/* the bio has been remapped so dispatch it */trace_block_bio_remap(bdev_get_queue(clone->bi_bdev),clone,tio->io->bio->bi_bdev->bd_dev,sector);generic_make_request(clone);}elseif(r<0||r==DM_MAPIO_REQUEUE){/* error the io and bail out, or requeue it if needed */md=tio->io->md;dec_pending(tio->io,r);free_tio(md,tio);}elseif(r){DMWARN("unimplemented target map return value: %d",r);BUG();}}