Linux Audio

Check our new training course

Loading...
v4.6
  1/*
  2 * Copyright (c) 2013
  3 * Phillip Lougher <phillip@squashfs.org.uk>
  4 *
  5 * This work is licensed under the terms of the GNU GPL, version 2. See
  6 * the COPYING file in the top-level directory.
  7 */
  8
  9#include <linux/kernel.h>
 10#include <linux/slab.h>
 11#include <linux/pagemap.h>
 12#include "page_actor.h"
 13
 14/*
 15 * This file contains implementations of page_actor for decompressing into
 16 * an intermediate buffer, and for decompressing directly into the
 17 * page cache.
 18 *
 19 * Calling code should avoid sleeping between calls to squashfs_first_page()
 20 * and squashfs_finish_page().
 21 */
 22
 23/* Implementation of page_actor for decompressing into intermediate buffer */
 24static void *cache_first_page(struct squashfs_page_actor *actor)
 25{
 26	actor->next_page = 1;
 27	return actor->buffer[0];
 28}
 29
 30static void *cache_next_page(struct squashfs_page_actor *actor)
 31{
 32	if (actor->next_page == actor->pages)
 33		return NULL;
 34
 35	return actor->buffer[actor->next_page++];
 36}
 37
 38static void cache_finish_page(struct squashfs_page_actor *actor)
 39{
 40	/* empty */
 41}
 42
 43struct squashfs_page_actor *squashfs_page_actor_init(void **buffer,
 44	int pages, int length)
 45{
 46	struct squashfs_page_actor *actor = kmalloc(sizeof(*actor), GFP_KERNEL);
 47
 48	if (actor == NULL)
 49		return NULL;
 50
 51	actor->length = length ? : pages * PAGE_SIZE;
 52	actor->buffer = buffer;
 53	actor->pages = pages;
 54	actor->next_page = 0;
 55	actor->squashfs_first_page = cache_first_page;
 56	actor->squashfs_next_page = cache_next_page;
 57	actor->squashfs_finish_page = cache_finish_page;
 58	return actor;
 59}
 60
 61/* Implementation of page_actor for decompressing directly into page cache. */
 62static void *direct_first_page(struct squashfs_page_actor *actor)
 63{
 64	actor->next_page = 1;
 65	return actor->pageaddr = kmap_atomic(actor->page[0]);
 66}
 67
 68static void *direct_next_page(struct squashfs_page_actor *actor)
 69{
 70	if (actor->pageaddr)
 71		kunmap_atomic(actor->pageaddr);
 72
 73	return actor->pageaddr = actor->next_page == actor->pages ? NULL :
 74		kmap_atomic(actor->page[actor->next_page++]);
 75}
 76
 77static void direct_finish_page(struct squashfs_page_actor *actor)
 78{
 79	if (actor->pageaddr)
 80		kunmap_atomic(actor->pageaddr);
 81}
 82
 83struct squashfs_page_actor *squashfs_page_actor_init_special(struct page **page,
 84	int pages, int length)
 85{
 86	struct squashfs_page_actor *actor = kmalloc(sizeof(*actor), GFP_KERNEL);
 87
 88	if (actor == NULL)
 89		return NULL;
 90
 91	actor->length = length ? : pages * PAGE_SIZE;
 92	actor->page = page;
 93	actor->pages = pages;
 94	actor->next_page = 0;
 95	actor->pageaddr = NULL;
 96	actor->squashfs_first_page = direct_first_page;
 97	actor->squashfs_next_page = direct_next_page;
 98	actor->squashfs_finish_page = direct_finish_page;
 99	return actor;
100}
v3.15
  1/*
  2 * Copyright (c) 2013
  3 * Phillip Lougher <phillip@squashfs.org.uk>
  4 *
  5 * This work is licensed under the terms of the GNU GPL, version 2. See
  6 * the COPYING file in the top-level directory.
  7 */
  8
  9#include <linux/kernel.h>
 10#include <linux/slab.h>
 11#include <linux/pagemap.h>
 12#include "page_actor.h"
 13
 14/*
 15 * This file contains implementations of page_actor for decompressing into
 16 * an intermediate buffer, and for decompressing directly into the
 17 * page cache.
 18 *
 19 * Calling code should avoid sleeping between calls to squashfs_first_page()
 20 * and squashfs_finish_page().
 21 */
 22
 23/* Implementation of page_actor for decompressing into intermediate buffer */
 24static void *cache_first_page(struct squashfs_page_actor *actor)
 25{
 26	actor->next_page = 1;
 27	return actor->buffer[0];
 28}
 29
 30static void *cache_next_page(struct squashfs_page_actor *actor)
 31{
 32	if (actor->next_page == actor->pages)
 33		return NULL;
 34
 35	return actor->buffer[actor->next_page++];
 36}
 37
 38static void cache_finish_page(struct squashfs_page_actor *actor)
 39{
 40	/* empty */
 41}
 42
 43struct squashfs_page_actor *squashfs_page_actor_init(void **buffer,
 44	int pages, int length)
 45{
 46	struct squashfs_page_actor *actor = kmalloc(sizeof(*actor), GFP_KERNEL);
 47
 48	if (actor == NULL)
 49		return NULL;
 50
 51	actor->length = length ? : pages * PAGE_CACHE_SIZE;
 52	actor->buffer = buffer;
 53	actor->pages = pages;
 54	actor->next_page = 0;
 55	actor->squashfs_first_page = cache_first_page;
 56	actor->squashfs_next_page = cache_next_page;
 57	actor->squashfs_finish_page = cache_finish_page;
 58	return actor;
 59}
 60
 61/* Implementation of page_actor for decompressing directly into page cache. */
 62static void *direct_first_page(struct squashfs_page_actor *actor)
 63{
 64	actor->next_page = 1;
 65	return actor->pageaddr = kmap_atomic(actor->page[0]);
 66}
 67
 68static void *direct_next_page(struct squashfs_page_actor *actor)
 69{
 70	if (actor->pageaddr)
 71		kunmap_atomic(actor->pageaddr);
 72
 73	return actor->pageaddr = actor->next_page == actor->pages ? NULL :
 74		kmap_atomic(actor->page[actor->next_page++]);
 75}
 76
 77static void direct_finish_page(struct squashfs_page_actor *actor)
 78{
 79	if (actor->pageaddr)
 80		kunmap_atomic(actor->pageaddr);
 81}
 82
 83struct squashfs_page_actor *squashfs_page_actor_init_special(struct page **page,
 84	int pages, int length)
 85{
 86	struct squashfs_page_actor *actor = kmalloc(sizeof(*actor), GFP_KERNEL);
 87
 88	if (actor == NULL)
 89		return NULL;
 90
 91	actor->length = length ? : pages * PAGE_CACHE_SIZE;
 92	actor->page = page;
 93	actor->pages = pages;
 94	actor->next_page = 0;
 95	actor->pageaddr = NULL;
 96	actor->squashfs_first_page = direct_first_page;
 97	actor->squashfs_next_page = direct_next_page;
 98	actor->squashfs_finish_page = direct_finish_page;
 99	return actor;
100}