/** * Implements cl_object_operations::clo_io_init() method for lov * layer. Dispatches to the appropriate layout io initialization method. */ int lov_io_init(const struct lu_env *env, struct cl_object *obj, struct cl_io *io) { CL_IO_SLICE_CLEAN(lov_env_io(env), lis_cl); return LOV_2DISPATCH_MAYLOCK(cl2lov(obj), llo_io_init, !io->ci_ignore_layout, env, obj, io); }
int lov_page_init_raid0(const struct lu_env *env, struct cl_object *obj, struct cl_page *page, struct page *vmpage) { struct lov_object *loo = cl2lov(obj); struct lov_layout_raid0 *r0 = lov_r0(loo); struct lov_io *lio = lov_env_io(env); struct cl_page *subpage; struct cl_object *subobj; struct lov_io_sub *sub; struct lov_page *lpg = cl_object_page_slice(obj, page); loff_t offset; u64 suboff; int stripe; int rc; offset = cl_offset(obj, page->cp_index); stripe = lov_stripe_number(loo->lo_lsm, offset); LASSERT(stripe < r0->lo_nr); rc = lov_stripe_offset(loo->lo_lsm, offset, stripe, &suboff); LASSERT(rc == 0); lpg->lps_invalid = 1; cl_page_slice_add(page, &lpg->lps_cl, obj, &lov_page_ops); sub = lov_sub_get(env, lio, stripe); if (IS_ERR(sub)) { rc = PTR_ERR(sub); goto out; } subobj = lovsub2cl(r0->lo_sub[stripe]); subpage = cl_page_find_sub(sub->sub_env, subobj, cl_index(subobj, suboff), vmpage, page); lov_sub_put(sub); if (IS_ERR(subpage)) { rc = PTR_ERR(subpage); goto out; } if (likely(subpage->cp_parent == page)) { lu_ref_add(&subpage->cp_reference, "lov", page); lpg->lps_invalid = 0; rc = 0; } else { CL_PAGE_DEBUG(D_ERROR, env, page, "parent page\n"); CL_PAGE_DEBUG(D_ERROR, env, subpage, "child page\n"); LASSERT(0); } out: return rc; }
static int lov_page_own(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *io, int nonblock) { struct lov_io *lio = lov_env_io(env); struct lov_io_sub *sub; LINVRNT(lov_page_invariant(slice)); LINVRNT(!cl2lov_page(slice)->lps_invalid); sub = lov_page_subio(env, lio, slice); if (!IS_ERR(sub)) { lov_sub_page(slice)->cp_owner = sub->sub_io; lov_sub_put(sub); } else LBUG(); /* Arrgh */ return 0; }
static int lov_page_cache_add(const struct lu_env *env, const struct cl_page_slice *slice, struct cl_io *io) { struct lov_io *lio = lov_env_io(env); struct lov_io_sub *sub; int rc = 0; LINVRNT(lov_page_invariant(slice)); LINVRNT(!cl2lov_page(slice)->lps_invalid); sub = lov_page_subio(env, lio, slice); if (!IS_ERR(sub)) { rc = cl_page_cache_add(sub->sub_env, sub->sub_io, slice->cpl_page->cp_child, CRT_WRITE); lov_sub_put(sub); } else { rc = PTR_ERR(sub); CL_PAGE_DEBUG(D_ERROR, env, slice->cpl_page, "rc = %d\n", rc); } return rc; }
static struct lov_sublock_env *lov_sublock_env_get(const struct lu_env *env, const struct cl_lock *parent, struct lov_lock_sub *lls) { struct lov_sublock_env *subenv; struct lov_io *lio = lov_env_io(env); struct cl_io *io = lio->lis_cl.cis_io; struct lov_io_sub *sub; subenv = &lov_env_session(env)->ls_subenv; /* * FIXME: We tend to use the subio's env & io to call the sublock * lock operations because osc lock sometimes stores some control * variables in thread's IO information(Now only lockless information). * However, if the lock's host(object) is different from the object * for current IO, we have no way to get the subenv and subio because * they are not initialized at all. As a temp fix, in this case, * we still borrow the parent's env to call sublock operations. */ if (!io || !cl_object_same(io->ci_obj, parent->cll_descr.cld_obj)) { subenv->lse_env = env; subenv->lse_io = io; subenv->lse_sub = NULL; } else { sub = lov_sub_get(env, lio, lls->sub_stripe); if (!IS_ERR(sub)) { subenv->lse_env = sub->sub_env; subenv->lse_io = sub->sub_io; subenv->lse_sub = sub; } else { subenv = (void *)sub; } } return subenv; }