return rc;
}
+static int ofd_ladvise_prefetch(const struct lu_env *env,
+ struct ofd_object *fo,
+ __u64 start, __u64 end)
+{
+ struct ofd_thread_info *info = ofd_info(env);
+ pgoff_t start_index, end_index, pages;
+ struct niobuf_remote rnb;
+ unsigned long nr_local;
+ struct niobuf_local *lnb;
+ int rc = 0;
+
+ if (end <= start)
+ RETURN(-EINVAL);
+
+ OBD_ALLOC_LARGE(lnb, sizeof(*lnb) * PTLRPC_MAX_BRW_PAGES);
+ if (lnb == NULL)
+ RETURN(-ENOMEM);
+
+ ofd_read_lock(env, fo);
+ if (!ofd_object_exists(fo))
+ GOTO(out_unlock, rc = -ENOENT);
+
+ rc = ofd_attr_get(env, fo, &info->fti_attr);
+ if (rc)
+ GOTO(out_unlock, rc);
+
+ if (end > info->fti_attr.la_size)
+ end = info->fti_attr.la_size;
+
+ if (end == 0)
+ GOTO(out_unlock, rc);
+
+ /* We need page aligned offset and length */
+ start_index = start >> PAGE_CACHE_SHIFT;
+ end_index = (end - 1) >> PAGE_CACHE_SHIFT;
+ pages = end_index - start_index + 1;
+ while (pages > 0) {
+ nr_local = pages <= PTLRPC_MAX_BRW_PAGES ? pages :
+ PTLRPC_MAX_BRW_PAGES;
+ rnb.rnb_offset = start_index << PAGE_CACHE_SHIFT;
+ rnb.rnb_len = nr_local << PAGE_CACHE_SHIFT;
+ rc = dt_bufs_get(env, ofd_object_child(fo), &rnb, lnb, 0);
+ if (unlikely(rc < 0))
+ break;
+ nr_local = rc;
+ rc = dt_read_prep(env, ofd_object_child(fo), lnb, nr_local);
+ dt_bufs_put(env, ofd_object_child(fo), lnb, nr_local);
+ if (unlikely(rc))
+ break;
+ start_index += nr_local;
+ pages -= nr_local;
+ }
+
+out_unlock:
+ ofd_read_unlock(env, fo);
+ OBD_FREE_LARGE(lnb, sizeof(*lnb) * PTLRPC_MAX_BRW_PAGES);
+ RETURN(rc);
+}
+
/**
* OFD request handler for OST_LADVISE RPC.
*
struct lu_ladvise *ladvise;
int num_advise;
struct ladvise_hdr *ladvise_hdr;
+ struct obd_ioobj ioo;
+ struct lustre_handle lockh = { 0 };
+ __u64 flags = 0;
int i;
ENTRY;
+ CFS_FAIL_TIMEOUT(OBD_FAIL_OST_LADVISE_PAUSE, cfs_fail_val);
body = tsi->tsi_ost_body;
if ((body->oa.o_valid & OBD_MD_FLID) != OBD_MD_FLID)
num_advise = req_capsule_get_size(&req->rq_pill,
&RMF_OST_LADVISE, RCL_CLIENT) /
- sizeof(*ladvise);
+ sizeof(*ladvise);
if (num_advise < ladvise_hdr->lah_count)
RETURN(err_serious(-EPROTO));
default:
rc = -ENOTSUPP;
break;
+ case LU_LADVISE_WILLREAD:
+ ioo.ioo_oid = body->oa.o_oi;
+ ioo.ioo_bufcnt = 1;
+ rc = tgt_extent_lock(exp->exp_obd->obd_namespace,
+ &tsi->tsi_resid,
+ ladvise->lla_start,
+ ladvise->lla_end - 1,
+ &lockh, LCK_PR, &flags);
+ if (rc != 0)
+ break;
+
+ req->rq_status = ofd_ladvise_prefetch(env,
+ fo,
+ ladvise->lla_start,
+ ladvise->lla_end);
+ tgt_extent_unlock(&lockh, LCK_PR);
+ break;
}
if (rc != 0)
break;