void td_queue_read(td_image_t *image, td_request_t treq) { int err; td_driver_t *driver; driver = image->driver; if (!driver) { err = -ENODEV; goto fail; } if (!td_flag_test(driver->state, TD_DRIVER_OPEN)) { err = -EBADF; goto fail; } err = tapdisk_image_check_td_request(image, treq); if (err) goto fail; driver->ops->td_queue_read(driver, treq); return; fail: td_complete_request(treq, err); }
static inline void vhd_index_signal_completion(vhd_index_t *index, vhd_index_request_t *req, int err) { td_complete_request(req->treq, err); vhd_index_put_file_ref(req->file); vhd_index_free_request(index, req); }
static void vhd_index_queue_write(td_driver_t *driver, td_request_t treq) { td_complete_request(treq, -EPERM); }
static void vhd_index_queue_read(td_driver_t *driver, td_request_t treq) { vhd_index_t *index; index = (vhd_index_t *)driver->data; while (treq.secs) { int err; td_request_t clone; err = 0; clone = treq; switch (vhd_index_read_cache(index, clone.sec)) { case -EINVAL: err = -EINVAL; goto fail; case VHD_INDEX_BAT_CLEAR: clone.secs = MIN(clone.secs, index->vhdi.spb - (clone.sec % index->vhdi.spb)); td_forward_request(clone); break; case VHD_INDEX_BIT_CLEAR: clone.secs = vhd_index_read_cache_span(index, clone.sec, clone.secs, 0); td_forward_request(clone); break; case VHD_INDEX_BIT_SET: clone.secs = vhd_index_read_cache_span(index, clone.sec, clone.secs, 1); err = vhd_index_schedule_data_read(index, clone); if (err) goto fail; break; case VHD_INDEX_CACHE_MISS: err = vhd_index_schedule_meta_read(index, clone.sec / index->vhdi.spb); if (err) goto fail; clone.secs = MIN(clone.secs, index->vhdi.spb - (clone.sec % index->vhdi.spb)); vhd_index_queue_request(index, clone); break; case VHD_INDEX_META_READ_PENDING: clone.secs = MIN(clone.secs, index->vhdi.spb - (clone.sec % index->vhdi.spb)); err = vhd_index_queue_request(index, clone); if (err) goto fail; break; } treq.sec += clone.secs; treq.secs -= clone.secs; treq.buf += vhd_sectors_to_bytes(clone.secs); continue; fail: clone.secs = treq.secs; td_complete_request(clone, err); break; } }