GOTO(out, rc = 60);
if (ext->oe_fsync_wait && !ext->oe_urgent && !ext->oe_hp)
GOTO(out, rc = 65);
+ /* fallthrough */
default:
if (atomic_read(&ext->oe_users) > 0)
GOTO(out, rc = 70);
"%s: wait ext to %u timedout, recovery in progress?\n",
cli_name(osc_cli(obj)), state);
- lwi = LWI_INTR(NULL, NULL);
- rc = l_wait_event(ext->oe_waitq, extent_wait_cb(ext, state),
- &lwi);
+ wait_event_idle(ext->oe_waitq, extent_wait_cb(ext, state));
+ rc = 0;
}
if (rc == 0 && ext->oe_rc < 0)
rc = ext->oe_rc;
struct osc_object *osc)
__must_hold(osc)
{
- struct list_head rpclist = LIST_HEAD_INIT(rpclist);
+ LIST_HEAD(rpclist);
struct osc_extent *ext;
struct osc_extent *tmp;
struct osc_extent *first = NULL;
{
struct osc_extent *ext;
struct osc_extent *next;
- struct list_head rpclist = LIST_HEAD_INIT(rpclist);
+ LIST_HEAD(rpclist);
struct extent_rpc_data data = {
.erd_rpc_list = &rpclist,
.erd_page_count = 0,
EXPORT_SYMBOL(osc_prep_async_page);
int osc_queue_async_io(const struct lu_env *env, struct cl_io *io,
- struct osc_page *ops)
+ struct osc_page *ops, cl_commit_cbt cb)
{
struct osc_io *oio = osc_env_io(env);
struct osc_extent *ext = NULL;
struct osc_async_page *oap = &ops->ops_oap;
struct client_obd *cli = oap->oap_cli;
struct osc_object *osc = oap->oap_obj;
+ struct pagevec *pvec = &osc_env_info(env)->oti_pagevec;
pgoff_t index;
unsigned int tmp;
unsigned int grants = 0;
rc = 0;
if (grants == 0) {
- /* we haven't allocated grant for this page. */
+ /* We haven't allocated grant for this page, and we
+ * must not hold a page lock while we do enter_cache,
+ * so we must mark dirty & unlock any pages in the
+ * write commit pagevec. */
+ if (pagevec_count(pvec)) {
+ cb(env, io, pvec);
+ pagevec_reinit(pvec);
+ }
rc = osc_enter_cache(env, cli, oap, tmp);
if (rc == 0)
grants = tmp;
struct osc_extent *ext;
struct osc_extent *waiting = NULL;
pgoff_t index;
- struct list_head list = LIST_HEAD_INIT(list);
+ LIST_HEAD(list);
int result = 0;
bool partial;
ENTRY;
pgoff_t start, pgoff_t end, int hp, int discard)
{
struct osc_extent *ext;
- struct list_head discard_list = LIST_HEAD_INIT(discard_list);
+ LIST_HEAD(discard_list);
bool unplug = false;
int result = 0;
ENTRY;
list_move_tail(&ext->oe_link, list);
unplug = true;
} else {
+ struct client_obd *cli = osc_cli(obj);
+ int pcc_bits = cli->cl_chunkbits - PAGE_SHIFT;
+ pgoff_t align_by = (1 << pcc_bits);
+ pgoff_t a_start = round_down(start, align_by);
+ pgoff_t a_end = round_up(end, align_by);
+
+ /* overflow case */
+ if (end && !a_end)
+ a_end = CL_PAGE_EOF;
/* the only discarder is lock cancelling, so
- * [start, end] must contain this extent */
- EASSERT(ext->oe_start >= start &&
- ext->oe_end <= end, ext);
+ * [start, end], aligned by chunk size, must
+ * contain this extent */
+ LASSERTF(ext->oe_start >= a_start &&
+ ext->oe_end <= a_end,
+ "ext [%lu, %lu] reg [%lu, %lu] "
+ "orig [%lu %lu] align %lu bits "
+ "%d\n", ext->oe_start, ext->oe_end,
+ a_start, a_end, start, end,
+ align_by, pcc_bits);
osc_extent_state_set(ext, OES_LOCKING);
ext->oe_owner = current;
list_move_tail(&ext->oe_link,