* GPL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved
+ * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* Use is subject to license terms.
*/
/*
lcc = ERR_PTR(result);
}
- CDEBUG(D_VFSTRACE, "%lu@"DFID" -> %i %p %p\n",
+ CDEBUG(D_VFSTRACE, "%lu@"DFID" -> %d %p %p\n",
vmpage->index, PFID(lu_object_fid(&clob->co_lu)), result,
env, io);
return lcc;
*/
static int ll_read_ahead_page(const struct lu_env *env, struct cl_io *io,
struct cl_page_list *queue,
- int index, struct address_space *mapping)
+ pgoff_t index, struct address_space *mapping)
{
struct page *vmpage;
struct cl_object *clob = ll_i2info(mapping->host)->lli_clob;
stride_pg_count(pgoff_t st_off, unsigned long st_len, unsigned long st_pgs,
unsigned long off, unsigned long length)
{
- unsigned long start = off > st_off ? off - st_off : 0;
- unsigned long end = off + length > st_off ? off + length - st_off : 0;
+ __u64 start = off > st_off ? off - st_off : 0;
+ __u64 end = off + length > st_off ? off + length - st_off : 0;
unsigned long start_left = 0;
unsigned long end_left = 0;
unsigned long pg_count;
if (end_left > st_pgs)
end_left = st_pgs;
- CDEBUG(D_READA, "start %lu, end %lu start_left %lu end_left %lu \n",
+ CDEBUG(D_READA, "start "LPU64", end "LPU64" start_left %lu end_left %lu \n",
start, end, start_left, end_left);
if (start == end)
* For stride I/O mode, just check whether the idx is inside
* the ria_pages. */
return ria->ria_length == 0 || ria->ria_length == ria->ria_pages ||
- (idx - ria->ria_stoff) % ria->ria_length < ria->ria_pages;
+ (idx >= ria->ria_stoff && (idx - ria->ria_stoff) %
+ ria->ria_length < ria->ria_pages);
}
static int ll_read_ahead_pages(const struct lu_env *env,
/* FIXME: This assertion only is valid when it is for
* forward read-ahead, it will be fixed when backward
* read-ahead is implemented */
- LASSERTF(page_idx > ria->ria_stoff, "since %lu in the"
- " gap of ra window,it should bigger than stride"
- " offset %lu \n", page_idx, ria->ria_stoff);
-
+ LASSERTF(page_idx > ria->ria_stoff, "Invalid page_idx %lu"
+ "rs %lu re %lu ro %lu rl %lu rp %lu\n", page_idx,
+ ria->ria_start, ria->ria_end, ria->ria_stoff,
+ ria->ria_length, ria->ria_pages);
offset = page_idx - ria->ria_stoff;
offset = offset % (ria->ria_length);
if (offset > ria->ria_pages) {
end = ras->ras_window_start + ras->ras_window_len - 1;
}
if (end != 0) {
+ unsigned long tmp_end;
+ /*
+ * Align RA window to an optimal boundary.
+ *
+ * XXX This would be better to align to cl_max_pages_per_rpc
+ * instead of PTLRPC_MAX_BRW_PAGES, because the RPC size may
+ * be aligned to the RAID stripe size in the future and that
+ * is more important than the RPC size.
+ */
+ tmp_end = ((end + 1) & (~(PTLRPC_MAX_BRW_PAGES - 1))) - 1;
+ if (tmp_end > start)
+ end = tmp_end;
+
/* Truncate RA window to end of file */
end = min(end, (unsigned long)((kms - 1) >> CFS_PAGE_SHIFT));
+
ras->ras_next_readahead = max(end, end + 1);
RAS_CDEBUG(ras);
}
int zero = 0, stride_detect = 0, ra_miss = 0;
ENTRY;
- cfs_spin_lock(&sbi->ll_lock);
cfs_spin_lock(&ras->ras_lock);
ll_ra_stats_inc_sbi(sbi, hit ? RA_STAT_HIT : RA_STAT_MISS);
ras->ras_consecutive_pages++;
ras->ras_last_readpage = index;
ras_set_start(ras, index);
- ras->ras_next_readahead = max(ras->ras_window_start,
- ras->ras_next_readahead);
+
+ if (stride_io_mode(ras))
+ /* Since stride readahead is sentivite to the offset
+ * of read-ahead, so we use original offset here,
+ * instead of ras_window_start, which is 1M aligned*/
+ ras->ras_next_readahead = max(index,
+ ras->ras_next_readahead);
+ else
+ ras->ras_next_readahead = max(ras->ras_window_start,
+ ras->ras_next_readahead);
RAS_CDEBUG(ras);
/* Trigger RA in the mmap case where ras_consecutive_requests
RAS_CDEBUG(ras);
ras->ras_request_index++;
cfs_spin_unlock(&ras->ras_lock);
- cfs_spin_unlock(&sbi->ll_lock);
return;
}
}
ll_cl_fini(lcc);
} else {
+ unlock_page(vmpage);
result = PTR_ERR(lcc);
}
RETURN(result);