* \retval valid-pointer pointer to already existing referenced page
* to be used instead of newly created.
*/
- int (*coo_page_init)(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index);
+ int (*coo_page_init)(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page,
+ pgoff_t index);
/**
* Initialize lock slice for this layer. Called top-to-bottom through
* every object layer when a new cl_lock is instantiated. Layer
/** \defgroup cl_page cl_page
* @{ */
struct cl_page *cl_page_find (const struct lu_env *env,
+ struct cl_io *io,
struct cl_object *obj,
pgoff_t idx, struct page *vmpage,
enum cl_page_type type);
struct cl_page *cl_page_alloc (const struct lu_env *env,
+ struct cl_io *io,
struct cl_object *o, pgoff_t ind,
struct page *vmpage,
enum cl_page_type type);
#define OSC_FLAGS (ASYNC_URGENT|ASYNC_READY)
/* osc_page.c */
-int osc_page_init(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t ind);
+int osc_page_init(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *cl_page,
+ pgoff_t index);
void osc_index2policy(union ldlm_policy_data *policy, const struct cl_object *obj,
pgoff_t start, pgoff_t end);
void osc_lru_add_batch(struct client_obd *cli, struct list_head *list);
#define OBD_FAIL_OSC_NO_SIZE_DATA 0x415
#define OBD_FAIL_OSC_DELAY_CANCEL 0x416
#define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
+#define OBD_FAIL_OSC_UNALIGNED_RDMA_ONLY 0x418
#define OBD_FAIL_PTLRPC 0x500
#define OBD_FAIL_PTLRPC_ACK 0x501
break;
}
/* attach VM page to CL page cache */
- page = cl_page_find(env, obj, vmpage->index, vmpage,
+ page = cl_page_find(env, io, obj, vmpage->index, vmpage,
CPT_CACHEABLE);
if (IS_ERR(page)) {
ClearPageUptodate(vmpage);
if (!PageDirty(vmpage)) {
/* associate cl_page */
- clpage = cl_page_find(env, clob, vmpage->index,
+ clpage = cl_page_find(env, io, clob, vmpage->index,
vmpage, CPT_CACHEABLE);
if (IS_ERR(clpage))
GOTO(pagefini, rc = PTR_ERR(clpage));
GOTO(out, rc = -EBUSY);
}
- cp = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE);
+ cp = cl_page_find(env, io, clob, vmpage->index, vmpage, CPT_CACHEABLE);
if (IS_ERR(cp)) {
which = RA_STAT_FAILED_GRAB_PAGE;
msg = "cl_page_find failed";
io->ci_ignore_layout = 1;
result = cl_io_init(env, io, CIT_MISC, clob);
if (result == 0) {
- page = cl_page_find(env, clob, vmpage->index,
+ page = cl_page_find(env, io, clob, vmpage->index,
vmpage, CPT_CACHEABLE);
if (!IS_ERR(page)) {
lu_ref_add(&page->cp_reference, "writepage",
}
LASSERT(io->ci_state == CIS_IO_GOING);
- page = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE);
+ page = cl_page_find(env, io, clob, vmpage->index, vmpage,
+ CPT_CACHEABLE);
if (!IS_ERR(page)) {
LASSERT(page->cp_type == CPT_CACHEABLE);
if (likely(!PageUptodate(vmpage))) {
size_t from = offset & ~PAGE_MASK;
size_t to = min(from + size, PAGE_SIZE);
- page = cl_page_find(env, obj, offset >> PAGE_SHIFT,
+ page = cl_page_find(env, io, obj, offset >> PAGE_SHIFT,
pv->ldp_pages[i], CPT_TRANSIENT);
if (IS_ERR(page)) {
rc = PTR_ERR(page);
goto again;
}
- page = cl_page_find(env, clob, vmpage->index, vmpage, CPT_CACHEABLE);
+ page = cl_page_find(env, io, clob, vmpage->index, vmpage,
+ CPT_CACHEABLE);
if (IS_ERR(page))
GOTO(out, result = PTR_ERR(page));
int vvp_io_init(const struct lu_env *env, struct cl_object *obj,
struct cl_io *io);
int vvp_io_write_commit(const struct lu_env *env, struct cl_io *io);
-int vvp_page_init(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index);
+int vvp_page_init(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page, pgoff_t index);
struct lu_object *vvp_object_alloc(const struct lu_env *env,
const struct lu_object_header *hdr,
struct lu_device *dev);
}
}
- page = cl_page_find(env, obj, fio->ft_index, vmpage, CPT_CACHEABLE);
+ page = cl_page_find(env, io, obj, fio->ft_index, vmpage,
+ CPT_CACHEABLE);
if (IS_ERR(page))
GOTO(out, result = PTR_ERR(page));
static const struct cl_page_operations vvp_transient_page_ops = {
};
-int vvp_page_init(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index)
+int vvp_page_init(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page, pgoff_t index)
{
struct cl_page_slice *cpl = cl_object_page_slice(obj, page);
struct page *vmpage = page->cp_vmpage;
return cp->cp_lov_index == CP_LOV_INDEX_EMPTY;
}
-int lov_page_init_empty (const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index);
-int lov_page_init_composite(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index);
-int lov_page_init_foreign(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index);
+int lov_page_init_empty (const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page,
+ pgoff_t index);
+int lov_page_init_composite(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page,
+ pgoff_t index);
+int lov_page_init_foreign(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page,
+ pgoff_t index);
struct lu_object *lov_object_alloc (const struct lu_env *env,
const struct lu_object_header *hdr,
struct lu_device *dev);
union lov_layout_state *state);
int (*llo_print)(const struct lu_env *env, void *cookie,
lu_printer_t p, const struct lu_object *o);
- int (*llo_page_init)(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index);
+ int (*llo_page_init)(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page,
+ pgoff_t index);
int (*llo_lock_init)(const struct lu_env *env,
struct cl_object *obj, struct cl_lock *lock,
const struct cl_io *io);
return LOV_2DISPATCH_NOLOCK(lu2lov(o), llo_print, env, cookie, p, o);
}
-static int lov_page_init(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index)
+static int lov_page_init(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page,
+ pgoff_t index)
{
- return LOV_2DISPATCH_NOLOCK(cl2lov(obj), llo_page_init, env, obj, page,
- index);
+ return LOV_2DISPATCH_NOLOCK(cl2lov(obj), llo_page_init, env, io, obj,
+ page, index);
}
/**
* Lov page operations.
*
*/
-int lov_page_init_composite(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index)
+int lov_page_init_composite(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page,
+ pgoff_t index)
{
struct lov_object *loo = cl2lov(obj);
struct lov_io *lio = lov_env_io(env);
if (entry < 0 || !lsm_entry_inited(loo->lo_lsm, entry)) {
/* non-existing layout component */
- lov_page_init_empty(env, obj, page, index);
+ lov_page_init_empty(env, io, obj, page, index);
RETURN(0);
}
subobj = lovsub2cl(r0->lo_sub[stripe]);
cl_object_for_each(o, subobj) {
if (o->co_ops->coo_page_init) {
- rc = o->co_ops->coo_page_init(sub->sub_env, o, page,
+ rc = o->co_ops->coo_page_init(sub->sub_env, io, o,
+ page,
suboff >> PAGE_SHIFT);
if (rc != 0)
break;
RETURN(rc);
}
-int lov_page_init_empty(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *cl_page, pgoff_t index)
+int lov_page_init_empty(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *cl_page,
+ pgoff_t index)
{
void *addr;
RETURN(0);
}
-int lov_page_init_foreign(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *page, pgoff_t index)
+int lov_page_init_foreign(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *page,
+ pgoff_t index)
{
CDEBUG(D_PAGE, DFID" has no data\n", PFID(lu_object_fid(&obj->co_lu)));
RETURN(-ENODATA);
return cl_page;
}
-struct cl_page *cl_page_alloc(const struct lu_env *env, struct cl_object *o,
- pgoff_t ind, struct page *vmpage,
- enum cl_page_type type)
+struct cl_page *cl_page_alloc(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *o, pgoff_t ind,
+ struct page *vmpage, enum cl_page_type type)
{
struct cl_page *cl_page;
struct cl_object *head;
cl_page->cp_page_index = ind;
cl_object_for_each(o, head) {
if (o->co_ops->coo_page_init != NULL) {
- result = o->co_ops->coo_page_init(env, o,
+ result = o->co_ops->coo_page_init(env, io, o,
cl_page, ind);
if (result != 0) {
__cl_page_delete(env, cl_page);
*
* \see cl_object_find(), cl_lock_find()
*/
-struct cl_page *cl_page_find(const struct lu_env *env,
+struct cl_page *cl_page_find(const struct lu_env *env, struct cl_io *io,
struct cl_object *o,
pgoff_t idx, struct page *vmpage,
enum cl_page_type type)
}
/* allocate and initialize cl_page */
- page = cl_page_alloc(env, o, idx, vmpage, type);
+ page = cl_page_alloc(env, io, o, idx, vmpage, type);
RETURN(page);
}
EXPORT_SYMBOL(cl_page_find);
#define DEBUG_SUBSYSTEM S_OSC
#include <lustre_osc.h>
+#include <lnet/lnet_rdma.h>
#include "osc_internal.h"
.cpo_page_touch = osc_page_touch,
};
-int osc_page_init(const struct lu_env *env, struct cl_object *obj,
- struct cl_page *cl_page, pgoff_t index)
+int osc_page_init(const struct lu_env *env, struct cl_io *io,
+ struct cl_object *obj, struct cl_page *cl_page, pgoff_t index)
{
struct osc_object *osc = cl2osc(obj);
struct osc_page *opg = cl_object_page_slice(obj, cl_page);
opg->ops_srvlock = osc_io_srvlock(oio);
cl_page_slice_add(cl_page, &opg->ops_cl, obj, &osc_page_ops);
+ if ((lnet_is_rdma_only_page(cl_page->cp_vmpage) ||
+ CFS_FAIL_CHECK(OBD_FAIL_OSC_UNALIGNED_RDMA_ONLY)) &&
+ io->ci_unaligned_dio) {
+ LASSERT(cl_page->cp_type == CPT_TRANSIENT);
+ /* setting this flag saves a little time if there are further
+ * stripes, but this is mostly for clarity in case we need this
+ * info later
+ */
+ io->ci_allow_unaligned_dio = false;
+ return -EINVAL;
+ }
+
/* reserve an LRU space for this page */
if (cl_page->cp_type == CPT_CACHEABLE) {
result = osc_lru_alloc(env, osc_cli(osc), opg);
}
run_test 119i "test unaligned aio at varying sizes"
+test_119j()
+{
+ (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
+ skip "Need server version at least 2.15.58"
+ (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
+
+ $LFS setstripe -c 2 -S 1M $DIR/$tfile
+
+ # trivial test of unaligned DIO, should work fine
+ dd if=/dev/urandom bs=4095 of=$DIR/$tfile count=4 \
+ oflag=direct ||
+ error "trivial unaligned dio failed"
+
+#define OBD_FAIL_OSC_UNALIGNED_RDMA_ONLY 0x418
+ $LCTL set_param fail_loc=0x418
+ # trivial test of unaligned DIO
+ dd if=/dev/urandom bs=4095 of=$DIR/$tfile count=4 \
+ oflag=direct &&
+ error "unaligned DIO succeeded with (fake) rdma only page"
+ echo "unaligned DIO with rdma only pages failed as expected"
+}
+run_test 119j "verify unaligned DIO + rdma_only fails as expected"
+
test_120a() {
[ $PARALLEL == "yes" ] && skip "skip parallel run"
remote_mds_nodsh && skip "remote MDS with nodsh"