1 /* SPDX-License-Identifier: GPL-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 /* shared xattrs */
26 #define XATTR 3
27 /* device table */
28 #define DEVT 4
29
30 struct erofs_bhops {
31 bool (*preflush)(struct erofs_buffer_head *bh);
32 bool (*flush)(struct erofs_buffer_head *bh);
33 };
34
35 struct erofs_buffer_head {
36 struct list_head list;
37 struct erofs_buffer_block *block;
38
39 erofs_off_t off;
40 struct erofs_bhops *op;
41
42 void *fsprivate;
43 };
44
45 struct erofs_buffer_block {
46 struct list_head list;
47 struct list_head mapped_list;
48
49 erofs_blk_t blkaddr;
50 int type;
51
52 struct erofs_buffer_head buffers;
53 };
54
get_alignsize(int type,int * type_ret)55 static inline const int get_alignsize(int type, int *type_ret)
56 {
57 if (type == DATA)
58 return EROFS_BLKSIZ;
59
60 if (type == INODE) {
61 *type_ret = META;
62 return sizeof(struct erofs_inode_compact);
63 } else if (type == XATTR) {
64 *type_ret = META;
65 return sizeof(struct erofs_xattr_entry);
66 } else if (type == DEVT) {
67 *type_ret = META;
68 return EROFS_DEVT_SLOT_SIZE;
69 }
70
71 if (type == META)
72 return 1;
73 return -EINVAL;
74 }
75
76 extern struct erofs_bhops erofs_drop_directly_bhops;
77 extern struct erofs_bhops erofs_skip_write_bhops;
78 extern struct erofs_bhops erofs_buf_write_bhops;
79
erofs_btell(struct erofs_buffer_head * bh,bool end)80 static inline erofs_off_t erofs_btell(struct erofs_buffer_head *bh, bool end)
81 {
82 const struct erofs_buffer_block *bb = bh->block;
83
84 if (bb->blkaddr == NULL_ADDR)
85 return NULL_ADDR_UL;
86
87 return blknr_to_addr(bb->blkaddr) +
88 (end ? list_next_entry(bh, list)->off : bh->off);
89 }
90
erofs_bh_flush_generic_end(struct erofs_buffer_head * bh)91 static inline bool erofs_bh_flush_generic_end(struct erofs_buffer_head *bh)
92 {
93 list_del(&bh->list);
94 free(bh);
95 return true;
96 }
97
98 struct erofs_buffer_head *erofs_buffer_init(void);
99 int erofs_bh_balloon(struct erofs_buffer_head *bh, erofs_off_t incr);
100
101 struct erofs_buffer_head *erofs_balloc(int type, erofs_off_t size,
102 unsigned int required_ext,
103 unsigned int inline_ext);
104 struct erofs_buffer_head *erofs_battach(struct erofs_buffer_head *bh,
105 int type, unsigned int size);
106
107 erofs_blk_t erofs_mapbh(struct erofs_buffer_block *bb);
108 bool erofs_bflush(struct erofs_buffer_block *bb);
109
110 void erofs_bdrop(struct erofs_buffer_head *bh, bool tryrevoke);
111
112 #ifdef __cplusplus
113 }
114 #endif
115
116 #endif
117