}
 EXPORT_SYMBOL_GPL(zs_unmap_object);
 
+void *zs_obj_read_begin(struct zs_pool *pool, unsigned long handle,
+                       void *local_copy)
+{
+       struct zspage *zspage;
+       struct zpdesc *zpdesc;
+       unsigned long obj, off;
+       unsigned int obj_idx;
+       struct size_class *class;
+       void *addr;
+
+       /* Guarantee we can get zspage from handle safely */
+       read_lock(&pool->lock);
+       obj = handle_to_obj(handle);
+       obj_to_location(obj, &zpdesc, &obj_idx);
+       zspage = get_zspage(zpdesc);
+
+       /* Make sure migration doesn't move any pages in this zspage */
+       zspage_read_lock(zspage);
+       read_unlock(&pool->lock);
+
+       class = zspage_class(pool, zspage);
+       off = offset_in_page(class->size * obj_idx);
+
+       if (off + class->size <= PAGE_SIZE) {
+               /* this object is contained entirely within a page */
+               addr = kmap_local_zpdesc(zpdesc);
+               addr += off;
+       } else {
+               size_t sizes[2];
+
+               /* this object spans two pages */
+               sizes[0] = PAGE_SIZE - off;
+               sizes[1] = class->size - sizes[0];
+               addr = local_copy;
+
+               memcpy_from_page(addr, zpdesc_page(zpdesc),
+                                off, sizes[0]);
+               zpdesc = get_next_zpdesc(zpdesc);
+               memcpy_from_page(addr + sizes[0],
+                                zpdesc_page(zpdesc),
+                                0, sizes[1]);
+       }
+
+       if (!ZsHugePage(zspage))
+               addr += ZS_HANDLE_SIZE;
+
+       return addr;
+}
+EXPORT_SYMBOL_GPL(zs_obj_read_begin);
+
+void zs_obj_read_end(struct zs_pool *pool, unsigned long handle,
+                    void *handle_mem)
+{
+       struct zspage *zspage;
+       struct zpdesc *zpdesc;
+       unsigned long obj, off;
+       unsigned int obj_idx;
+       struct size_class *class;
+
+       obj = handle_to_obj(handle);
+       obj_to_location(obj, &zpdesc, &obj_idx);
+       zspage = get_zspage(zpdesc);
+       class = zspage_class(pool, zspage);
+       off = offset_in_page(class->size * obj_idx);
+
+       if (off + class->size <= PAGE_SIZE) {
+               if (!ZsHugePage(zspage))
+                       off += ZS_HANDLE_SIZE;
+               handle_mem -= off;
+               kunmap_local(handle_mem);
+       }
+
+       zspage_read_unlock(zspage);
+}
+EXPORT_SYMBOL_GPL(zs_obj_read_end);
+
+void zs_obj_write(struct zs_pool *pool, unsigned long handle,
+                 void *handle_mem, size_t mem_len)
+{
+       struct zspage *zspage;
+       struct zpdesc *zpdesc;
+       unsigned long obj, off;
+       unsigned int obj_idx;
+       struct size_class *class;
+
+       /* Guarantee we can get zspage from handle safely */
+       read_lock(&pool->lock);
+       obj = handle_to_obj(handle);
+       obj_to_location(obj, &zpdesc, &obj_idx);
+       zspage = get_zspage(zpdesc);
+
+       /* Make sure migration doesn't move any pages in this zspage */
+       zspage_read_lock(zspage);
+       read_unlock(&pool->lock);
+
+       class = zspage_class(pool, zspage);
+       off = offset_in_page(class->size * obj_idx);
+
+       if (off + class->size <= PAGE_SIZE) {
+               /* this object is contained entirely within a page */
+               void *dst = kmap_local_zpdesc(zpdesc);
+
+               if (!ZsHugePage(zspage))
+                       off += ZS_HANDLE_SIZE;
+               memcpy(dst + off, handle_mem, mem_len);
+               kunmap_local(dst);
+       } else {
+               /* this object spans two pages */
+               size_t sizes[2];
+
+               off += ZS_HANDLE_SIZE;
+               sizes[0] = PAGE_SIZE - off;
+               sizes[1] = mem_len - sizes[0];
+
+               memcpy_to_page(zpdesc_page(zpdesc), off,
+                              handle_mem, sizes[0]);
+               zpdesc = get_next_zpdesc(zpdesc);
+               memcpy_to_page(zpdesc_page(zpdesc), 0,
+                              handle_mem + sizes[0], sizes[1]);
+       }
+
+       zspage_read_unlock(zspage);
+}
+EXPORT_SYMBOL_GPL(zs_obj_write);
+
 /**
  * zs_huge_class_size() - Returns the size (in bytes) of the first huge
  *                        zsmalloc &size_class.