示例#1
0
文件: osc_io.c 项目: 383530895/linux
/**
 * 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);
}
示例#2
0
文件: osc_io.c 项目: 383530895/linux
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;
}
示例#3
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);
}