- 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;
- struct cl_page *result;
- loff_t offset;
- obd_off suboff;
- int stripe;
- int rc;
- ENTRY;
-
- offset = cl_offset(obj, page->cp_index);
- stripe = lov_stripe_number(r0->lo_lsm, offset);
- LASSERT(stripe < r0->lo_nr);
- rc = lov_stripe_offset(r0->lo_lsm, offset, stripe,
- &suboff);
- LASSERT(rc == 0);
-
- OBD_SLAB_ALLOC_PTR_GFP(lpg, lov_page_kmem, CFS_ALLOC_IO);
- if (lpg == NULL)
- GOTO(out, result = ERR_PTR(-ENOMEM));
-
- 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))
- GOTO(out, result = (struct cl_page *)sub);
-
- 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))
- GOTO(out, result = subpage);
-
- if (likely(subpage->cp_parent == page)) {
- lu_ref_add(&subpage->cp_reference, "lov", page);
- lpg->lps_invalid = 0;
- result = NULL;
- } else {
- /*
- * This is only possible when TRANSIENT page
- * is being created, and CACHEABLE sub-page
- * (attached to already existing top-page) has
- * been found. Tell cl_page_find() to use
- * existing page.
- */
- LASSERT(subpage->cp_type == CPT_CACHEABLE);
- LASSERT(page->cp_type == CPT_TRANSIENT);
- /* TODO: this is problematic, what if the page is being freed? */
- result = cl_page_top(subpage);
- cl_page_get(result);
- cl_page_put(env, subpage);
- }
-
- EXIT;
-out:
- return(result);
-}