]>
Commit | Line | Data |
---|---|---|
85aec44f DW |
1 | /* |
2 | * Copyright (C) 2016 Oracle. All Rights Reserved. | |
3 | * | |
4 | * Author: Darrick J. Wong <darrick.wong@oracle.com> | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public License | |
8 | * as published by the Free Software Foundation; either version 2 | |
9 | * of the License, or (at your option) any later version. | |
10 | * | |
11 | * This program is distributed in the hope that it would be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | * GNU General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU General Public License | |
17 | * along with this program; if not, write the Free Software Foundation, | |
18 | * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. | |
19 | */ | |
20 | #ifndef __XFS_RMAP_H__ | |
21 | #define __XFS_RMAP_H__ | |
22 | ||
23 | static inline void | |
24 | xfs_rmap_ag_owner( | |
25 | struct xfs_owner_info *oi, | |
26 | uint64_t owner) | |
27 | { | |
28 | oi->oi_owner = owner; | |
29 | oi->oi_offset = 0; | |
30 | oi->oi_flags = 0; | |
31 | } | |
32 | ||
33 | static inline void | |
34 | xfs_rmap_ino_bmbt_owner( | |
35 | struct xfs_owner_info *oi, | |
36 | xfs_ino_t ino, | |
37 | int whichfork) | |
38 | { | |
39 | oi->oi_owner = ino; | |
40 | oi->oi_offset = 0; | |
41 | oi->oi_flags = XFS_OWNER_INFO_BMBT_BLOCK; | |
42 | if (whichfork == XFS_ATTR_FORK) | |
43 | oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK; | |
44 | } | |
45 | ||
46 | static inline void | |
47 | xfs_rmap_ino_owner( | |
48 | struct xfs_owner_info *oi, | |
49 | xfs_ino_t ino, | |
50 | int whichfork, | |
51 | xfs_fileoff_t offset) | |
52 | { | |
53 | oi->oi_owner = ino; | |
54 | oi->oi_offset = offset; | |
55 | oi->oi_flags = 0; | |
56 | if (whichfork == XFS_ATTR_FORK) | |
57 | oi->oi_flags |= XFS_OWNER_INFO_ATTR_FORK; | |
58 | } | |
59 | ||
60 | static inline void | |
61 | xfs_rmap_skip_owner_update( | |
62 | struct xfs_owner_info *oi) | |
63 | { | |
3ee858aa DW |
64 | xfs_rmap_ag_owner(oi, XFS_RMAP_OWN_NULL); |
65 | } | |
66 | ||
67 | static inline bool | |
68 | xfs_rmap_should_skip_owner_update( | |
69 | struct xfs_owner_info *oi) | |
70 | { | |
71 | return oi->oi_owner == XFS_RMAP_OWN_NULL; | |
72 | } | |
73 | ||
74 | static inline void | |
75 | xfs_rmap_any_owner_update( | |
76 | struct xfs_owner_info *oi) | |
77 | { | |
78 | xfs_rmap_ag_owner(oi, XFS_RMAP_OWN_UNKNOWN); | |
85aec44f DW |
79 | } |
80 | ||
631ac87a DW |
81 | /* Reverse mapping functions. */ |
82 | ||
83 | struct xfs_buf; | |
84 | ||
b3a96b46 DW |
85 | static inline __u64 |
86 | xfs_rmap_irec_offset_pack( | |
87 | const struct xfs_rmap_irec *irec) | |
88 | { | |
89 | __u64 x; | |
90 | ||
91 | x = XFS_RMAP_OFF(irec->rm_offset); | |
92 | if (irec->rm_flags & XFS_RMAP_ATTR_FORK) | |
93 | x |= XFS_RMAP_OFF_ATTR_FORK; | |
94 | if (irec->rm_flags & XFS_RMAP_BMBT_BLOCK) | |
95 | x |= XFS_RMAP_OFF_BMBT_BLOCK; | |
96 | if (irec->rm_flags & XFS_RMAP_UNWRITTEN) | |
97 | x |= XFS_RMAP_OFF_UNWRITTEN; | |
98 | return x; | |
99 | } | |
100 | ||
101 | static inline int | |
102 | xfs_rmap_irec_offset_unpack( | |
103 | __u64 offset, | |
104 | struct xfs_rmap_irec *irec) | |
105 | { | |
106 | if (offset & ~(XFS_RMAP_OFF_MASK | XFS_RMAP_OFF_FLAGS)) | |
107 | return -EFSCORRUPTED; | |
108 | irec->rm_offset = XFS_RMAP_OFF(offset); | |
109 | if (offset & XFS_RMAP_OFF_ATTR_FORK) | |
110 | irec->rm_flags |= XFS_RMAP_ATTR_FORK; | |
111 | if (offset & XFS_RMAP_OFF_BMBT_BLOCK) | |
112 | irec->rm_flags |= XFS_RMAP_BMBT_BLOCK; | |
113 | if (offset & XFS_RMAP_OFF_UNWRITTEN) | |
114 | irec->rm_flags |= XFS_RMAP_UNWRITTEN; | |
115 | return 0; | |
116 | } | |
117 | ||
118 | static inline void | |
119 | xfs_owner_info_unpack( | |
120 | struct xfs_owner_info *oinfo, | |
121 | uint64_t *owner, | |
122 | uint64_t *offset, | |
123 | unsigned int *flags) | |
124 | { | |
125 | unsigned int r = 0; | |
126 | ||
127 | *owner = oinfo->oi_owner; | |
128 | *offset = oinfo->oi_offset; | |
129 | if (oinfo->oi_flags & XFS_OWNER_INFO_ATTR_FORK) | |
130 | r |= XFS_RMAP_ATTR_FORK; | |
131 | if (oinfo->oi_flags & XFS_OWNER_INFO_BMBT_BLOCK) | |
132 | r |= XFS_RMAP_BMBT_BLOCK; | |
133 | *flags = r; | |
134 | } | |
135 | ||
136 | static inline void | |
137 | xfs_owner_info_pack( | |
138 | struct xfs_owner_info *oinfo, | |
139 | uint64_t owner, | |
140 | uint64_t offset, | |
141 | unsigned int flags) | |
142 | { | |
143 | oinfo->oi_owner = owner; | |
144 | oinfo->oi_offset = XFS_RMAP_OFF(offset); | |
145 | oinfo->oi_flags = 0; | |
146 | if (flags & XFS_RMAP_ATTR_FORK) | |
147 | oinfo->oi_flags |= XFS_OWNER_INFO_ATTR_FORK; | |
148 | if (flags & XFS_RMAP_BMBT_BLOCK) | |
149 | oinfo->oi_flags |= XFS_OWNER_INFO_BMBT_BLOCK; | |
150 | } | |
151 | ||
631ac87a DW |
152 | int xfs_rmap_alloc(struct xfs_trans *tp, struct xfs_buf *agbp, |
153 | xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, | |
154 | struct xfs_owner_info *oinfo); | |
155 | int xfs_rmap_free(struct xfs_trans *tp, struct xfs_buf *agbp, | |
156 | xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, | |
157 | struct xfs_owner_info *oinfo); | |
158 | ||
936ca687 DW |
159 | int xfs_rmap_lookup_le(struct xfs_btree_cur *cur, xfs_agblock_t bno, |
160 | xfs_extlen_t len, uint64_t owner, uint64_t offset, | |
161 | unsigned int flags, int *stat); | |
162 | int xfs_rmap_lookup_eq(struct xfs_btree_cur *cur, xfs_agblock_t bno, | |
163 | xfs_extlen_t len, uint64_t owner, uint64_t offset, | |
164 | unsigned int flags, int *stat); | |
b26675c4 DW |
165 | int xfs_rmap_insert(struct xfs_btree_cur *rcur, xfs_agblock_t agbno, |
166 | xfs_extlen_t len, uint64_t owner, uint64_t offset, | |
167 | unsigned int flags); | |
936ca687 DW |
168 | int xfs_rmap_get_rec(struct xfs_btree_cur *cur, struct xfs_rmap_irec *irec, |
169 | int *stat); | |
170 | ||
890e1174 DW |
171 | typedef int (*xfs_rmap_query_range_fn)( |
172 | struct xfs_btree_cur *cur, | |
173 | struct xfs_rmap_irec *rec, | |
174 | void *priv); | |
175 | ||
176 | int xfs_rmap_query_range(struct xfs_btree_cur *cur, | |
177 | struct xfs_rmap_irec *low_rec, struct xfs_rmap_irec *high_rec, | |
178 | xfs_rmap_query_range_fn fn, void *priv); | |
7e05e856 DW |
179 | int xfs_rmap_query_all(struct xfs_btree_cur *cur, xfs_rmap_query_range_fn fn, |
180 | void *priv); | |
890e1174 | 181 | |
e2d7f10f DW |
182 | enum xfs_rmap_intent_type { |
183 | XFS_RMAP_MAP, | |
184 | XFS_RMAP_MAP_SHARED, | |
185 | XFS_RMAP_UNMAP, | |
186 | XFS_RMAP_UNMAP_SHARED, | |
187 | XFS_RMAP_CONVERT, | |
188 | XFS_RMAP_CONVERT_SHARED, | |
189 | XFS_RMAP_ALLOC, | |
190 | XFS_RMAP_FREE, | |
191 | }; | |
192 | ||
193 | struct xfs_rmap_intent { | |
194 | struct list_head ri_list; | |
195 | enum xfs_rmap_intent_type ri_type; | |
4a492e72 | 196 | uint64_t ri_owner; |
e2d7f10f DW |
197 | int ri_whichfork; |
198 | struct xfs_bmbt_irec ri_bmap; | |
199 | }; | |
200 | ||
d7f80320 DW |
201 | /* functions for updating the rmapbt based on bmbt map/unmap operations */ |
202 | int xfs_rmap_map_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, | |
203 | struct xfs_inode *ip, int whichfork, | |
204 | struct xfs_bmbt_irec *imap); | |
205 | int xfs_rmap_unmap_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, | |
206 | struct xfs_inode *ip, int whichfork, | |
207 | struct xfs_bmbt_irec *imap); | |
208 | int xfs_rmap_convert_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, | |
209 | struct xfs_inode *ip, int whichfork, | |
210 | struct xfs_bmbt_irec *imap); | |
211 | int xfs_rmap_alloc_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, | |
212 | xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, | |
4a492e72 | 213 | uint64_t owner); |
d7f80320 DW |
214 | int xfs_rmap_free_extent(struct xfs_mount *mp, struct xfs_defer_ops *dfops, |
215 | xfs_agnumber_t agno, xfs_agblock_t bno, xfs_extlen_t len, | |
4a492e72 | 216 | uint64_t owner); |
d7f80320 DW |
217 | |
218 | void xfs_rmap_finish_one_cleanup(struct xfs_trans *tp, | |
219 | struct xfs_btree_cur *rcur, int error); | |
220 | int xfs_rmap_finish_one(struct xfs_trans *tp, enum xfs_rmap_intent_type type, | |
4a492e72 | 221 | uint64_t owner, int whichfork, xfs_fileoff_t startoff, |
d7f80320 DW |
222 | xfs_fsblock_t startblock, xfs_filblks_t blockcount, |
223 | xfs_exntst_t state, struct xfs_btree_cur **pcur); | |
224 | ||
6c6bdf6f DW |
225 | int xfs_rmap_find_left_neighbor(struct xfs_btree_cur *cur, xfs_agblock_t bno, |
226 | uint64_t owner, uint64_t offset, unsigned int flags, | |
227 | struct xfs_rmap_irec *irec, int *stat); | |
228 | int xfs_rmap_lookup_le_range(struct xfs_btree_cur *cur, xfs_agblock_t bno, | |
229 | uint64_t owner, uint64_t offset, unsigned int flags, | |
230 | struct xfs_rmap_irec *irec, int *stat); | |
9282c506 DW |
231 | int xfs_rmap_compare(const struct xfs_rmap_irec *a, |
232 | const struct xfs_rmap_irec *b); | |
50bb67d6 DW |
233 | union xfs_btree_rec; |
234 | int xfs_rmap_btrec_to_irec(union xfs_btree_rec *rec, | |
235 | struct xfs_rmap_irec *irec); | |
556c739d DW |
236 | int xfs_rmap_has_record(struct xfs_btree_cur *cur, xfs_agblock_t bno, |
237 | xfs_extlen_t len, bool *exists); | |
238 | int xfs_rmap_record_exists(struct xfs_btree_cur *cur, xfs_agblock_t bno, | |
239 | xfs_extlen_t len, struct xfs_owner_info *oinfo, | |
240 | bool *has_rmap); | |
6c6bdf6f | 241 | |
85aec44f | 242 | #endif /* __XFS_RMAP_H__ */ |