CPT_TRANSIENT,
};
-/**
- * Flags maintained for every cl_page.
- */
-enum cl_page_flags {
- /**
- * Set when pagein completes. Used for debugging (read completes at
- * most once for a page).
- */
- CPF_READ_COMPLETED = 1 << 0
-};
-
/**
* Fields are protected by the lock on struct page, except for atomics and
* immutables.
struct cl_page {
/** Reference counter. */
atomic_t cp_ref;
+ /** Transfer error. */
+ int cp_error;
/** An object this page is a part of. Immutable after creation. */
struct cl_object *cp_obj;
- /** List of slices. Immutable after creation. */
- struct list_head cp_layers;
/** vmpage */
struct page *cp_vmpage;
+ /** Linkage of pages within group. Pages must be owned */
+ struct list_head cp_batch;
+ /** List of slices. Immutable after creation. */
+ struct list_head cp_layers;
+ /** Linkage of pages within cl_req. */
+ struct list_head cp_flight;
/**
* Page state. This field is const to avoid accidental update, it is
* modified only internally within cl_page.c. Protected by a VM lock.
*/
const enum cl_page_state cp_state;
- /** Linkage of pages within group. Protected by cl_page::cp_mutex. */
- struct list_head cp_batch;
- /** Mutex serializing membership of a page in a batch. */
- struct mutex cp_mutex;
- /** Linkage of pages within cl_req. */
- struct list_head cp_flight;
- /** Transfer error. */
- int cp_error;
-
/**
* Page type. Only CPT_TRANSIENT is used so far. Immutable after
* creation.
* by sub-io. Protected by a VM lock.
*/
struct cl_io *cp_owner;
- /**
- * Debug information, the task is owning the page.
- */
- struct task_struct *cp_task;
/**
* Owning IO request in cl_page_state::CPS_PAGEOUT and
* cl_page_state::CPS_PAGEIN states. This field is maintained only in
struct lu_ref_link cp_obj_ref;
/** Link to a queue, for debugging. */
struct lu_ref_link cp_queue_ref;
- /** Per-page flags from enum cl_page_flags. Protected by a VM lock. */
- unsigned cp_flags;
/** Assigned if doing a sync_io */
struct cl_sync_io *cp_sync_io;
};
{
clob->co_slice_off = cl_object_header(clob)->coh_page_bufsize;
cl_object_header(clob)->coh_page_bufsize += cfs_size_round(size);
+ WARN_ON(cl_object_header(clob)->coh_page_bufsize > 512);
}
static inline void *cl_object_page_slice(struct cl_object *clob,
*/
struct vvp_page {
struct cl_page_slice vpg_cl;
- int vpg_defer_uptodate;
- int vpg_ra_used;
- int vpg_write_queued;
+ unsigned int vpg_defer_uptodate:1,
+ vpg_ra_used:1,
+ vpg_write_queued:1;
/**
* Non-empty iff this page is already counted in
* vvp_object::vob_pending_list. This list is only used as a flag,
};
struct lov_page {
- struct cl_page_slice lps_cl;
- int lps_invalid;
+ struct cl_page_slice lps_cl;
+ unsigned int lps_stripe; /* stripe index */
};
/*
int lov_page_stripe(const struct cl_page *page)
{
- struct lovsub_object *subobj;
const struct cl_page_slice *slice;
- slice = cl_page_at(page, &lovsub_device_type);
+ slice = cl_page_at(page, &lov_device_type);
LASSERT(slice->cpl_obj);
- subobj = cl2lovsub(slice->cpl_obj);
- return subobj->lso_index;
+ return cl2lov_page(slice)->lps_stripe;
}
struct lov_io_sub *lov_page_subio(const struct lu_env *env, struct lov_io *lio,
rc = lov_stripe_offset(loo->lo_lsm, offset, stripe, &suboff);
LASSERT(rc == 0);
+ lpg->lps_stripe = stripe;
cl_page_slice_add(page, &lpg->lps_cl, obj, index, &lov_raid0_page_ops);
sub = lov_sub_get(env, lio, stripe);
LASSERT(page->cp_owner);
LINVRNT(plist->pl_owner == current);
- lockdep_off();
- mutex_lock(&page->cp_mutex);
- lockdep_on();
LASSERT(list_empty(&page->cp_batch));
list_add_tail(&page->cp_batch, &plist->pl_pages);
++plist->pl_nr;
struct cl_page *page)
{
LASSERT(plist->pl_nr > 0);
+ LASSERT(cl_page_is_vmlocked(env, page));
LINVRNT(plist->pl_owner == current);
list_del_init(&page->cp_batch);
- lockdep_off();
- mutex_unlock(&page->cp_mutex);
- lockdep_on();
--plist->pl_nr;
lu_ref_del_at(&page->cp_reference, &page->cp_queue_ref, "queue", plist);
cl_page_put(env, page);
LASSERT(plist->pl_nr > 0);
list_del_init(&page->cp_batch);
- lockdep_off();
- mutex_unlock(&page->cp_mutex);
- lockdep_on();
--plist->pl_nr;
/*
* cl_page_disown0 rather than usual cl_page_disown() is used,
INIT_LIST_HEAD(&page->cp_layers);
INIT_LIST_HEAD(&page->cp_batch);
INIT_LIST_HEAD(&page->cp_flight);
- mutex_init(&page->cp_mutex);
lu_ref_init(&page->cp_reference);
head = o->co_lu.lo_header;
list_for_each_entry(o, &head->loh_layers, co_lu.lo_linkage) {
LASSERT(page->cp_owner->ci_owned_nr > 0);
page->cp_owner->ci_owned_nr--;
page->cp_owner = NULL;
- page->cp_task = NULL;
}
}
PASSERT(env, pg, !pg->cp_owner);
PASSERT(env, pg, !pg->cp_req);
pg->cp_owner = cl_io_top(io);
- pg->cp_task = current;
cl_page_owner_set(pg);
if (pg->cp_state != CPS_FREEING) {
cl_page_state_set(env, pg, CPS_OWNED);
cl_page_invoid(env, io, pg, CL_PAGE_OP(cpo_assume));
PASSERT(env, pg, !pg->cp_owner);
pg->cp_owner = cl_io_top(io);
- pg->cp_task = current;
cl_page_owner_set(pg);
cl_page_state_set(env, pg, CPS_OWNED);
}
PASSERT(env, pg, pg->cp_state == cl_req_type_state(crt));
CL_PAGE_HEADER(D_TRACE, env, pg, "%d %d\n", crt, ioret);
- if (crt == CRT_READ && ioret == 0) {
- PASSERT(env, pg, !(pg->cp_flags & CPF_READ_COMPLETED));
- pg->cp_flags |= CPF_READ_COMPLETED;
- }
cl_page_state_set(env, pg, CPS_CACHED);
if (crt >= CRT_NR)
lu_printer_t printer, const struct cl_page *pg)
{
(*printer)(env, cookie,
- "page@%p[%d %p %d %d %d %p %p %#x]\n",
+ "page@%p[%d %p %d %d %d %p %p]\n",
pg, atomic_read(&pg->cp_ref), pg->cp_obj,
pg->cp_state, pg->cp_error, pg->cp_type,
- pg->cp_owner, pg->cp_req, pg->cp_flags);
+ pg->cp_owner, pg->cp_req);
}
EXPORT_SYMBOL(cl_page_header_print);
struct client_obd *oap_cli;
struct osc_object *oap_obj;
- struct ldlm_lock *oap_ldlm_lock;
spinlock_t oap_lock;
};
continue;
}
- cl_page_list_move(qout, qin, page);
spin_lock(&oap->oap_lock);
oap->oap_async_flags = ASYNC_URGENT|ASYNC_READY;
oap->oap_async_flags |= ASYNC_COUNT_STABLE;
osc_page_submit(env, opg, crt, brw_flags);
list_add_tail(&oap->oap_pending_item, &list);
+
+ if (page->cp_sync_io)
+ cl_page_list_move(qout, qin, page);
+ else /* async IO */
+ cl_page_list_del(env, qin, page);
+
if (++queued == max_pages) {
queued = 0;
result = osc_queue_sync_pages(env, osc, &list, cmd,
struct osc_async_page *tmp;
struct cl_req *clerq = NULL;
enum cl_req_type crt = (cmd & OBD_BRW_WRITE) ? CRT_WRITE : CRT_READ;
- struct ldlm_lock *lock = NULL;
struct cl_req_attr *crattr = NULL;
u64 starting_offset = OBD_OBJECT_EOF;
u64 ending_offset = 0;
rc = PTR_ERR(clerq);
goto out;
}
- lock = oap->oap_ldlm_lock;
}
if (mem_tight)
oap->oap_brw_flags |= OBD_BRW_MEMALLOC;
LASSERT(clerq);
crattr->cra_oa = oa;
cl_req_attr_set(env, clerq, crattr, ~0ULL);
- if (lock) {
- oa->o_handle = lock->l_remote_handle;
- oa->o_valid |= OBD_MD_FLHANDLE;
- }
rc = cl_req_prep(env, clerq);
if (rc != 0) {