/** * This is called when a page is accessed within file in a way that creates * new page, if one were missing (i.e., if there were a hole at that place in * the file, or accessed page is beyond the current file size). Examples: * ->commit_write() and ->nopage() methods. * * Expand stripe KMS if necessary. */ static void osc_page_touch(const struct lu_env *env, struct osc_page *opage, unsigned to) { struct cl_page *page = opage->ops_cl.cpl_page; struct cl_object *obj = opage->ops_cl.cpl_obj; osc_page_touch_at(env, obj, page->cp_index, to); }
static int osc_io_fault_start(const struct lu_env *env, const struct cl_io_slice *ios) { struct cl_io *io; struct cl_fault_io *fio; io = ios->cis_io; fio = &io->u.ci_fault; CDEBUG(D_INFO, "%lu %d %d\n", fio->ft_index, fio->ft_writable, fio->ft_nob); /* * If mapping is writeable, adjust kms to cover this page, * but do not extend kms beyond actual file size. * See bug 10919. */ if (fio->ft_writable) osc_page_touch_at(env, ios->cis_obj, fio->ft_index, fio->ft_nob); return 0; }
static int osc_io_commit_async(const struct lu_env *env, const struct cl_io_slice *ios, struct cl_page_list *qin, int from, int to, cl_commit_cbt cb) { struct cl_io *io = ios->cis_io; struct osc_io *oio = cl2osc_io(env, ios); struct osc_object *osc = cl2osc(ios->cis_obj); struct cl_page *page; struct cl_page *last_page; struct osc_page *opg; int result = 0; ENTRY; LASSERT(qin->pl_nr > 0); /* Handle partial page cases */ last_page = cl_page_list_last(qin); if (oio->oi_lockless) { page = cl_page_list_first(qin); if (page == last_page) { cl_page_clip(env, page, from, to); } else { if (from != 0) cl_page_clip(env, page, from, PAGE_SIZE); if (to != PAGE_SIZE) cl_page_clip(env, last_page, 0, to); } } while (qin->pl_nr > 0) { struct osc_async_page *oap; page = cl_page_list_first(qin); opg = osc_cl_page_osc(page, osc); oap = &opg->ops_oap; if (!list_empty(&oap->oap_rpc_item)) { CDEBUG(D_CACHE, "Busy oap %p page %p for submit.\n", oap, opg); result = -EBUSY; break; } /* The page may be already in dirty cache. */ if (list_empty(&oap->oap_pending_item)) { result = osc_page_cache_add(env, &opg->ops_cl, io); if (result != 0) break; } osc_page_touch_at(env, osc2cl(osc), osc_index(opg), page == last_page ? to : PAGE_SIZE); cl_page_list_del(env, qin, page); (*cb)(env, io, page); /* Can't access page any more. Page can be in transfer and * complete at any time. */ } /* for sync write, kernel will wait for this page to be flushed before * osc_io_end() is called, so release it earlier. * for mkwrite(), it's known there is no further pages. */ if (cl_io_is_sync_write(io) && oio->oi_active != NULL) { osc_extent_release(env, oio->oi_active); oio->oi_active = NULL; } CDEBUG(D_INFO, "%d %d\n", qin->pl_nr, result); RETURN(result); }