Blame view

fs/erofs/zpvec.h 3.55 KB
29b24f6ca   Gao Xiang   staging: erofs: u...
1
2
  /* SPDX-License-Identifier: GPL-2.0-only */
  /*
5eb20ec3e   Gao Xiang   staging: erofs: i...
3
4
5
   * Copyright (C) 2018 HUAWEI, Inc.
   *             http://www.huawei.com/
   * Created by Gao Xiang <gaoxiang25@huawei.com>
5eb20ec3e   Gao Xiang   staging: erofs: i...
6
   */
57b78c9fd   Gao Xiang   staging: erofs: r...
7
8
  #ifndef __EROFS_FS_ZPVEC_H
  #define __EROFS_FS_ZPVEC_H
5eb20ec3e   Gao Xiang   staging: erofs: i...
9

57b78c9fd   Gao Xiang   staging: erofs: r...
10
  #include "tagptr.h"
5eb20ec3e   Gao Xiang   staging: erofs: i...
11

046d64e11   Gao Xiang   staging: erofs: t...
12
  /* page type in pagevec for decompress subsystem */
5eb20ec3e   Gao Xiang   staging: erofs: i...
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
  enum z_erofs_page_type {
  	/* including Z_EROFS_VLE_PAGE_TAIL_EXCLUSIVE */
  	Z_EROFS_PAGE_TYPE_EXCLUSIVE,
  
  	Z_EROFS_VLE_PAGE_TYPE_TAIL_SHARED,
  
  	Z_EROFS_VLE_PAGE_TYPE_HEAD,
  	Z_EROFS_VLE_PAGE_TYPE_MAX
  };
  
  extern void __compiletime_error("Z_EROFS_PAGE_TYPE_EXCLUSIVE != 0")
  	__bad_page_type_exclusive(void);
  
  /* pagevec tagged pointer */
  typedef tagptr2_t	erofs_vtptr_t;
  
  /* pagevec collector */
  struct z_erofs_pagevec_ctor {
  	struct page *curr, *next;
  	erofs_vtptr_t *pages;
  
  	unsigned int nr, index;
  };
  
  static inline void z_erofs_pagevec_ctor_exit(struct z_erofs_pagevec_ctor *ctor,
  					     bool atomic)
  {
561fb35a9   Bhanusree Pola   staging: erofs: U...
40
  	if (!ctor->curr)
5eb20ec3e   Gao Xiang   staging: erofs: i...
41
42
43
44
45
46
47
48
49
50
  		return;
  
  	if (atomic)
  		kunmap_atomic(ctor->pages);
  	else
  		kunmap(ctor->curr);
  }
  
  static inline struct page *
  z_erofs_pagevec_ctor_next_page(struct z_erofs_pagevec_ctor *ctor,
e82a9a17d   Pratik Shinde   staging: erofs:co...
51
  			       unsigned int nr)
5eb20ec3e   Gao Xiang   staging: erofs: i...
52
  {
e82a9a17d   Pratik Shinde   staging: erofs:co...
53
  	unsigned int index;
5eb20ec3e   Gao Xiang   staging: erofs: i...
54
55
  
  	/* keep away from occupied pages */
561fb35a9   Bhanusree Pola   staging: erofs: U...
56
  	if (ctor->next)
5eb20ec3e   Gao Xiang   staging: erofs: i...
57
58
59
60
  		return ctor->next;
  
  	for (index = 0; index < nr; ++index) {
  		const erofs_vtptr_t t = ctor->pages[index];
e82a9a17d   Pratik Shinde   staging: erofs:co...
61
  		const unsigned int tags = tagptr_unfold_tags(t);
5eb20ec3e   Gao Xiang   staging: erofs: i...
62
63
64
65
  
  		if (tags == Z_EROFS_PAGE_TYPE_EXCLUSIVE)
  			return tagptr_unfold_ptr(t);
  	}
3fb58b857   Hariprasad Kelam   staging: erofs: f...
66
  	DBG_BUGON(nr >= ctor->nr);
5eb20ec3e   Gao Xiang   staging: erofs: i...
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
  	return NULL;
  }
  
  static inline void
  z_erofs_pagevec_ctor_pagedown(struct z_erofs_pagevec_ctor *ctor,
  			      bool atomic)
  {
  	struct page *next = z_erofs_pagevec_ctor_next_page(ctor, ctor->nr);
  
  	z_erofs_pagevec_ctor_exit(ctor, atomic);
  
  	ctor->curr = next;
  	ctor->next = NULL;
  	ctor->pages = atomic ?
  		kmap_atomic(ctor->curr) : kmap(ctor->curr);
  
  	ctor->nr = PAGE_SIZE / sizeof(struct page *);
  	ctor->index = 0;
  }
  
  static inline void z_erofs_pagevec_ctor_init(struct z_erofs_pagevec_ctor *ctor,
e82a9a17d   Pratik Shinde   staging: erofs:co...
88
89
90
  					     unsigned int nr,
  					     erofs_vtptr_t *pages,
  					     unsigned int i)
