xref: /aosp_15_r20/external/erofs-utils/include/erofs/cache.h (revision 33b1fccf6a0fada2c2875d400ed01119b7676ee5)
1 /* SPDX-License-Identifier: GPL-2.0+ OR Apache-2.0 */
2 /*
3  * Copyright (C) 2018 HUAWEI, Inc.
4  *             http://www.huawei.com/
5  * Created by Miao Xie <[email protected]>
6  * with heavy changes by Gao Xiang <[email protected]>
7  */
8 #ifndef __EROFS_CACHE_H
9 #define __EROFS_CACHE_H
10 
11 #ifdef __cplusplus
12 extern "C"
13 {
14 #endif
15 
16 #include "internal.h"
17 
18 struct erofs_buffer_head;
19 struct erofs_buffer_block;
20 
21 #define DATA		0
22 #define META		1
23 /* including inline xattrs, extent */
24 #define INODE		2
25 /* directory data */
26 #define DIRA		3
27 /* shared xattrs */
28 #define XATTR		4
29 /* device table */
30 #define DEVT		5
31 
32 struct erofs_bhops {
33 	int (*flush)(struct erofs_buffer_head *bh);
34 };
35 
36 struct erofs_buffer_head {
37 	struct list_head list;
38 	struct erofs_buffer_block *block;
39 
40 	erofs_off_t off;
41 	const struct erofs_bhops *op;
42 
43 	void *fsprivate;
44 };
45 
46 struct erofs_buffer_block {
47 	struct list_head list;
48 	struct list_head mapped_list;
49 
50 	erofs_blk_t blkaddr;
51 	int type;
52 
53 	struct erofs_buffer_head buffers;
54 };
55 
56 struct erofs_bufmgr {
57 	struct erofs_sb_info *sbi;
58 
59 	/* buckets for all mapped buffer blocks to boost up allocation */
60 	struct list_head mapped_buckets[META + 1][EROFS_MAX_BLOCK_SIZE];
61 
62 	struct erofs_buffer_block blkh;
63 	erofs_blk_t tail_blkaddr, metablkcnt;
64 
65 	/* last mapped buffer block to accelerate erofs_mapbh() */
66 	struct erofs_buffer_block *last_mapped_block;
67 };
68 
get_alignsize(struct erofs_sb_info * sbi,int type,int * type_ret)69 static inline const int get_alignsize(struct erofs_sb_info *sbi, int type,
70 				      int *type_ret)
71 {
72 	if (type == DATA)
73 		return erofs_blksiz(sbi);
74 
75 	if (type == INODE) {
76 		*type_ret = META;
77 		return sizeof(struct erofs_inode_compact);
78 	} else if (type == DIRA) {
79 		*type_ret = META;
80 		return erofs_blksiz(sbi);
81 	} else if (type == XATTR) {
82 		*type_ret = META;
83 		return sizeof(struct erofs_xattr_entry);
84 	} else if (type == DEVT) {
85 		*type_ret = META;
86 		return EROFS_DEVT_SLOT_SIZE;
87 	}
88 
89 	if (type == META)
90 		return 1;
91 	return -EINVAL;
92 }
93 
94 extern const struct erofs_bhops erofs_drop_directly_bhops;
95 extern const struct erofs_bhops erofs_skip_write_bhops;
96 
erofs_btell(struct erofs_buffer_head * bh,bool end)97 static inline erofs_off_t erofs_btell(struct erofs_buffer_head *bh, bool end)
98 {
99 	const struct erofs_buffer_block *bb = bh->block;
100 	struct erofs_bufmgr *bmgr =
101 			(struct erofs_bufmgr *)bb->buffers.fsprivate;
102 
103 	if (bb->blkaddr == NULL_ADDR)
104 		return NULL_ADDR_UL;
105 
106 	return erofs_pos(bmgr->sbi, bb->blkaddr) +
107 		(end ? list_next_entry(bh, list)->off : bh->off);
108 }
109 
erofs_bh_flush_generic_end(struct erofs_buffer_head * bh)110 static inline int erofs_bh_flush_generic_end(struct erofs_buffer_head *bh)
111 {
112 	list_del(&bh->list);
113 	free(bh);
114 	return 0;
115 }
116 
117 struct erofs_bufmgr *erofs_buffer_init(struct erofs_sb_info *sbi,
118 				       erofs_blk_t startblk);
119 int erofs_bh_balloon(struct erofs_buffer_head *bh, erofs_off_t incr);
120 
121 struct erofs_buffer_head *erofs_balloc(struct erofs_bufmgr *bmgr,
122 				       int type, erofs_off_t size,
123 				       unsigned int required_ext,
124 				       unsigned int inline_ext);
125 struct erofs_buffer_head *erofs_battach(struct erofs_buffer_head *bh,
126 					int type, unsigned int size);
127 
128 erofs_blk_t erofs_mapbh(struct erofs_bufmgr *bmgr,
129 			struct erofs_buffer_block *bb);
130 int erofs_bflush(struct erofs_bufmgr *bmgr,
131 		 struct erofs_buffer_block *bb);
132 
133 void erofs_bdrop(struct erofs_buffer_head *bh, bool tryrevoke);
134 erofs_blk_t erofs_total_metablocks(struct erofs_bufmgr *bmgr);
135 void erofs_buffer_exit(struct erofs_bufmgr *bmgr);
136 
137 #ifdef __cplusplus
138 }
139 #endif
140 
141 #endif
142