1 ext4: adjust reserved cluster count when removing extents
3 From: Eric Whitney <enwlinux@gmail.com>
5 Modify ext4_ext_remove_space() and the code it calls to correct the
6 reserved cluster count for pending reservations (delayed allocated
7 clusters shared with allocated blocks) when a block range is removed
8 from the extent tree. Pending reservations may be found for the clusters
9 at the ends of written or unwritten extents when a block range is removed.
10 If a physical cluster at the end of an extent is freed, it's necessary
11 to increment the reserved cluster count to maintain correct accounting
12 if the corresponding logical cluster is shared with at least one
13 delayed and unwritten extent as found in the extents status tree.
15 Add a new function, ext4_rereserve_cluster(), to reapply a reservation
16 on a delayed allocated cluster sharing blocks with a freed allocated
17 cluster. To avoid ENOSPC on reservation, a flag is applied to
18 ext4_free_blocks() to briefly defer updating the freeclusters counter
19 when an allocated cluster is freed. This prevents another thread
20 from allocating the freed block before the reservation can be reapplied.
22 Redefine the partial cluster object as a struct to carry more state
23 information and to clarify the code using it.
25 Adjust the conditional code structure in ext4_ext_remove_space to
26 reduce the indentation level in the main body of the code to improve
29 Signed-off-by: Eric Whitney <enwlinux@gmail.com>
30 Signed-off-by: Theodore Ts'o <tytso@mit.edu>
33 fs/ext4/ext4_extents.h | 13 ++
34 fs/ext4/extents.c | 284 +++++++++++++++++++++++++++-----------------
35 fs/ext4/mballoc.c | 14 ++-
36 include/trace/events/ext4.h | 60 ++++++----
37 5 files changed, 238 insertions(+), 134 deletions(-)
39 diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h
40 index d85fd5c8a2c4..0bdbbd151d2c 100644
43 @@ -628,6 +628,7 @@ enum {
44 #define EXT4_FREE_BLOCKS_NO_QUOT_UPDATE 0x0008
45 #define EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER 0x0010
46 #define EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER 0x0020
47 +#define EXT4_FREE_BLOCKS_RERESERVE_CLUSTER 0x0040
51 diff --git a/fs/ext4/ext4_extents.h b/fs/ext4/ext4_extents.h
52 index adf6668b596f..98bd0e9ee7df 100644
53 --- a/fs/ext4/ext4_extents.h
54 +++ b/fs/ext4/ext4_extents.h
55 @@ -120,6 +120,19 @@ struct ext4_ext_path {
59 + * Used to record a portion of a cluster found at the beginning or end
60 + * of an extent while traversing the extent tree during space removal.
61 + * A partial cluster may be removed if it does not contain blocks shared
62 + * with extents that aren't being deleted (tofree state). Otherwise,
63 + * it cannot be removed (nofree state).
65 +struct partial_cluster {
66 + ext4_fsblk_t pclu; /* physical cluster number */
67 + ext4_lblk_t lblk; /* logical block number within logical cluster */
68 + enum {initial, tofree, nofree} state;
72 * structure for external API
75 diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c
76 index b52ac813ca20..240b6dea5441 100644
77 --- a/fs/ext4/extents.c
78 +++ b/fs/ext4/extents.c
79 @@ -2490,106 +2490,157 @@ static inline int get_default_free_blocks_flags(struct inode *inode)
84 + * ext4_rereserve_cluster - increment the reserved cluster count when
85 + * freeing a cluster with a pending reservation
87 + * @inode - file containing the cluster
88 + * @lblk - logical block in cluster to be reserved
90 + * Increments the reserved cluster count and adjusts quota in a bigalloc
91 + * file system when freeing a partial cluster containing at least one
92 + * delayed and unwritten block. A partial cluster meeting that
93 + * requirement will have a pending reservation. If so, the
94 + * RERESERVE_CLUSTER flag is used when calling ext4_free_blocks() to
95 + * defer reserved and allocated space accounting to a subsequent call
98 +static void ext4_rereserve_cluster(struct inode *inode, ext4_lblk_t lblk)
100 + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
101 + struct ext4_inode_info *ei = EXT4_I(inode);
103 + dquot_reclaim_block(inode, EXT4_C2B(sbi, 1));
105 + spin_lock(&ei->i_block_reservation_lock);
106 + ei->i_reserved_data_blocks++;
107 + percpu_counter_add(&sbi->s_dirtyclusters_counter, 1);
108 + spin_unlock(&ei->i_block_reservation_lock);
110 + percpu_counter_add(&sbi->s_freeclusters_counter, 1);
111 + ext4_remove_pending(inode, lblk);
114 static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
115 struct ext4_extent *ex,
116 - long long *partial_cluster,
117 + struct partial_cluster *partial,
118 ext4_lblk_t from, ext4_lblk_t to)
120 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
121 unsigned short ee_len = ext4_ext_get_actual_len(ex);
123 - int flags = get_default_free_blocks_flags(inode);
124 + ext4_fsblk_t last_pblk, pblk;
128 + /* only extent tail removal is allowed */
129 + if (from < le32_to_cpu(ex->ee_block) ||
130 + to != le32_to_cpu(ex->ee_block) + ee_len - 1) {
131 + ext4_error(sbi->s_sb,
132 + "strange request: removal(2) %u-%u from %u:%u",
133 + from, to, le32_to_cpu(ex->ee_block), ee_len);
137 +#ifdef EXTENTS_STATS
138 + spin_lock(&sbi->s_ext_stats_lock);
139 + sbi->s_ext_blocks += ee_len;
140 + sbi->s_ext_extents++;
141 + if (ee_len < sbi->s_ext_min)
142 + sbi->s_ext_min = ee_len;
143 + if (ee_len > sbi->s_ext_max)
144 + sbi->s_ext_max = ee_len;
145 + if (ext_depth(inode) > sbi->s_depth_max)
146 + sbi->s_depth_max = ext_depth(inode);
147 + spin_unlock(&sbi->s_ext_stats_lock);
150 + trace_ext4_remove_blocks(inode, ex, from, to, partial);
153 - * For bigalloc file systems, we never free a partial cluster
154 - * at the beginning of the extent. Instead, we make a note
155 - * that we tried freeing the cluster, and check to see if we
156 - * need to free it on a subsequent call to ext4_remove_blocks,
157 - * or at the end of ext4_ext_rm_leaf or ext4_ext_remove_space.
158 + * if we have a partial cluster, and it's different from the
159 + * cluster of the last block in the extent, we free it
161 - flags |= EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER;
162 + last_pblk = ext4_ext_pblock(ex) + ee_len - 1;
164 + if (partial->state != initial &&
165 + partial->pclu != EXT4_B2C(sbi, last_pblk)) {
166 + if (partial->state == tofree) {
167 + flags = get_default_free_blocks_flags(inode);
168 + if (ext4_is_pending(inode, partial->lblk))
169 + flags |= EXT4_FREE_BLOCKS_RERESERVE_CLUSTER;
170 + ext4_free_blocks(handle, inode, NULL,
171 + EXT4_C2B(sbi, partial->pclu),
172 + sbi->s_cluster_ratio, flags);
173 + if (flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER)
174 + ext4_rereserve_cluster(inode, partial->lblk);
176 + partial->state = initial;
179 + num = le32_to_cpu(ex->ee_block) + ee_len - from;
180 + pblk = ext4_ext_pblock(ex) + ee_len - num;
182 - trace_ext4_remove_blocks(inode, ex, from, to, *partial_cluster);
184 - * If we have a partial cluster, and it's different from the
185 - * cluster of the last block, we need to explicitly free the
186 - * partial cluster here.
187 + * We free the partial cluster at the end of the extent (if any),
188 + * unless the cluster is used by another extent (partial_cluster
189 + * state is nofree). If a partial cluster exists here, it must be
190 + * shared with the last block in the extent.
192 - pblk = ext4_ext_pblock(ex) + ee_len - 1;
193 - if (*partial_cluster > 0 &&
194 - *partial_cluster != (long long) EXT4_B2C(sbi, pblk)) {
195 + flags = get_default_free_blocks_flags(inode);
197 + /* partial, left end cluster aligned, right end unaligned */
198 + if ((EXT4_LBLK_COFF(sbi, to) != sbi->s_cluster_ratio - 1) &&
199 + (EXT4_LBLK_CMASK(sbi, to) >= from) &&
200 + (partial->state != nofree)) {
201 + if (ext4_is_pending(inode, to))
202 + flags |= EXT4_FREE_BLOCKS_RERESERVE_CLUSTER;
203 ext4_free_blocks(handle, inode, NULL,
204 - EXT4_C2B(sbi, *partial_cluster),
205 + EXT4_PBLK_CMASK(sbi, last_pblk),
206 sbi->s_cluster_ratio, flags);
207 - *partial_cluster = 0;
208 + if (flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER)
209 + ext4_rereserve_cluster(inode, to);
210 + partial->state = initial;
211 + flags = get_default_free_blocks_flags(inode);
214 -#ifdef EXTENTS_STATS
216 - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
217 - spin_lock(&sbi->s_ext_stats_lock);
218 - sbi->s_ext_blocks += ee_len;
219 - sbi->s_ext_extents++;
220 - if (ee_len < sbi->s_ext_min)
221 - sbi->s_ext_min = ee_len;
222 - if (ee_len > sbi->s_ext_max)
223 - sbi->s_ext_max = ee_len;
224 - if (ext_depth(inode) > sbi->s_depth_max)
225 - sbi->s_depth_max = ext_depth(inode);
226 - spin_unlock(&sbi->s_ext_stats_lock);
229 - if (from >= le32_to_cpu(ex->ee_block)
230 - && to == le32_to_cpu(ex->ee_block) + ee_len - 1) {
233 - long long first_cluster;
235 - num = le32_to_cpu(ex->ee_block) + ee_len - from;
236 - pblk = ext4_ext_pblock(ex) + ee_len - num;
238 - * Usually we want to free partial cluster at the end of the
239 - * extent, except for the situation when the cluster is still
240 - * used by any other extent (partial_cluster is negative).
242 - if (*partial_cluster < 0 &&
243 - *partial_cluster == -(long long) EXT4_B2C(sbi, pblk+num-1))
244 - flags |= EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER;
245 + flags |= EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER;
247 - ext_debug("free last %u blocks starting %llu partial %lld\n",
248 - num, pblk, *partial_cluster);
249 - ext4_free_blocks(handle, inode, NULL, pblk, num, flags);
251 - * If the block range to be freed didn't start at the
252 - * beginning of a cluster, and we removed the entire
253 - * extent and the cluster is not used by any other extent,
254 - * save the partial cluster here, since we might need to
255 - * delete if we determine that the truncate or punch hole
256 - * operation has removed all of the blocks in the cluster.
257 - * If that cluster is used by another extent, preserve its
258 - * negative value so it isn't freed later on.
260 - * If the whole extent wasn't freed, we've reached the
261 - * start of the truncated/punched region and have finished
262 - * removing blocks. If there's a partial cluster here it's
263 - * shared with the remainder of the extent and is no longer
264 - * a candidate for removal.
266 - if (EXT4_PBLK_COFF(sbi, pblk) && ee_len == num) {
267 - first_cluster = (long long) EXT4_B2C(sbi, pblk);
268 - if (first_cluster != -*partial_cluster)
269 - *partial_cluster = first_cluster;
271 - *partial_cluster = 0;
273 + * For bigalloc file systems, we never free a partial cluster
274 + * at the beginning of the extent. Instead, we check to see if we
275 + * need to free it on a subsequent call to ext4_remove_blocks,
276 + * or at the end of ext4_ext_rm_leaf or ext4_ext_remove_space.
278 + flags |= EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER;
279 + ext4_free_blocks(handle, inode, NULL, pblk, num, flags);
281 + /* reset the partial cluster if we've freed past it */
282 + if (partial->state != initial && partial->pclu != EXT4_B2C(sbi, pblk))
283 + partial->state = initial;
286 + * If we've freed the entire extent but the beginning is not left
287 + * cluster aligned and is not marked as ineligible for freeing we
288 + * record the partial cluster at the beginning of the extent. It
289 + * wasn't freed by the preceding ext4_free_blocks() call, and we
290 + * need to look farther to the left to determine if it's to be freed
291 + * (not shared with another extent). Else, reset the partial
292 + * cluster - we're either done freeing or the beginning of the
293 + * extent is left cluster aligned.
295 + if (EXT4_LBLK_COFF(sbi, from) && num == ee_len) {
296 + if (partial->state == initial) {
297 + partial->pclu = EXT4_B2C(sbi, pblk);
298 + partial->lblk = from;
299 + partial->state = tofree;
302 - ext4_error(sbi->s_sb, "strange request: removal(2) "
303 - "%u-%u from %u:%u",
304 - from, to, le32_to_cpu(ex->ee_block), ee_len);
306 + partial->state = initial;
314 * ext4_ext_rm_leaf() Removes the extents associated with the
315 * blocks appearing between "start" and "end". Both "start"
316 @@ -2608,7 +2659,7 @@ static int ext4_remove_blocks(handle_t *handle, struct inode *inode,
318 ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
319 struct ext4_ext_path *path,
320 - long long *partial_cluster,
321 + struct partial_cluster *partial,
322 ext4_lblk_t start, ext4_lblk_t end)
324 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
325 @@ -2640,7 +2691,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
326 ex_ee_block = le32_to_cpu(ex->ee_block);
327 ex_ee_len = ext4_ext_get_actual_len(ex);
329 - trace_ext4_ext_rm_leaf(inode, start, ex, *partial_cluster);
330 + trace_ext4_ext_rm_leaf(inode, start, ex, partial);
332 while (ex >= EXT_FIRST_EXTENT(eh) &&
333 ex_ee_block + ex_ee_len > start) {
334 @@ -2671,8 +2722,8 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
336 if (sbi->s_cluster_ratio > 1) {
337 pblk = ext4_ext_pblock(ex);
339 - -(long long) EXT4_B2C(sbi, pblk);
340 + partial->pclu = EXT4_B2C(sbi, pblk);
341 + partial->state = nofree;
344 ex_ee_block = le32_to_cpu(ex->ee_block);
345 @@ -2714,8 +2765,7 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
349 - err = ext4_remove_blocks(handle, inode, ex, partial_cluster,
351 + err = ext4_remove_blocks(handle, inode, ex, partial, a, b);
355 @@ -2769,18 +2819,23 @@ ext4_ext_rm_leaf(handle_t *handle, struct inode *inode,
356 * If there's a partial cluster and at least one extent remains in
357 * the leaf, free the partial cluster if it isn't shared with the
358 * current extent. If it is shared with the current extent
359 - * we zero partial_cluster because we've reached the start of the
360 + * we reset the partial cluster because we've reached the start of the
361 * truncated/punched region and we're done removing blocks.
363 - if (*partial_cluster > 0 && ex >= EXT_FIRST_EXTENT(eh)) {
364 + if (partial->state == tofree && ex >= EXT_FIRST_EXTENT(eh)) {
365 pblk = ext4_ext_pblock(ex) + ex_ee_len - 1;
366 - if (*partial_cluster != (long long) EXT4_B2C(sbi, pblk)) {
367 + if (partial->pclu != EXT4_B2C(sbi, pblk)) {
368 + int flags = get_default_free_blocks_flags(inode);
370 + if (ext4_is_pending(inode, partial->lblk))
371 + flags |= EXT4_FREE_BLOCKS_RERESERVE_CLUSTER;
372 ext4_free_blocks(handle, inode, NULL,
373 - EXT4_C2B(sbi, *partial_cluster),
374 - sbi->s_cluster_ratio,
375 - get_default_free_blocks_flags(inode));
376 + EXT4_C2B(sbi, partial->pclu),
377 + sbi->s_cluster_ratio, flags);
378 + if (flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER)
379 + ext4_rereserve_cluster(inode, partial->lblk);
381 - *partial_cluster = 0;
382 + partial->state = initial;
385 /* if this leaf is free, then we should
386 @@ -2819,10 +2874,14 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
387 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb);
388 int depth = ext_depth(inode);
389 struct ext4_ext_path *path = NULL;
390 - long long partial_cluster = 0;
391 + struct partial_cluster partial;
397 + partial.state = initial;
399 ext_debug("truncate since %u to %u\n", start, end);
401 /* probably first extent we're gonna free will be last in block */
402 @@ -2882,8 +2941,8 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
404 if (sbi->s_cluster_ratio > 1) {
405 pblk = ext4_ext_pblock(ex) + end - ee_block + 2;
407 - -(long long) EXT4_B2C(sbi, pblk);
408 + partial.pclu = EXT4_B2C(sbi, pblk);
409 + partial.state = nofree;
413 @@ -2911,9 +2970,10 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
419 - -(long long) EXT4_B2C(sbi, pblk);
421 + partial.pclu = EXT4_B2C(sbi, pblk);
422 + partial.state = nofree;
427 @@ -2948,8 +3008,7 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
429 /* this is leaf block */
430 err = ext4_ext_rm_leaf(handle, inode, path,
431 - &partial_cluster, start,
433 + &partial, start, end);
434 /* root level has p_bh == NULL, brelse() eats this */
435 brelse(path[i].p_bh);
437 @@ -3021,21 +3080,24 @@ int ext4_ext_remove_space(struct inode *inode, ext4_lblk_t start,
441 - trace_ext4_ext_remove_space_done(inode, start, end, depth,
442 - partial_cluster, path->p_hdr->eh_entries);
443 + trace_ext4_ext_remove_space_done(inode, start, end, depth, &partial,
444 + path->p_hdr->eh_entries);
447 - * If we still have something in the partial cluster and we have removed
448 - * even the first extent, then we should free the blocks in the partial
449 - * cluster as well. (This code will only run when there are no leaves
450 - * to the immediate left of the truncated/punched region.)
451 + * if there's a partial cluster and we have removed the first extent
452 + * in the file, then we also free the partial cluster, if any
454 - if (partial_cluster > 0 && err == 0) {
455 - /* don't zero partial_cluster since it's not used afterwards */
456 + if (partial.state == tofree && err == 0) {
457 + int flags = get_default_free_blocks_flags(inode);
459 + if (ext4_is_pending(inode, partial.lblk))
460 + flags |= EXT4_FREE_BLOCKS_RERESERVE_CLUSTER;
461 ext4_free_blocks(handle, inode, NULL,
462 - EXT4_C2B(sbi, partial_cluster),
463 - sbi->s_cluster_ratio,
464 - get_default_free_blocks_flags(inode));
465 + EXT4_C2B(sbi, partial.pclu),
466 + sbi->s_cluster_ratio, flags);
467 + if (flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER)
468 + ext4_rereserve_cluster(inode, partial.lblk);
469 + partial.state = initial;
472 /* TODO: flexible tree reduction should be here */
473 diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c
474 index e29fce2fbf25..e2248083cdca 100644
475 --- a/fs/ext4/mballoc.c
476 +++ b/fs/ext4/mballoc.c
477 @@ -4915,9 +4915,17 @@ void ext4_free_blocks(handle_t *handle, struct inode *inode,
478 &sbi->s_flex_groups[flex_group].free_clusters);
481 - if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
482 - dquot_free_block(inode, EXT4_C2B(sbi, count_clusters));
483 - percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters);
485 + * on a bigalloc file system, defer the s_freeclusters_counter
486 + * update to the caller (ext4_remove_space and friends) so they
487 + * can determine if a cluster freed here should be rereserved
489 + if (!(flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER)) {
490 + if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE))
491 + dquot_free_block(inode, EXT4_C2B(sbi, count_clusters));
492 + percpu_counter_add(&sbi->s_freeclusters_counter,
496 ext4_mb_unload_buddy(&e4b);
498 diff --git a/include/trace/events/ext4.h b/include/trace/events/ext4.h
499 index 6d7a943f849c..698e0d8a5ca4 100644
500 --- a/include/trace/events/ext4.h
501 +++ b/include/trace/events/ext4.h
502 @@ -17,6 +17,7 @@ struct mpage_da_data;
503 struct ext4_map_blocks;
504 struct extent_status;
506 +struct partial_cluster;
508 #define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode))
510 @@ -2035,21 +2036,23 @@ TRACE_EVENT(ext4_ext_show_extent,
513 TRACE_EVENT(ext4_remove_blocks,
514 - TP_PROTO(struct inode *inode, struct ext4_extent *ex,
515 - ext4_lblk_t from, ext4_fsblk_t to,
516 - long long partial_cluster),
517 + TP_PROTO(struct inode *inode, struct ext4_extent *ex,
518 + ext4_lblk_t from, ext4_fsblk_t to,
519 + struct partial_cluster *pc),
521 - TP_ARGS(inode, ex, from, to, partial_cluster),
522 + TP_ARGS(inode, ex, from, to, pc),
525 __field( dev_t, dev )
526 __field( ino_t, ino )
527 __field( ext4_lblk_t, from )
528 __field( ext4_lblk_t, to )
529 - __field( long long, partial )
530 __field( ext4_fsblk_t, ee_pblk )
531 __field( ext4_lblk_t, ee_lblk )
532 __field( unsigned short, ee_len )
533 + __field( ext4_fsblk_t, pc_pclu )
534 + __field( ext4_lblk_t, pc_lblk )
535 + __field( int, pc_state)
539 @@ -2057,14 +2060,16 @@ TRACE_EVENT(ext4_remove_blocks,
540 __entry->ino = inode->i_ino;
541 __entry->from = from;
543 - __entry->partial = partial_cluster;
544 __entry->ee_pblk = ext4_ext_pblock(ex);
545 __entry->ee_lblk = le32_to_cpu(ex->ee_block);
546 __entry->ee_len = ext4_ext_get_actual_len(ex);
547 + __entry->pc_pclu = pc->pclu;
548 + __entry->pc_lblk = pc->lblk;
549 + __entry->pc_state = pc->state;
552 TP_printk("dev %d,%d ino %lu extent [%u(%llu), %u]"
553 - "from %u to %u partial_cluster %lld",
554 + "from %u to %u partial [pclu %lld lblk %u state %d]",
555 MAJOR(__entry->dev), MINOR(__entry->dev),
556 (unsigned long) __entry->ino,
557 (unsigned) __entry->ee_lblk,
558 @@ -2072,45 +2077,53 @@ TRACE_EVENT(ext4_remove_blocks,
559 (unsigned short) __entry->ee_len,
560 (unsigned) __entry->from,
561 (unsigned) __entry->to,
562 - (long long) __entry->partial)
563 + (long long) __entry->pc_pclu,
564 + (unsigned int) __entry->pc_lblk,
565 + (int) __entry->pc_state)
568 TRACE_EVENT(ext4_ext_rm_leaf,
569 TP_PROTO(struct inode *inode, ext4_lblk_t start,
570 struct ext4_extent *ex,
571 - long long partial_cluster),
572 + struct partial_cluster *pc),
574 - TP_ARGS(inode, start, ex, partial_cluster),
575 + TP_ARGS(inode, start, ex, pc),
578 __field( dev_t, dev )
579 __field( ino_t, ino )
580 - __field( long long, partial )
581 __field( ext4_lblk_t, start )
582 __field( ext4_lblk_t, ee_lblk )
583 __field( ext4_fsblk_t, ee_pblk )
584 __field( short, ee_len )
585 + __field( ext4_fsblk_t, pc_pclu )
586 + __field( ext4_lblk_t, pc_lblk )
587 + __field( int, pc_state)
591 __entry->dev = inode->i_sb->s_dev;
592 __entry->ino = inode->i_ino;
593 - __entry->partial = partial_cluster;
594 __entry->start = start;
595 __entry->ee_lblk = le32_to_cpu(ex->ee_block);
596 __entry->ee_pblk = ext4_ext_pblock(ex);
597 __entry->ee_len = ext4_ext_get_actual_len(ex);
598 + __entry->pc_pclu = pc->pclu;
599 + __entry->pc_lblk = pc->lblk;
600 + __entry->pc_state = pc->state;
603 TP_printk("dev %d,%d ino %lu start_lblk %u last_extent [%u(%llu), %u]"
604 - "partial_cluster %lld",
605 + "partial [pclu %lld lblk %u state %d]",
606 MAJOR(__entry->dev), MINOR(__entry->dev),
607 (unsigned long) __entry->ino,
608 (unsigned) __entry->start,
609 (unsigned) __entry->ee_lblk,
610 (unsigned long long) __entry->ee_pblk,
611 (unsigned short) __entry->ee_len,
612 - (long long) __entry->partial)
613 + (long long) __entry->pc_pclu,
614 + (unsigned int) __entry->pc_lblk,
615 + (int) __entry->pc_state)
618 TRACE_EVENT(ext4_ext_rm_idx,
619 @@ -2168,9 +2181,9 @@ TRACE_EVENT(ext4_ext_remove_space,
621 TRACE_EVENT(ext4_ext_remove_space_done,
622 TP_PROTO(struct inode *inode, ext4_lblk_t start, ext4_lblk_t end,
623 - int depth, long long partial, __le16 eh_entries),
624 + int depth, struct partial_cluster *pc, __le16 eh_entries),
626 - TP_ARGS(inode, start, end, depth, partial, eh_entries),
627 + TP_ARGS(inode, start, end, depth, pc, eh_entries),
630 __field( dev_t, dev )
631 @@ -2178,7 +2191,9 @@ TRACE_EVENT(ext4_ext_remove_space_done,
632 __field( ext4_lblk_t, start )
633 __field( ext4_lblk_t, end )
634 __field( int, depth )
635 - __field( long long, partial )
636 + __field( ext4_fsblk_t, pc_pclu )
637 + __field( ext4_lblk_t, pc_lblk )
638 + __field( int, pc_state )
639 __field( unsigned short, eh_entries )
642 @@ -2188,18 +2203,23 @@ TRACE_EVENT(ext4_ext_remove_space_done,
643 __entry->start = start;
645 __entry->depth = depth;
646 - __entry->partial = partial;
647 + __entry->pc_pclu = pc->pclu;
648 + __entry->pc_lblk = pc->lblk;
649 + __entry->pc_state = pc->state;
650 __entry->eh_entries = le16_to_cpu(eh_entries);
653 - TP_printk("dev %d,%d ino %lu since %u end %u depth %d partial %lld "
654 + TP_printk("dev %d,%d ino %lu since %u end %u depth %d "
655 + "partial [pclu %lld lblk %u state %d] "
656 "remaining_entries %u",
657 MAJOR(__entry->dev), MINOR(__entry->dev),
658 (unsigned long) __entry->ino,
659 (unsigned) __entry->start,
660 (unsigned) __entry->end,
662 - (long long) __entry->partial,
663 + (long long) __entry->pc_pclu,
664 + (unsigned int) __entry->pc_lblk,
665 + (int) __entry->pc_state,
666 (unsigned short) __entry->eh_entries)