diff options
author | Darrick J. Wong <darrick.wong@oracle.com> | 2016-08-02 22:11:01 -0400 |
---|---|---|
committer | Dave Chinner <david@fromorbit.com> | 2016-08-02 22:11:01 -0400 |
commit | f8dbebef98f0b960a0e91d6b8d45c288c377797b (patch) | |
tree | 6c57c1a1836c3824843e11bd762941b3c6dfb74c | |
parent | 9e88b5d86703bb836d33dcd0c70eb59e049c80c7 (diff) |
xfs: enable the xfs_defer mechanism to process rmaps to update
Connect the xfs_defer mechanism with the pieces that we'll need to
handle deferred rmap updates. We'll wire up the existing code to
our new deferred mechanism later.
Signed-off-by: Darrick J. Wong <darrick.wong@oracle.com>
Reviewed-by: Dave Chinner <dchinner@redhat.com>
Signed-off-by: Dave Chinner <david@fromorbit.com>
-rw-r--r-- | fs/xfs/libxfs/xfs_defer.h | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_super.c | 1 | ||||
-rw-r--r-- | fs/xfs/xfs_trans.h | 11 | ||||
-rw-r--r-- | fs/xfs/xfs_trans_rmap.c | 131 |
4 files changed, 134 insertions, 10 deletions
diff --git a/fs/xfs/libxfs/xfs_defer.h b/fs/xfs/libxfs/xfs_defer.h index b9b5a92ffa6c..cc3981c48296 100644 --- a/fs/xfs/libxfs/xfs_defer.h +++ b/fs/xfs/libxfs/xfs_defer.h | |||
@@ -51,6 +51,7 @@ struct xfs_defer_pending { | |||
51 | * find all the space it needs. | 51 | * find all the space it needs. |
52 | */ | 52 | */ |
53 | enum xfs_defer_ops_type { | 53 | enum xfs_defer_ops_type { |
54 | XFS_DEFER_OPS_TYPE_RMAP, | ||
54 | XFS_DEFER_OPS_TYPE_FREE, | 55 | XFS_DEFER_OPS_TYPE_FREE, |
55 | XFS_DEFER_OPS_TYPE_MAX, | 56 | XFS_DEFER_OPS_TYPE_MAX, |
56 | }; | 57 | }; |
diff --git a/fs/xfs/xfs_super.c b/fs/xfs/xfs_super.c index 654a0924b3d3..9f8090951f09 100644 --- a/fs/xfs/xfs_super.c +++ b/fs/xfs/xfs_super.c | |||
@@ -1876,6 +1876,7 @@ init_xfs_fs(void) | |||
1876 | XFS_BUILD_OPTIONS " enabled\n"); | 1876 | XFS_BUILD_OPTIONS " enabled\n"); |
1877 | 1877 | ||
1878 | xfs_extent_free_init_defer_op(); | 1878 | xfs_extent_free_init_defer_op(); |
1879 | xfs_rmap_update_init_defer_op(); | ||
1879 | 1880 | ||
1880 | xfs_dir_startup(); | 1881 | xfs_dir_startup(); |
1881 | 1882 | ||
diff --git a/fs/xfs/xfs_trans.h b/fs/xfs/xfs_trans.h index 02265817f016..07f4550825f6 100644 --- a/fs/xfs/xfs_trans.h +++ b/fs/xfs/xfs_trans.h | |||
@@ -33,6 +33,8 @@ struct xfs_trans; | |||
33 | struct xfs_trans_res; | 33 | struct xfs_trans_res; |
34 | struct xfs_dquot_acct; | 34 | struct xfs_dquot_acct; |
35 | struct xfs_busy_extent; | 35 | struct xfs_busy_extent; |
36 | struct xfs_rud_log_item; | ||
37 | struct xfs_rui_log_item; | ||
36 | 38 | ||
37 | typedef struct xfs_log_item { | 39 | typedef struct xfs_log_item { |
38 | struct list_head li_ail; /* AIL pointers */ | 40 | struct list_head li_ail; /* AIL pointers */ |
@@ -233,15 +235,10 @@ void xfs_trans_buf_copy_type(struct xfs_buf *dst_bp, | |||
233 | extern kmem_zone_t *xfs_trans_zone; | 235 | extern kmem_zone_t *xfs_trans_zone; |
234 | extern kmem_zone_t *xfs_log_item_desc_zone; | 236 | extern kmem_zone_t *xfs_log_item_desc_zone; |
235 | 237 | ||
238 | /* rmap updates */ | ||
236 | enum xfs_rmap_intent_type; | 239 | enum xfs_rmap_intent_type; |
237 | 240 | ||
238 | struct xfs_rui_log_item *xfs_trans_get_rui(struct xfs_trans *tp, uint nextents); | 241 | void xfs_rmap_update_init_defer_op(void); |
239 | void xfs_trans_log_start_rmap_update(struct xfs_trans *tp, | ||
240 | struct xfs_rui_log_item *ruip, enum xfs_rmap_intent_type type, | ||
241 | __uint64_t owner, int whichfork, xfs_fileoff_t startoff, | ||
242 | xfs_fsblock_t startblock, xfs_filblks_t blockcount, | ||
243 | xfs_exntst_t state); | ||
244 | |||
245 | struct xfs_rud_log_item *xfs_trans_get_rud(struct xfs_trans *tp, | 242 | struct xfs_rud_log_item *xfs_trans_get_rud(struct xfs_trans *tp, |
246 | struct xfs_rui_log_item *ruip, uint nextents); | 243 | struct xfs_rui_log_item *ruip, uint nextents); |
247 | int xfs_trans_log_finish_rmap_update(struct xfs_trans *tp, | 244 | int xfs_trans_log_finish_rmap_update(struct xfs_trans *tp, |
diff --git a/fs/xfs/xfs_trans_rmap.c b/fs/xfs/xfs_trans_rmap.c index e3a5172ad0c0..baab99077f77 100644 --- a/fs/xfs/xfs_trans_rmap.c +++ b/fs/xfs/xfs_trans_rmap.c | |||
@@ -37,7 +37,7 @@ | |||
37 | * caller must use all nextents extents, because we are not | 37 | * caller must use all nextents extents, because we are not |
38 | * flexible about this at all. | 38 | * flexible about this at all. |
39 | */ | 39 | */ |
40 | struct xfs_rui_log_item * | 40 | STATIC struct xfs_rui_log_item * |
41 | xfs_trans_get_rui( | 41 | xfs_trans_get_rui( |
42 | struct xfs_trans *tp, | 42 | struct xfs_trans *tp, |
43 | uint nextents) | 43 | uint nextents) |
@@ -96,7 +96,7 @@ xfs_trans_set_rmap_flags( | |||
96 | * mapping is to be logged as needing to be updated. It should be | 96 | * mapping is to be logged as needing to be updated. It should be |
97 | * called once for each mapping. | 97 | * called once for each mapping. |
98 | */ | 98 | */ |
99 | void | 99 | STATIC void |
100 | xfs_trans_log_start_rmap_update( | 100 | xfs_trans_log_start_rmap_update( |
101 | struct xfs_trans *tp, | 101 | struct xfs_trans *tp, |
102 | struct xfs_rui_log_item *ruip, | 102 | struct xfs_rui_log_item *ruip, |
@@ -129,7 +129,6 @@ xfs_trans_log_start_rmap_update( | |||
129 | xfs_trans_set_rmap_flags(rmap, type, whichfork, state); | 129 | xfs_trans_set_rmap_flags(rmap, type, whichfork, state); |
130 | } | 130 | } |
131 | 131 | ||
132 | |||
133 | /* | 132 | /* |
134 | * This routine is called to allocate an "rmap update done" | 133 | * This routine is called to allocate an "rmap update done" |
135 | * log item that will hold nextents worth of extents. The | 134 | * log item that will hold nextents worth of extents. The |
@@ -203,3 +202,129 @@ xfs_trans_log_finish_rmap_update( | |||
203 | 202 | ||
204 | return error; | 203 | return error; |
205 | } | 204 | } |
205 | |||
206 | /* Sort rmap intents by AG. */ | ||
207 | static int | ||
208 | xfs_rmap_update_diff_items( | ||
209 | void *priv, | ||
210 | struct list_head *a, | ||
211 | struct list_head *b) | ||
212 | { | ||
213 | struct xfs_mount *mp = priv; | ||
214 | struct xfs_rmap_intent *ra; | ||
215 | struct xfs_rmap_intent *rb; | ||
216 | |||
217 | ra = container_of(a, struct xfs_rmap_intent, ri_list); | ||
218 | rb = container_of(b, struct xfs_rmap_intent, ri_list); | ||
219 | return XFS_FSB_TO_AGNO(mp, ra->ri_bmap.br_startblock) - | ||
220 | XFS_FSB_TO_AGNO(mp, rb->ri_bmap.br_startblock); | ||
221 | } | ||
222 | |||
223 | /* Get an RUI. */ | ||
224 | STATIC void * | ||
225 | xfs_rmap_update_create_intent( | ||
226 | struct xfs_trans *tp, | ||
227 | unsigned int count) | ||
228 | { | ||
229 | return xfs_trans_get_rui(tp, count); | ||
230 | } | ||
231 | |||
232 | /* Log rmap updates in the intent item. */ | ||
233 | STATIC void | ||
234 | xfs_rmap_update_log_item( | ||
235 | struct xfs_trans *tp, | ||
236 | void *intent, | ||
237 | struct list_head *item) | ||
238 | { | ||
239 | struct xfs_rmap_intent *rmap; | ||
240 | |||
241 | rmap = container_of(item, struct xfs_rmap_intent, ri_list); | ||
242 | xfs_trans_log_start_rmap_update(tp, intent, rmap->ri_type, | ||
243 | rmap->ri_owner, rmap->ri_whichfork, | ||
244 | rmap->ri_bmap.br_startoff, | ||
245 | rmap->ri_bmap.br_startblock, | ||
246 | rmap->ri_bmap.br_blockcount, | ||
247 | rmap->ri_bmap.br_state); | ||
248 | } | ||
249 | |||
250 | /* Get an RUD so we can process all the deferred rmap updates. */ | ||
251 | STATIC void * | ||
252 | xfs_rmap_update_create_done( | ||
253 | struct xfs_trans *tp, | ||
254 | void *intent, | ||
255 | unsigned int count) | ||
256 | { | ||
257 | return xfs_trans_get_rud(tp, intent, count); | ||
258 | } | ||
259 | |||
260 | /* Process a deferred rmap update. */ | ||
261 | STATIC int | ||
262 | xfs_rmap_update_finish_item( | ||
263 | struct xfs_trans *tp, | ||
264 | struct xfs_defer_ops *dop, | ||
265 | struct list_head *item, | ||
266 | void *done_item, | ||
267 | void **state) | ||
268 | { | ||
269 | struct xfs_rmap_intent *rmap; | ||
270 | int error; | ||
271 | |||
272 | rmap = container_of(item, struct xfs_rmap_intent, ri_list); | ||
273 | error = xfs_trans_log_finish_rmap_update(tp, done_item, | ||
274 | rmap->ri_type, | ||
275 | rmap->ri_owner, rmap->ri_whichfork, | ||
276 | rmap->ri_bmap.br_startoff, | ||
277 | rmap->ri_bmap.br_startblock, | ||
278 | rmap->ri_bmap.br_blockcount, | ||
279 | rmap->ri_bmap.br_state); | ||
280 | kmem_free(rmap); | ||
281 | return error; | ||
282 | } | ||
283 | |||
284 | /* Clean up after processing deferred rmaps. */ | ||
285 | STATIC void | ||
286 | xfs_rmap_update_finish_cleanup( | ||
287 | struct xfs_trans *tp, | ||
288 | void *state, | ||
289 | int error) | ||
290 | { | ||
291 | } | ||
292 | |||
293 | /* Abort all pending RUIs. */ | ||
294 | STATIC void | ||
295 | xfs_rmap_update_abort_intent( | ||
296 | void *intent) | ||
297 | { | ||
298 | xfs_rui_release(intent); | ||
299 | } | ||
300 | |||
301 | /* Cancel a deferred rmap update. */ | ||
302 | STATIC void | ||
303 | xfs_rmap_update_cancel_item( | ||
304 | struct list_head *item) | ||
305 | { | ||
306 | struct xfs_rmap_intent *rmap; | ||
307 | |||
308 | rmap = container_of(item, struct xfs_rmap_intent, ri_list); | ||
309 | kmem_free(rmap); | ||
310 | } | ||
311 | |||
312 | static const struct xfs_defer_op_type xfs_rmap_update_defer_type = { | ||
313 | .type = XFS_DEFER_OPS_TYPE_RMAP, | ||
314 | .max_items = XFS_RUI_MAX_FAST_EXTENTS, | ||
315 | .diff_items = xfs_rmap_update_diff_items, | ||
316 | .create_intent = xfs_rmap_update_create_intent, | ||
317 | .abort_intent = xfs_rmap_update_abort_intent, | ||
318 | .log_item = xfs_rmap_update_log_item, | ||
319 | .create_done = xfs_rmap_update_create_done, | ||
320 | .finish_item = xfs_rmap_update_finish_item, | ||
321 | .finish_cleanup = xfs_rmap_update_finish_cleanup, | ||
322 | .cancel_item = xfs_rmap_update_cancel_item, | ||
323 | }; | ||
324 | |||
325 | /* Register the deferred op type. */ | ||
326 | void | ||
327 | xfs_rmap_update_init_defer_op(void) | ||
328 | { | ||
329 | xfs_defer_init_op_type(&xfs_rmap_update_defer_type); | ||
330 | } | ||