~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/fs/erofs/zpvec.h

Version: ~ [ linux-6.4-rc3 ] ~ [ linux-6.3.4 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.30 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.113 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.180 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.243 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.283 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.315 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0-only */
  2 /*
  3  * Copyright (C) 2018 HUAWEI, Inc.
  4  *             https://www.huawei.com/
  5  */
  6 #ifndef __EROFS_FS_ZPVEC_H
  7 #define __EROFS_FS_ZPVEC_H
  8 
  9 #include "tagptr.h"
 10 
 11 /* page type in pagevec for decompress subsystem */
 12 enum z_erofs_page_type {
 13         /* including Z_EROFS_VLE_PAGE_TAIL_EXCLUSIVE */
 14         Z_EROFS_PAGE_TYPE_EXCLUSIVE,
 15 
 16         Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED,
 17 
 18         Z_EROFS_VLE_PAGE_TYPE_HEAD,
 19         Z_EROFS_VLE_PAGE_TYPE_MAX
 20 };
 21 
 22 extern void __compiletime_error("Z_EROFS_PAGE_TYPE_EXCLUSIVE != 0")
 23         __bad_page_type_exclusive(void);
 24 
 25 /* pagevec tagged pointer */
 26 typedef tagptr2_t       erofs_vtptr_t;
 27 
 28 /* pagevec collector */
 29 struct z_erofs_pagevec_ctor {
 30         struct page *curr, *next;
 31         erofs_vtptr_t *pages;
 32 
 33         unsigned int nr, index;
 34 };
 35 
 36 static inline void z_erofs_pagevec_ctor_exit(struct z_erofs_pagevec_ctor *ctor,
 37                                              bool atomic)
 38 {
 39         if (!ctor->curr)
 40                 return;
 41 
 42         if (atomic)
 43                 kunmap_atomic(ctor->pages);
 44         else
 45                 kunmap(ctor->curr);
 46 }
 47 
 48 static inline struct page *
 49 z_erofs_pagevec_ctor_next_page(struct z_erofs_pagevec_ctor *ctor,
 50                                unsigned int nr)
 51 {
 52         unsigned int index;
 53 
 54         /* keep away from occupied pages */
 55         if (ctor->next)
 56                 return ctor->next;
 57 
 58         for (index = 0; index < nr; ++index) {
 59                 const erofs_vtptr_t t = ctor->pages[index];
 60                 const unsigned int tags = tagptr_unfold_tags(t);
 61 
 62                 if (tags == Z_EROFS_PAGE_TYPE_EXCLUSIVE)
 63                         return tagptr_unfold_ptr(t);
 64         }
 65         DBG_BUGON(nr >= ctor->nr);
 66         return NULL;
 67 }
 68 
 69 static inline void
 70 z_erofs_pagevec_ctor_pagedown(struct z_erofs_pagevec_ctor *ctor,
 71                               bool atomic)
 72 {
 73         struct page *next = z_erofs_pagevec_ctor_next_page(ctor, ctor->nr);
 74 
 75         z_erofs_pagevec_ctor_exit(ctor, atomic);
 76 
 77         ctor->curr = next;
 78         ctor->next = NULL;
 79         ctor->pages = atomic ?
 80                 kmap_atomic(ctor->curr) : kmap(ctor->curr);
 81 
 82         ctor->nr = PAGE_SIZE / sizeof(struct page *);
 83         ctor->index = 0;
 84 }
 85 
 86 static inline void z_erofs_pagevec_ctor_init(struct z_erofs_pagevec_ctor *ctor,
 87                                              unsigned int nr,
 88                                              erofs_vtptr_t *pages,
 89                                              unsigned int i)
 90 {
 91         ctor->nr = nr;
 92         ctor->curr = ctor->next = NULL;
 93         ctor->pages = pages;
 94 
 95         if (i >= nr) {
 96                 i -= nr;
 97                 z_erofs_pagevec_ctor_pagedown(ctor, false);
 98                 while (i > ctor->nr) {
 99                         i -= ctor->nr;
100                         z_erofs_pagevec_ctor_pagedown(ctor, false);
101                 }
102         }
103         ctor->next = z_erofs_pagevec_ctor_next_page(ctor, i);
104         ctor->index = i;
105 }
106 
107 static inline bool z_erofs_pagevec_enqueue(struct z_erofs_pagevec_ctor *ctor,
108                                            struct page *page,
109                                            enum z_erofs_page_type type,
110                                            bool pvec_safereuse)
111 {
112         if (!ctor->next) {
113                 /* some pages cannot be reused as pvec safely without I/O */
114                 if (type == Z_EROFS_PAGE_TYPE_EXCLUSIVE && !pvec_safereuse)
115                         type = Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED;
116 
117                 if (type != Z_EROFS_PAGE_TYPE_EXCLUSIVE &&
118                     ctor->index + 1 == ctor->nr)
119                         return false;
120         }
121 
122         if (ctor->index >= ctor->nr)
123                 z_erofs_pagevec_ctor_pagedown(ctor, false);
124 
125         /* exclusive page type must be 0 */
126         if (Z_EROFS_PAGE_TYPE_EXCLUSIVE != (uintptr_t)NULL)
127                 __bad_page_type_exclusive();
128 
129         /* should remind that collector->next never equal to 1, 2 */
130         if (type == (uintptr_t)ctor->next) {
131                 ctor->next = page;
132         }
133         ctor->pages[ctor->index++] = tagptr_fold(erofs_vtptr_t, page, type);
134         return true;
135 }
136 
137 static inline struct page *
138 z_erofs_pagevec_dequeue(struct z_erofs_pagevec_ctor *ctor,
139                         enum z_erofs_page_type *type)
140 {
141         erofs_vtptr_t t;
142 
143         if (ctor->index >= ctor->nr) {
144                 DBG_BUGON(!ctor->next);
145                 z_erofs_pagevec_ctor_pagedown(ctor, true);
146         }
147 
148         t = ctor->pages[ctor->index];
149 
150         *type = tagptr_unfold_tags(t);
151 
152         /* should remind that collector->next never equal to 1, 2 */
153         if (*type == (uintptr_t)ctor->next)
154                 ctor->next = tagptr_unfold_ptr(t);
155 
156         ctor->pages[ctor->index++] = tagptr_fold(erofs_vtptr_t, NULL, 0);
157         return tagptr_unfold_ptr(t);
158 }
159 #endif
160 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp