- return
- ((__u64)id->vpi_index) |
- ((__u64)id->vpi_depth << PGC_DEPTH_SHIFT) |
- ((__u64)id->vpi_bucket << PGC_OBJ_SHIFT);
-}
-
-static struct cl_object *vvp_pgcache_obj(const struct lu_env *env,
- struct lu_device *dev,
- struct vvp_pgcache_id *id)
-{
- struct hlist_head *bucket;
- struct lu_object_header *hdr;
- struct lu_site *site;
- struct hlist_node *scan;
- struct lu_object_header *found;
- struct cl_object *clob;
- unsigned depth;
-
- LASSERT(lu_device_is_cl(dev));
-
- site = dev->ld_site;
- bucket = site->ls_hash + (id->vpi_bucket & site->ls_hash_mask);
- depth = id->vpi_depth & 0xf;
- found = NULL;
- clob = NULL;
-
- /* XXX copy of lu_object.c:htable_lookup() */
- read_lock(&site->ls_guard);
- hlist_for_each_entry(hdr, scan, bucket, loh_hash) {
- if (depth-- == 0) {
- if (!lu_object_is_dying(hdr)) {
- if (atomic_add_return(1, &hdr->loh_ref) == 1)
- ++ site->ls_busy;
- found = hdr;
- }
- break;
- }
- }
- read_unlock(&site->ls_guard);
-
- if (found != NULL) {
- struct lu_object *lu_obj;
-
- lu_obj = lu_object_locate(found, dev->ld_type);
- if (lu_obj != NULL) {
- lu_object_ref_add(lu_obj, "dump", cfs_current());
- clob = lu2cl(lu_obj);
- } else
- lu_object_put(env, lu_object_top(found));
- } else if (depth > 0)
- id->vpi_depth = 0xf;
- return clob;
-}
-
-static loff_t vvp_pgcache_find(const struct lu_env *env,
- struct lu_device *dev, loff_t pos)
-{
- struct cl_object *clob;
- struct lu_site *site;
- struct vvp_pgcache_id id;
-
- site = dev->ld_site;
- vvp_pgcache_id_unpack(pos, &id);
-
- while (1) {
- if (id.vpi_bucket >= site->ls_hash_size)
- return ~0ULL;
- clob = vvp_pgcache_obj(env, dev, &id);
- if (clob != NULL) {
- struct cl_object_header *hdr;
- int nr;
- struct cl_page *pg;
-
- /* got an object. Find next page. */
- hdr = cl_object_header(clob);
-
- spin_lock(&hdr->coh_page_guard);
- nr = radix_tree_gang_lookup(&hdr->coh_tree,
- (void **)&pg,
- id.vpi_index, 1);
- if (nr > 0) {
- id.vpi_index = pg->cp_index;
- /* Cant support over 16T file */
- nr = !(pg->cp_index > 0xffffffff);
- }
- spin_unlock(&hdr->coh_page_guard);
-
- lu_object_ref_del(&clob->co_lu, "dump", cfs_current());
- cl_object_put(env, clob);
- if (nr > 0)
- return vvp_pgcache_id_pack(&id);
- }
- /* to the next object. */
- ++id.vpi_depth;
- id.vpi_depth &= 0xf;
- if (id.vpi_depth == 0 && ++id.vpi_bucket == 0)
- return ~0ULL;
- id.vpi_index = 0;
- }
+ struct lu_device *dev = &priv->vsp_sbi->ll_cl->cd_lu_dev;
+ struct lu_object_header *h;
+ struct page *vmpage = NULL;
+
+ rhashtable_walk_start(&priv->vsp_iter);
+ while ((h = rhashtable_walk_next(&priv->vsp_iter)) != NULL) {
+ struct inode *inode;
+ int nr;
+
+ if (!priv->vsp_clob) {
+ struct lu_object *lu_obj;
+
+ lu_obj = lu_object_get_first(h, dev);
+ if (!lu_obj)
+ continue;
+
+ priv->vsp_clob = lu2cl(lu_obj);
+ lu_object_ref_add(lu_obj, "dump", current);
+ priv->vsp_page_index = 0;
+ }
+
+ inode = vvp_object_inode(priv->vsp_clob);
+ nr = find_get_pages_contig(inode->i_mapping,
+ priv->vsp_page_index, 1, &vmpage);
+ if (nr > 0) {
+ priv->vsp_page_index = vmpage->index;
+ break;
+ }
+ lu_object_ref_del(&priv->vsp_clob->co_lu, "dump", current);
+ cl_object_put(priv->vsp_env, priv->vsp_clob);
+ priv->vsp_clob = NULL;
+ priv->vsp_page_index = 0;
+ }
+ rhashtable_walk_stop(&priv->vsp_iter);
+ return vmpage;