root/fs/squashfs/page_actor.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. cache_first_page
  2. cache_next_page
  3. cache_finish_page
  4. squashfs_page_actor_init
  5. direct_first_page
  6. direct_next_page
  7. direct_finish_page
  8. squashfs_page_actor_init_special

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

/* [<][>][^][v][top][bottom][index][help] */