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 <miaoxie@huawei.com>
6 * with heavy changes by Gao Xiang <gaoxiang25@huawei.com>
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 bool (*preflush)(struct erofs_buffer_head *bh);
34 bool (*flush)(struct erofs_buffer_head *bh);
35 };
36
37 struct erofs_buffer_head {
38 struct list_head list;
39 struct erofs_buffer_block *block;
40
41 erofs_off_t off;
42 const struct erofs_bhops *op;
43
44 void *fsprivate;
45 };
46
47 struct erofs_buffer_block {
48 struct list_head list;
49 struct list_head mapped_list;
50
51 erofs_blk_t blkaddr;
52 int type;
53
54 struct erofs_buffer_head buffers;
55 };
56
get_alignsize(int type,int * type_ret)57 static inline const int get_alignsize(int type, int *type_ret)
58 {
59 if (type == DATA)
60 return erofs_blksiz(&sbi);
61
62 if (type == INODE) {
63 *type_ret = META;
64 return sizeof(struct erofs_inode_compact);
65 } else if (type == DIRA) {
66 *type_ret = META;
67 return erofs_blksiz(&sbi);
68 } else if (type == XATTR) {
69 *type_ret = META;
70 return sizeof(struct erofs_xattr_entry);
71 } else if (type == DEVT) {
72 *type_ret = META;
73 return EROFS_DEVT_SLOT_SIZE;
74 }
75
76 if (type == META)
77 return 1;
78 return -EINVAL;
79 }
80
81 extern const struct erofs_bhops erofs_drop_directly_bhops;
82 extern const struct erofs_bhops erofs_skip_write_bhops;
83
erofs_btell(struct erofs_buffer_head * bh,bool end)84 static inline erofs_off_t erofs_btell(struct erofs_buffer_head *bh, bool end)
85 {
86 const struct erofs_buffer_block *bb = bh->block;
87
88 if (bb->blkaddr == NULL_ADDR)
89 return NULL_ADDR_UL;
90
91 return erofs_pos(&sbi, bb->blkaddr) +
92 (end ? list_next_entry(bh, list)->off : bh->off);
93 }
94
erofs_bh_flush_generic_end(struct erofs_buffer_head * bh)95 static inline bool erofs_bh_flush_generic_end(struct erofs_buffer_head *bh)
96 {
97 list_del(&bh->list);
98 free(bh);
99 return true;
100 }
101
102 struct erofs_buffer_head *erofs_buffer_init(void);
103 int erofs_bh_balloon(struct erofs_buffer_head *bh, erofs_off_t incr);
104
105 struct erofs_buffer_head *erofs_balloc(int type, erofs_off_t size,
106 unsigned int required_ext,
107 unsigned int inline_ext);
108 struct erofs_buffer_head *erofs_battach(struct erofs_buffer_head *bh,
109 int type, unsigned int size);
110
111 erofs_blk_t erofs_mapbh(struct erofs_buffer_block *bb);
112 bool erofs_bflush(struct erofs_buffer_block *bb);
113
114 void erofs_bdrop(struct erofs_buffer_head *bh, bool tryrevoke);
115 erofs_blk_t erofs_total_metablocks(void);
116
117 #ifdef __cplusplus
118 }
119 #endif
120
121 #endif
122