@@ -1474,6 +1474,8 @@ struct cl_read_ahead {
void (*cra_release)(const struct lu_env *env, void *cbdata);
/* Callback data for cra_release routine */
void *cra_cbdata;
+ /* whether lock is in contention */
+ bool cra_contention;
};
static inline void cl_read_ahead_release(const struct lu_env *env,
@@ -369,6 +369,18 @@ static int ras_inside_ra_window(unsigned long idx, struct ra_io_arg *ria)
if (rc < 0)
break;
+ /* Do not shrink the ria_end at any case until
+ * the minimum end of current read is covered.
+ * And only shrink the ria_end if the matched
+ * LDLM lock doesn't cover more.
+ */
+ if (page_idx > ra.cra_end ||
+ (ra.cra_contention &&
+ page_idx > ria->ria_end_min)) {
+ ria->ria_end = ra.cra_end;
+ break;
+ }
+
CDEBUG(D_READA, "idx: %lu, ra: %lu, rpc: %lu\n",
page_idx, ra.cra_end, ra.cra_rpc_size);
LASSERTF(ra.cra_end >= page_idx,
@@ -387,8 +399,6 @@ static int ras_inside_ra_window(unsigned long idx, struct ra_io_arg *ria)
ria->ria_end = end - 1;
if (ria->ria_end < ria->ria_end_min)
ria->ria_end = ria->ria_end_min;
- if (ria->ria_end > ra.cra_end)
- ria->ria_end = ra.cra_end;
}
/* If the page is inside the read-ahead window */
@@ -92,6 +92,8 @@ static int osc_io_read_ahead(const struct lu_env *env,
dlmlock->l_policy_data.l_extent.end);
ra->cra_release = osc_read_ahead_release;
ra->cra_cbdata = dlmlock;
+ if (ra->cra_end != CL_PAGE_EOF)
+ ra->cra_contention = true;
result = 0;
}