blob: aa1ed790b5a387fce482a79a442dd10d391815c8 [file] [log] [blame]
Phillip Lougher846b7302013-11-18 02:59:12 +00001#ifndef PAGE_ACTOR_H
2#define PAGE_ACTOR_H
3/*
4 * Copyright (c) 2013
5 * Phillip Lougher <phillip@squashfs.org.uk>
6 *
7 * This work is licensed under the terms of the GNU GPL, version 2. See
Adrien Schildknecht38840af2016-09-28 13:59:18 -07008 * the COPYING file in the top-level squashfsory.
Phillip Lougher846b7302013-11-18 02:59:12 +00009 */
10
Phillip Lougher0d455c12013-11-13 02:04:19 +000011struct squashfs_page_actor {
Adrien Schildknecht38840af2016-09-28 13:59:18 -070012 struct page **page;
Phillip Lougher0d455c12013-11-13 02:04:19 +000013 void *pageaddr;
Phillip Lougher0d455c12013-11-13 02:04:19 +000014 int pages;
15 int length;
16 int next_page;
Adrien Schildknecht38840af2016-09-28 13:59:18 -070017 void (*release_pages)(struct page **, int, int);
Phillip Lougher0d455c12013-11-13 02:04:19 +000018};
19
Adrien Schildknecht38840af2016-09-28 13:59:18 -070020extern struct squashfs_page_actor *squashfs_page_actor_init(struct page **,
21 int, int, void (*)(struct page **, int, int));
22extern void squashfs_page_actor_free(struct squashfs_page_actor *, int);
23
24extern void squashfs_actor_to_buf(struct squashfs_page_actor *, void *, int);
25extern void squashfs_buf_to_actor(void *, struct squashfs_page_actor *, int);
26extern void squashfs_bh_to_actor(struct buffer_head **, int,
27 struct squashfs_page_actor *, int, int, int);
28extern void squashfs_bh_to_buf(struct buffer_head **, int, void *, int, int,
29 int);
30
31/*
32 * Calling code should avoid sleeping between calls to squashfs_first_page()
33 * and squashfs_finish_page().
34 */
Phillip Lougher0d455c12013-11-13 02:04:19 +000035static inline void *squashfs_first_page(struct squashfs_page_actor *actor)
36{
Adrien Schildknecht38840af2016-09-28 13:59:18 -070037 actor->next_page = 1;
38 return actor->pageaddr = actor->page[0] ? kmap_atomic(actor->page[0])
39 : NULL;
Phillip Lougher0d455c12013-11-13 02:04:19 +000040}
Adrien Schildknecht38840af2016-09-28 13:59:18 -070041
Phillip Lougher0d455c12013-11-13 02:04:19 +000042static inline void *squashfs_next_page(struct squashfs_page_actor *actor)
43{
Adrien Schildknecht38840af2016-09-28 13:59:18 -070044 if (!IS_ERR_OR_NULL(actor->pageaddr))
45 kunmap_atomic(actor->pageaddr);
46
47 if (actor->next_page == actor->pages)
48 return actor->pageaddr = ERR_PTR(-ENODATA);
49
50 actor->pageaddr = actor->page[actor->next_page] ?
51 kmap_atomic(actor->page[actor->next_page]) : NULL;
52 ++actor->next_page;
53 return actor->pageaddr;
Phillip Lougher0d455c12013-11-13 02:04:19 +000054}
Adrien Schildknecht38840af2016-09-28 13:59:18 -070055
Phillip Lougher0d455c12013-11-13 02:04:19 +000056static inline void squashfs_finish_page(struct squashfs_page_actor *actor)
57{
Adrien Schildknecht38840af2016-09-28 13:59:18 -070058 if (!IS_ERR_OR_NULL(actor->pageaddr))
59 kunmap_atomic(actor->pageaddr);
Phillip Lougher0d455c12013-11-13 02:04:19 +000060}
Adrien Schildknecht0f1ddd12016-09-28 12:14:39 -070061
Adrien Schildknecht38840af2016-09-28 13:59:18 -070062extern struct page **alloc_page_array(int, int);
63extern void free_page_array(struct page **, int);
64
Phillip Lougher846b7302013-11-18 02:59:12 +000065#endif