5eb20ec3e   Gao Xiang   staging: erofs: i...
91
92
93
94
95
96
97
98
99
100
101
102
103
  {
  	ctor->nr = nr;
  	ctor->curr = ctor->next = NULL;
  	ctor->pages = pages;
  
  	if (i >= nr) {
  		i -= nr;
  		z_erofs_pagevec_ctor_pagedown(ctor, false);
  		while (i > ctor->nr) {
  			i -= ctor->nr;
  			z_erofs_pagevec_ctor_pagedown(ctor, false);
  		}
  	}
5eb20ec3e   Gao Xiang   staging: erofs: i...
104
105
106
  	ctor->next = z_erofs_pagevec_ctor_next_page(ctor, i);
  	ctor->index = i;
  }
046d64e11   Gao Xiang   staging: erofs: t...
107
108
109
110
  static inline bool z_erofs_pagevec_enqueue(struct z_erofs_pagevec_ctor *ctor,
  					   struct page *page,
  					   enum z_erofs_page_type type,
  					   bool *occupied)
5eb20ec3e   Gao Xiang   staging: erofs: i...
111
112
  {
  	*occupied = false;
8d8a09b09   Gao Xiang   erofs: remove all...
113
  	if (!ctor->next && type)
5eb20ec3e   Gao Xiang   staging: erofs: i...
114
115
  		if (ctor->index + 1 == ctor->nr)
  			return false;
8d8a09b09   Gao Xiang   erofs: remove all...
116
  	if (ctor->index >= ctor->nr)
5eb20ec3e   Gao Xiang   staging: erofs: i...
117
118
119
120
121
122
123
124
125
126
127
  		z_erofs_pagevec_ctor_pagedown(ctor, false);
  
  	/* exclusive page type must be 0 */
  	if (Z_EROFS_PAGE_TYPE_EXCLUSIVE != (uintptr_t)NULL)
  		__bad_page_type_exclusive();
  
  	/* should remind that collector->next never equal to 1, 2 */
  	if (type == (uintptr_t)ctor->next) {
  		ctor->next = page;
  		*occupied = true;
  	}
046d64e11   Gao Xiang   staging: erofs: t...
128
  	ctor->pages[ctor->index++] = tagptr_fold(erofs_vtptr_t, page, type);
5eb20ec3e   Gao Xiang   staging: erofs: i...
129
130
131
132
  	return true;
  }
  
  static inline struct page *
046d64e11   Gao Xiang   staging: erofs: t...
133
134
  z_erofs_pagevec_dequeue(struct z_erofs_pagevec_ctor *ctor,
  			enum z_erofs_page_type *type)
5eb20ec3e   Gao Xiang   staging: erofs: i...
135
136
  {
  	erofs_vtptr_t t;
8d8a09b09   Gao Xiang   erofs: remove all...
137
  	if (ctor->index >= ctor->nr) {
70b17991d   Gao Xiang   staging: erofs: u...
138
  		DBG_BUGON(!ctor->next);
5eb20ec3e   Gao Xiang   staging: erofs: i...
139
140
141
142
143
144
145
146
147
148
  		z_erofs_pagevec_ctor_pagedown(ctor, true);
  	}
  
  	t = ctor->pages[ctor->index];
  
  	*type = tagptr_unfold_tags(t);
  
  	/* should remind that collector->next never equal to 1, 2 */
  	if (*type == (uintptr_t)ctor->next)
  		ctor->next = tagptr_unfold_ptr(t);
046d64e11   Gao Xiang   staging: erofs: t...
149
  	ctor->pages[ctor->index++] = tagptr_fold(erofs_vtptr_t, NULL, 0);
5eb20ec3e   Gao Xiang   staging: erofs: i...
150
151
  	return tagptr_unfold_ptr(t);
  }
5eb20ec3e   Gao Xiang   staging: erofs: i...
152
  #endif