* RPC.
*/
if (io->ci_need_write_intent) {
- loff_t start = 0;
- loff_t end = OBD_OBJECT_EOF;
-
io->ci_need_write_intent = 0;
LASSERT(io->ci_type == CIT_WRITE ||
cl_io_is_trunc(io) || cl_io_is_mkwrite(io));
- if (io->ci_type == CIT_WRITE) {
- if (!cl_io_is_append(io)) {
- start = io->u.ci_rw.rw_range.cir_pos;
- end = start + io->u.ci_rw.rw_range.cir_count;
- }
- } else if (cl_io_is_trunc(io)) {
- end = io->u.ci_setattr.sa_attr.lvb_size;
- } else { /* mkwrite */
- pgoff_t index = io->u.ci_fault.ft_index;
-
- start = cl_offset(io->ci_obj, index);
- end = cl_offset(io->ci_obj, index + 1);
- }
-
- CDEBUG(D_VFSTRACE, DFID" write layout, type %u [%llu, %llu)\n",
+ CDEBUG(D_VFSTRACE, DFID" write layout, type %u "DEXT"\n",
PFID(lu_object_fid(&obj->co_lu)), io->ci_type,
- start, end);
- rc = ll_layout_write_intent(inode, start, end);
+ PEXT(&io->ci_write_intent));
+
+ rc = ll_layout_write_intent(inode, io->ci_write_intent.e_start,
+ io->ci_write_intent.e_end);
io->ci_result = rc;
if (!rc)
io->ci_need_restart = 1;
static int lov_io_slice_init(struct lov_io *lio,
struct lov_object *obj, struct cl_io *io)
{
+ struct lu_extent ext;
+ int index;
int result = 0;
ENTRY;
}
result = lov_io_mirror_init(lio, obj, io);
+ if (result)
+ RETURN(result);
+
+ /* check if it needs to instantiate layout */
+ if (!(io->ci_type == CIT_WRITE || cl_io_is_mkwrite(io) ||
+ (cl_io_is_trunc(io) && io->u.ci_setattr.sa_attr.lvb_size > 0)))
+ RETURN(0);
+
+ ext.e_start = lio->lis_pos;
+ ext.e_end = lio->lis_endpos;
+
+ /* for truncate, it only needs to instantiate the components
+ * before the truncated size. */
+ if (cl_io_is_trunc(io)) {
+ ext.e_start = 0;
+ ext.e_end = io->u.ci_setattr.sa_attr.lvb_size;
+ }
+
+ index = 0;
+ lov_foreach_io_layout(index, lio, &ext) {
+ if (!lsm_entry_inited(obj->lo_lsm, index)) {
+ io->ci_need_write_intent = 1;
+ io->ci_write_intent = ext;
+ result = 1;
+ break;
+ }
+ }
+
RETURN(result);
}
static int lov_io_iter_init(const struct lu_env *env,
const struct cl_io_slice *ios)
{
- struct cl_io *io = ios->cis_io;
struct lov_io *lio = cl2lov_io(env, ios);
struct lov_stripe_md *lsm = lio->lis_object->lo_lsm;
struct lov_io_sub *sub;
CDEBUG(D_VFSTRACE, "component[%d] flags %#x\n",
index, lsm->lsm_entries[index]->lsme_flags);
if (!lsm_entry_inited(lsm, index)) {
- /* truncate IO will trigger write intent as well, and
- * it's handled in lov_io_setattr_iter_init() */
- if (io->ci_type == CIT_WRITE || cl_io_is_mkwrite(io)) {
- io->ci_need_write_intent = 1;
- /* execute it in main thread */
- io->ci_pio = 0;
- rc = -ENODATA;
- break;
- }
-
/* Read from uninitialized components should return
* zero filled pages. */
continue;
{
struct cl_io *io = ios->cis_io;
struct lov_io *lio = cl2lov_io(env, ios);
- struct lov_stripe_md *lsm = lio->lis_object->lo_lsm;
struct lov_stripe_md_entry *lse;
struct cl_io_range *range = &io->u.ci_rw.rw_range;
loff_t start = range->cir_pos;
io->ci_pio = 0;
}
- if (io->ci_pio) {
- /* it only splits IO here for parallel IO,
- * there will be no actual IO going to occur,
- * so it doesn't need to invoke lov_io_iter_init()
- * to initialize sub IOs. */
- if (!lsm_entry_inited(lsm, index)) {
- io->ci_need_write_intent = 1;
- RETURN(-ENODATA);
- }
+ if (io->ci_pio)
RETURN(0);
- }
/*
* XXX The following call should be optimized: we know, that
{
struct lov_io *lio = cl2lov_io(env, ios);
struct cl_io *io = ios->cis_io;
- struct lov_stripe_md *lsm = lio->lis_object->lo_lsm;
int index;
ENTRY;
if (cl_io_is_trunc(io) && lio->lis_pos > 0) {
index = lov_io_layout_at(lio, lio->lis_pos - 1);
/* no entry found for such offset */
- if (index < 0) {
+ if (index < 0)
RETURN(io->ci_result = -ENODATA);
- } else if (!lsm_entry_inited(lsm, index)) {
- io->ci_need_write_intent = 1;
- RETURN(io->ci_result = -ENODATA);
- }
}
RETURN(lov_io_iter_init(env, ios));