/*
* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
+ *
+ * Copyright (c) 2011 Whamcloud, Inc.
+ *
*/
/*
* This file is part of Lustre, http://www.lustre.org/
{
loi_list_maint(cli, osc->oo_oinfo);
osc_check_rpcs(env, cli);
- client_obd_list_unlock(&cli->cl_loi_list_lock);
}
/**
LASSERT(qin->pl_nr > 0);
- CDEBUG(D_INFO, "%i %i\n", qin->pl_nr, crt);
+ CDEBUG(D_INFO, "%d %d\n", qin->pl_nr, crt);
/*
* NOTE: here @page is a top-level page. This is done to avoid
* creation of sub-page-list.
oap->oap_async_flags |= ASYNC_HP;
cfs_spin_unlock(&oap->oap_lock);
}
- /*
- * This can be checked without cli->cl_loi_list_lock, because
- * ->oap_*_item are always manipulated when the page is owned.
- */
- if (!cfs_list_empty(&oap->oap_urgent_item) ||
- !cfs_list_empty(&oap->oap_rpc_item)) {
- result = -EBUSY;
- break;
- }
if (osc0 == NULL) { /* first iteration */
cli = &exp->exp_obd->u.cli;
osc0 = osc;
+ client_obd_list_lock(&cli->cl_loi_list_lock);
} else /* check that all pages are against the same object
* (for now) */
LASSERT(osc == osc0);
- if (queued++ == 0)
- client_obd_list_lock(&cli->cl_loi_list_lock);
+
+ if (!cfs_list_empty(&oap->oap_urgent_item) ||
+ !cfs_list_empty(&oap->oap_rpc_item)) {
+ result = -EBUSY;
+ break;
+ }
+
result = cl_page_prep(env, io, page, crt);
if (result == 0) {
+ ++queued;
cl_page_list_move(qout, qin, page);
if (cfs_list_empty(&oap->oap_pending_item)) {
osc_io_submit_page(env, cl2osc_io(env, ios),
OSC_FLAGS);
/*
* bug 18881: we can't just break out here when
- * error occurrs after cl_page_prep has been
+ * error occurs after cl_page_prep has been
* called against the page. The correct
* way is to call page's completion routine,
* as in osc_oap_interrupted. For simplicity,
if (queued > 0)
osc_io_unplug(env, osc, cli);
- CDEBUG(D_INFO, "%i/%i %i\n", qin->pl_nr, qout->pl_nr, result);
+ if (osc0)
+ client_obd_list_unlock(&cli->cl_loi_list_lock);
+ CDEBUG(D_INFO, "%d/%d %d\n", qin->pl_nr, qout->pl_nr, result);
return qout->pl_nr > 0 ? 0 : result;
}
{
struct osc_device *dev = lu2osc_dev(slice->cpl_obj->co_lu.lo_dev);
struct obd_import *imp = class_exp2cliimp(dev->od_exp);
-
+ struct osc_io *oio = cl2osc_io(env, ios);
+ int result = 0;
ENTRY;
/*
* This implements OBD_BRW_CHECK logic from old client.
*/
- RETURN(imp == NULL || imp->imp_invalid ? -EIO : 0);
+ if (imp == NULL || imp->imp_invalid)
+ result = -EIO;
+ if (result == 0 && oio->oi_lockless)
+ /* this page contains `invalid' data, but who cares?
+ * nobody can access the invalid data.
+ * in osc_io_commit_write(), we're going to write exact
+ * [from, to) bytes of this page to OST. -jay */
+ cl_page_export(env, slice->cpl_page, 1);
+
+ RETURN(result);
}
static int osc_io_commit_write(const struct lu_env *env,
const struct cl_page_slice *slice,
unsigned from, unsigned to)
{
+ struct osc_io *oio = cl2osc_io(env, ios);
struct osc_page *opg = cl2osc_page(slice);
struct osc_object *obj = cl2osc(opg->ops_cl.cpl_obj);
struct osc_async_page *oap = &opg->ops_oap;
cfs_capable(CFS_CAP_SYS_RESOURCE))
oap->oap_brw_flags |= OBD_BRW_NOQUOTA;
+ if (oio->oi_lockless)
+ /* see osc_io_prepare_write() for lockless io handling. */
+ cl_page_clip(env, slice->cpl_page, from, to);
+
RETURN(0);
}
io = ios->cis_io;
fio = &io->u.ci_fault;
- CDEBUG(D_INFO, "%lu %i %i\n",
+ 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,
* XXX this is quite expensive check.
*/
cl_page_list_init(list);
- cl_page_gang_lookup(env, clob, io, start + partial, CL_PAGE_EOF, list, 0);
+ cl_page_gang_lookup(env, clob, io, start + partial, CL_PAGE_EOF, list);
cl_page_list_for_each(page, list)
CL_PAGE_DEBUG(D_ERROR, env, page, "exists %lu\n", start);
/*
* XXX Linux specific debugging stuff.
*/
- CL_PAGE_DEBUG(D_ERROR, env, page, "%s/%i %lu\n",
+ CL_PAGE_DEBUG(D_ERROR, env, page, "%s/%d %lu\n",
submitter->comm, submitter->pid, start);
libcfs_debug_dumpstack(submitter);
}