aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDarrick J. Wong <darrick.wong@oracle.com>2016-08-02 22:11:01 -0400
committerDave Chinner <david@fromorbit.com>2016-08-02 22:11:01 -0400
commitf8dbebef98f0b960a0e91d6b8d45c288c377797b (patch)
tree6c57c1a1836c3824843e11bd762941b3c6dfb74c
parent9e88b5d86703bb836d33dcd0c70eb59e049c80c7 (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.h1
-rw-r--r--fs/xfs/xfs_super.c1
-rw-r--r--fs/xfs/xfs_trans.h11
-rw-r--r--fs/xfs/xfs_trans_rmap.c131
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 */
53enum xfs_defer_ops_type { 53enum 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;
33struct xfs_trans_res; 33struct xfs_trans_res;
34struct xfs_dquot_acct; 34struct xfs_dquot_acct;
35struct xfs_busy_extent; 35struct xfs_busy_extent;
36struct xfs_rud_log_item;
37struct xfs_rui_log_item;
36 38
37typedef struct xfs_log_item { 39typedef 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,
233extern kmem_zone_t *xfs_trans_zone; 235extern kmem_zone_t *xfs_trans_zone;
234extern kmem_zone_t *xfs_log_item_desc_zone; 236extern kmem_zone_t *xfs_log_item_desc_zone;
235 237
238/* rmap updates */
236enum xfs_rmap_intent_type; 239enum xfs_rmap_intent_type;
237 240
238struct xfs_rui_log_item *xfs_trans_get_rui(struct xfs_trans *tp, uint nextents); 241void xfs_rmap_update_init_defer_op(void);
239void 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
245struct xfs_rud_log_item *xfs_trans_get_rud(struct xfs_trans *tp, 242struct 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);
247int xfs_trans_log_finish_rmap_update(struct xfs_trans *tp, 244int 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 */
40struct xfs_rui_log_item * 40STATIC struct xfs_rui_log_item *
41xfs_trans_get_rui( 41xfs_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 */
99void 99STATIC void
100xfs_trans_log_start_rmap_update( 100xfs_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. */
207static int
208xfs_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. */
224STATIC void *
225xfs_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. */
233STATIC void
234xfs_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. */
251STATIC void *
252xfs_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. */
261STATIC int
262xfs_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. */
285STATIC void
286xfs_rmap_update_finish_cleanup(
287 struct xfs_trans *tp,
288 void *state,
289 int error)
290{
291}
292
293/* Abort all pending RUIs. */
294STATIC void
295xfs_rmap_update_abort_intent(
296 void *intent)
297{
298 xfs_rui_release(intent);
299}
300
301/* Cancel a deferred rmap update. */
302STATIC void
303xfs_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
312static 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. */
326void
327xfs_rmap_update_init_defer_op(void)
328{
329 xfs_defer_init_op_type(&xfs_rmap_update_defer_type);
330}