- CLASSERT(sizeof(pos) == sizeof(__u64));
-
- id->vpi_index = pos & 0xffffffff;
- id->vpi_depth = (pos >> PGC_DEPTH_SHIFT) & 0xf;
- id->vpi_bucket = ((unsigned long long)pos >> PGC_OBJ_SHIFT);
-}
-
-static loff_t vvp_pgcache_id_pack(struct vvp_pgcache_id *id)
-{
- return
- ((__u64)id->vpi_index) |
- ((__u64)id->vpi_depth << PGC_DEPTH_SHIFT) |
- ((__u64)id->vpi_bucket << PGC_OBJ_SHIFT);
-}
-
-static int vvp_pgcache_obj_get(cfs_hash_t *hs, cfs_hash_bd_t *bd,
- cfs_hlist_node_t *hnode, void *data)
-{
- struct vvp_pgcache_id *id = data;
- struct lu_object_header *hdr = cfs_hash_object(hs, hnode);
-
- if (id->vpi_curdep-- > 0)
- return 0; /* continue */
-
- if (lu_object_is_dying(hdr))
- return 1;
-
- cfs_hash_get(hs, hnode);
- id->vpi_obj = hdr;
- return 1;
-}
-
-static struct cl_object *vvp_pgcache_obj(const struct lu_env *env,
- struct lu_device *dev,
- struct vvp_pgcache_id *id)
-{
- LASSERT(lu_device_is_cl(dev));
-
- id->vpi_depth &= 0xf;
- id->vpi_obj = NULL;
- id->vpi_curdep = id->vpi_depth;
-
- cfs_hash_hlist_for_each(dev->ld_site->ls_obj_hash, id->vpi_bucket,
- vvp_pgcache_obj_get, id);
- if (id->vpi_obj != NULL) {
- struct lu_object *lu_obj;
-
- lu_obj = lu_object_locate(id->vpi_obj, dev->ld_type);
- if (lu_obj != NULL) {
- lu_object_ref_add(lu_obj, "dump", cfs_current());
- return lu2cl(lu_obj);
- }
- lu_object_put(env, lu_object_top(id->vpi_obj));
-
- } else if (id->vpi_curdep > 0) {
- id->vpi_depth = 0xf;
- }
- return NULL;
-}
-
-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 >= CFS_HASH_NHLIST(site->ls_obj_hash))
- 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;