static void _complete_mref(struct aio_output *output, struct mref_object *mref, int err) { struct aio_mref_aspect *mref_a; _mref_check(mref); mref_a = aio_mref_get_aspect(output->brick, mref); CHECK_PTR(mref_a, fatal); _complete(output, mref_a, err); return; fatal: MARS_FAT("bad pointer, giving up...\n"); }
static void aio_ref_io(struct aio_output *output, struct mref_object *mref) { struct aio_threadinfo *tinfo = &output->tinfo[0]; struct aio_mref_aspect *mref_a; int err = -EINVAL; _mref_check(mref); if (unlikely(!output->brick->power.led_on)) { SIMPLE_CALLBACK(mref, -EBADFD); return; } _mref_get(mref); atomic_inc(&mars_global_io_flying); atomic_inc(&output->work_count); // statistics if (mref->ref_rw) { atomic_inc(&output->total_write_count); atomic_inc(&output->write_count); } else { atomic_inc(&output->total_read_count); atomic_inc(&output->read_count); } if (unlikely(!output->mf || !output->mf->mf_filp)) { goto done; } mapfree_set(output->mf, mref->ref_pos, -1); MARS_IO("AIO rw=%d pos=%lld len=%d data=%p\n", mref->ref_rw, mref->ref_pos, mref->ref_len, mref->ref_data); mref_a = aio_mref_get_aspect(output->brick, mref); if (unlikely(!mref_a)) { goto done; } _enqueue(tinfo, mref_a, mref->ref_prio, true); return; done: _complete_mref(output, mref, err); }
static void usebuf_ref_io(struct usebuf_output *output, struct mref_object *mref) { struct usebuf_input *input = output->brick->inputs[0]; struct usebuf_mref_aspect *mref_a; struct usebuf_mref_aspect *sub_mref_a; struct mref_object *sub_mref; int error = -EILSEQ; might_sleep(); _mref_check(mref); mref_a = usebuf_mref_get_aspect(output->brick, mref); if (unlikely(!mref_a)) { MARS_FAT("cannot get aspect\n"); goto err; } sub_mref_a = mref_a->sub_mref_a; if (!sub_mref_a) { MARS_FAT("sub_mref is missing\n"); goto err; } sub_mref = sub_mref_a->object; if (!sub_mref) { MARS_FAT("sub_mref is missing\n"); goto err; } if (mref->ref_rw != 0 && sub_mref->ref_may_write == 0) { MARS_ERR("mref_may_write was not set before\n"); goto err; } _mref_get(mref); sub_mref->ref_rw = mref->ref_rw; sub_mref->ref_len = mref->ref_len; mref_a->input = input; /* Optimization: when buffered IO is used and buffer is already * uptodate, skip real IO operation. */ if (mref->ref_rw != 0) { #ifdef DIRECT_WRITE sub_mref->ref_rw = 1; #else // normal case sub_mref->ref_rw = 0; if (sub_mref->ref_flags & MREF_UPTODATE) { sub_mref->ref_rw = 1; } #endif } else if (sub_mref->ref_flags & MREF_UPTODATE) { MARS_IO("direct _usebuf_endio\n"); _usebuf_endio(sub_mref->object_cb); return; } if (mref->ref_data != sub_mref->ref_data) { if (sub_mref->ref_rw != 0) { _usebuf_copy(mref, sub_mref, 1); mref->ref_flags |= MREF_UPTODATE; } } #ifdef FAKE_ALL _usebuf_endio(sub_mref->ref_cb); return; #endif GENERIC_INPUT_CALL(input, mref_io, sub_mref); return; err: SIMPLE_CALLBACK(mref, error); return; }