Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ext4: adjust reserved cluster count when removing extents

Modify ext4_ext_remove_space() and the code it calls to correct the
reserved cluster count for pending reservations (delayed allocated
clusters shared with allocated blocks) when a block range is removed
from the extent tree. Pending reservations may be found for the clusters
at the ends of written or unwritten extents when a block range is removed.
If a physical cluster at the end of an extent is freed, it's necessary
to increment the reserved cluster count to maintain correct accounting
if the corresponding logical cluster is shared with at least one
delayed and unwritten extent as found in the extents status tree.

Add a new function, ext4_rereserve_cluster(), to reapply a reservation
on a delayed allocated cluster sharing blocks with a freed allocated
cluster. To avoid ENOSPC on reservation, a flag is applied to
ext4_free_blocks() to briefly defer updating the freeclusters counter
when an allocated cluster is freed. This prevents another thread
from allocating the freed block before the reservation can be reapplied.

Redefine the partial cluster object as a struct to carry more state
information and to clarify the code using it.

Adjust the conditional code structure in ext4_ext_remove_space to
reduce the indentation level in the main body of the code to improve
readability.

Signed-off-by: Eric Whitney <enwlinux@gmail.com>
Signed-off-by: Theodore Ts'o <tytso@mit.edu>

authored by

Eric Whitney and committed by
Theodore Ts'o
9fe67149 b6bf9171

+239 -135
+1
fs/ext4/ext4.h
··· 628 628 #define EXT4_FREE_BLOCKS_NO_QUOT_UPDATE 0x0008 629 629 #define EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER 0x0010 630 630 #define EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER 0x0020 631 + #define EXT4_FREE_BLOCKS_RERESERVE_CLUSTER 0x0040 631 632 632 633 /* 633 634 * ioctl commands
+13
fs/ext4/ext4_extents.h
··· 120 120 }; 121 121 122 122 /* 123 + * Used to record a portion of a cluster found at the beginning or end 124 + * of an extent while traversing the extent tree during space removal. 125 + * A partial cluster may be removed if it does not contain blocks shared 126 + * with extents that aren't being deleted (tofree state). Otherwise, 127 + * it cannot be removed (nofree state). 128 + */ 129 + struct partial_cluster { 130 + ext4_fsblk_t pclu; /* physical cluster number */ 131 + ext4_lblk_t lblk; /* logical block number within logical cluster */ 132 + enum {initial, tofree, nofree} state; 133 + }; 134 + 135 + /* 123 136 * structure for external API 124 137 */ 125 138
+174 -112
fs/ext4/extents.c
··· 2490 2490 return 0; 2491 2491 } 2492 2492 2493 + /* 2494 + * ext4_rereserve_cluster - increment the reserved cluster count when 2495 + * freeing a cluster with a pending reservation 2496 + * 2497 + * @inode - file containing the cluster 2498 + * @lblk - logical block in cluster to be reserved 2499 + * 2500 + * Increments the reserved cluster count and adjusts quota in a bigalloc 2501 + * file system when freeing a partial cluster containing at least one 2502 + * delayed and unwritten block. A partial cluster meeting that 2503 + * requirement will have a pending reservation. If so, the 2504 + * RERESERVE_CLUSTER flag is used when calling ext4_free_blocks() to 2505 + * defer reserved and allocated space accounting to a subsequent call 2506 + * to this function. 2507 + */ 2508 + static void ext4_rereserve_cluster(struct inode *inode, ext4_lblk_t lblk) 2509 + { 2510 + struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 2511 + struct ext4_inode_info *ei = EXT4_I(inode); 2512 + 2513 + dquot_reclaim_block(inode, EXT4_C2B(sbi, 1)); 2514 + 2515 + spin_lock(&ei->i_block_reservation_lock); 2516 + ei->i_reserved_data_blocks++; 2517 + percpu_counter_add(&sbi->s_dirtyclusters_counter, 1); 2518 + spin_unlock(&ei->i_block_reservation_lock); 2519 + 2520 + percpu_counter_add(&sbi->s_freeclusters_counter, 1); 2521 + ext4_remove_pending(inode, lblk); 2522 + } 2523 + 2493 2524 static int ext4_remove_blocks(handle_t *handle, struct inode *inode, 2494 2525 struct ext4_extent *ex, 2495 - long long *partial_cluster, 2526 + struct partial_cluster *partial, 2496 2527 ext4_lblk_t from, ext4_lblk_t to) 2497 2528 { 2498 2529 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 2499 2530 unsigned short ee_len = ext4_ext_get_actual_len(ex); 2500 - ext4_fsblk_t pblk; 2501 - int flags = get_default_free_blocks_flags(inode); 2531 + ext4_fsblk_t last_pblk, pblk; 2532 + ext4_lblk_t num; 2533 + int flags; 2534 + 2535 + /* only extent tail removal is allowed */ 2536 + if (from < le32_to_cpu(ex->ee_block) || 2537 + to != le32_to_cpu(ex->ee_block) + ee_len - 1) { 2538 + ext4_error(sbi->s_sb, 2539 + "strange request: removal(2) %u-%u from %u:%u", 2540 + from, to, le32_to_cpu(ex->ee_block), ee_len); 2541 + return 0; 2542 + } 2543 + 2544 + #ifdef EXTENTS_STATS 2545 + spin_lock(&sbi->s_ext_stats_lock); 2546 + sbi->s_ext_blocks += ee_len; 2547 + sbi->s_ext_extents++; 2548 + if (ee_len < sbi->s_ext_min) 2549 + sbi->s_ext_min = ee_len; 2550 + if (ee_len > sbi->s_ext_max) 2551 + sbi->s_ext_max = ee_len; 2552 + if (ext_depth(inode) > sbi->s_depth_max) 2553 + sbi->s_depth_max = ext_depth(inode); 2554 + spin_unlock(&sbi->s_ext_stats_lock); 2555 + #endif 2556 + 2557 + trace_ext4_remove_blocks(inode, ex, from, to, partial); 2558 + 2559 + /* 2560 + * if we have a partial cluster, and it's different from the 2561 + * cluster of the last block in the extent, we free it 2562 + */ 2563 + last_pblk = ext4_ext_pblock(ex) + ee_len - 1; 2564 + 2565 + if (partial->state != initial && 2566 + partial->pclu != EXT4_B2C(sbi, last_pblk)) { 2567 + if (partial->state == tofree) { 2568 + flags = get_default_free_blocks_flags(inode); 2569 + if (ext4_is_pending(inode, partial->lblk)) 2570 + flags |= EXT4_FREE_BLOCKS_RERESERVE_CLUSTER; 2571 + ext4_free_blocks(handle, inode, NULL, 2572 + EXT4_C2B(sbi, partial->pclu), 2573 + sbi->s_cluster_ratio, flags); 2574 + if (flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER) 2575 + ext4_rereserve_cluster(inode, partial->lblk); 2576 + } 2577 + partial->state = initial; 2578 + } 2579 + 2580 + num = le32_to_cpu(ex->ee_block) + ee_len - from; 2581 + pblk = ext4_ext_pblock(ex) + ee_len - num; 2582 + 2583 + /* 2584 + * We free the partial cluster at the end of the extent (if any), 2585 + * unless the cluster is used by another extent (partial_cluster 2586 + * state is nofree). If a partial cluster exists here, it must be 2587 + * shared with the last block in the extent. 2588 + */ 2589 + flags = get_default_free_blocks_flags(inode); 2590 + 2591 + /* partial, left end cluster aligned, right end unaligned */ 2592 + if ((EXT4_LBLK_COFF(sbi, to) != sbi->s_cluster_ratio - 1) && 2593 + (EXT4_LBLK_CMASK(sbi, to) >= from) && 2594 + (partial->state != nofree)) { 2595 + if (ext4_is_pending(inode, to)) 2596 + flags |= EXT4_FREE_BLOCKS_RERESERVE_CLUSTER; 2597 + ext4_free_blocks(handle, inode, NULL, 2598 + EXT4_PBLK_CMASK(sbi, last_pblk), 2599 + sbi->s_cluster_ratio, flags); 2600 + if (flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER) 2601 + ext4_rereserve_cluster(inode, to); 2602 + partial->state = initial; 2603 + flags = get_default_free_blocks_flags(inode); 2604 + } 2605 + 2606 + flags |= EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER; 2502 2607 2503 2608 /* 2504 2609 * For bigalloc file systems, we never free a partial cluster 2505 - * at the beginning of the extent. Instead, we make a note 2506 - * that we tried freeing the cluster, and check to see if we 2610 + * at the beginning of the extent. Instead, we check to see if we 2507 2611 * need to free it on a subsequent call to ext4_remove_blocks, 2508 2612 * or at the end of ext4_ext_rm_leaf or ext4_ext_remove_space. 2509 2613 */ 2510 2614 flags |= EXT4_FREE_BLOCKS_NOFREE_FIRST_CLUSTER; 2615 + ext4_free_blocks(handle, inode, NULL, pblk, num, flags); 2511 2616 2512 - trace_ext4_remove_blocks(inode, ex, from, to, *partial_cluster); 2617 + /* reset the partial cluster if we've freed past it */ 2618 + if (partial->state != initial && partial->pclu != EXT4_B2C(sbi, pblk)) 2619 + partial->state = initial; 2620 + 2513 2621 /* 2514 - * If we have a partial cluster, and it's different from the 2515 - * cluster of the last block, we need to explicitly free the 2516 - * partial cluster here. 2622 + * If we've freed the entire extent but the beginning is not left 2623 + * cluster aligned and is not marked as ineligible for freeing we 2624 + * record the partial cluster at the beginning of the extent. It 2625 + * wasn't freed by the preceding ext4_free_blocks() call, and we 2626 + * need to look farther to the left to determine if it's to be freed 2627 + * (not shared with another extent). Else, reset the partial 2628 + * cluster - we're either done freeing or the beginning of the 2629 + * extent is left cluster aligned. 2517 2630 */ 2518 - pblk = ext4_ext_pblock(ex) + ee_len - 1; 2519 - if (*partial_cluster > 0 && 2520 - *partial_cluster != (long long) EXT4_B2C(sbi, pblk)) { 2521 - ext4_free_blocks(handle, inode, NULL, 2522 - EXT4_C2B(sbi, *partial_cluster), 2523 - sbi->s_cluster_ratio, flags); 2524 - *partial_cluster = 0; 2525 - } 2526 - 2527 - #ifdef EXTENTS_STATS 2528 - { 2529 - struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 2530 - spin_lock(&sbi->s_ext_stats_lock); 2531 - sbi->s_ext_blocks += ee_len; 2532 - sbi->s_ext_extents++; 2533 - if (ee_len < sbi->s_ext_min) 2534 - sbi->s_ext_min = ee_len; 2535 - if (ee_len > sbi->s_ext_max) 2536 - sbi->s_ext_max = ee_len; 2537 - if (ext_depth(inode) > sbi->s_depth_max) 2538 - sbi->s_depth_max = ext_depth(inode); 2539 - spin_unlock(&sbi->s_ext_stats_lock); 2540 - } 2541 - #endif 2542 - if (from >= le32_to_cpu(ex->ee_block) 2543 - && to == le32_to_cpu(ex->ee_block) + ee_len - 1) { 2544 - /* tail removal */ 2545 - ext4_lblk_t num; 2546 - long long first_cluster; 2547 - 2548 - num = le32_to_cpu(ex->ee_block) + ee_len - from; 2549 - pblk = ext4_ext_pblock(ex) + ee_len - num; 2550 - /* 2551 - * Usually we want to free partial cluster at the end of the 2552 - * extent, except for the situation when the cluster is still 2553 - * used by any other extent (partial_cluster is negative). 2554 - */ 2555 - if (*partial_cluster < 0 && 2556 - *partial_cluster == -(long long) EXT4_B2C(sbi, pblk+num-1)) 2557 - flags |= EXT4_FREE_BLOCKS_NOFREE_LAST_CLUSTER; 2558 - 2559 - ext_debug("free last %u blocks starting %llu partial %lld\n", 2560 - num, pblk, *partial_cluster); 2561 - ext4_free_blocks(handle, inode, NULL, pblk, num, flags); 2562 - /* 2563 - * If the block range to be freed didn't start at the 2564 - * beginning of a cluster, and we removed the entire 2565 - * extent and the cluster is not used by any other extent, 2566 - * save the partial cluster here, since we might need to 2567 - * delete if we determine that the truncate or punch hole 2568 - * operation has removed all of the blocks in the cluster. 2569 - * If that cluster is used by another extent, preserve its 2570 - * negative value so it isn't freed later on. 2571 - * 2572 - * If the whole extent wasn't freed, we've reached the 2573 - * start of the truncated/punched region and have finished 2574 - * removing blocks. If there's a partial cluster here it's 2575 - * shared with the remainder of the extent and is no longer 2576 - * a candidate for removal. 2577 - */ 2578 - if (EXT4_PBLK_COFF(sbi, pblk) && ee_len == num) { 2579 - first_cluster = (long long) EXT4_B2C(sbi, pblk); 2580 - if (first_cluster != -*partial_cluster) 2581 - *partial_cluster = first_cluster; 2582 - } else { 2583 - *partial_cluster = 0; 2631 + if (EXT4_LBLK_COFF(sbi, from) && num == ee_len) { 2632 + if (partial->state == initial) { 2633 + partial->pclu = EXT4_B2C(sbi, pblk); 2634 + partial->lblk = from; 2635 + partial->state = tofree; 2584 2636 } 2585 - } else 2586 - ext4_error(sbi->s_sb, "strange request: removal(2) " 2587 - "%u-%u from %u:%u", 2588 - from, to, le32_to_cpu(ex->ee_block), ee_len); 2637 + } else { 2638 + partial->state = initial; 2639 + } 2640 + 2589 2641 return 0; 2590 2642 } 2591 - 2592 2643 2593 2644 /* 2594 2645 * ext4_ext_rm_leaf() Removes the extents associated with the ··· 2659 2608 static int 2660 2609 ext4_ext_rm_leaf(handle_t *handle, struct inode *inode, 2661 2610 struct ext4_ext_path *path, 2662 - long long *partial_cluster, 2611 + struct partial_cluster *partial, 2663 2612 ext4_lblk_t start, ext4_lblk_t end) 2664 2613 { 2665 2614 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); ··· 2691 2640 ex_ee_block = le32_to_cpu(ex->ee_block); 2692 2641 ex_ee_len = ext4_ext_get_actual_len(ex); 2693 2642 2694 - trace_ext4_ext_rm_leaf(inode, start, ex, *partial_cluster); 2643 + trace_ext4_ext_rm_leaf(inode, start, ex, partial); 2695 2644 2696 2645 while (ex >= EXT_FIRST_EXTENT(eh) && 2697 2646 ex_ee_block + ex_ee_len > start) { ··· 2722 2671 */ 2723 2672 if (sbi->s_cluster_ratio > 1) { 2724 2673 pblk = ext4_ext_pblock(ex); 2725 - *partial_cluster = 2726 - -(long long) EXT4_B2C(sbi, pblk); 2674 + partial->pclu = EXT4_B2C(sbi, pblk); 2675 + partial->state = nofree; 2727 2676 } 2728 2677 ex--; 2729 2678 ex_ee_block = le32_to_cpu(ex->ee_block); ··· 2765 2714 if (err) 2766 2715 goto out; 2767 2716 2768 - err = ext4_remove_blocks(handle, inode, ex, partial_cluster, 2769 - a, b); 2717 + err = ext4_remove_blocks(handle, inode, ex, partial, a, b); 2770 2718 if (err) 2771 2719 goto out; 2772 2720 ··· 2819 2769 * If there's a partial cluster and at least one extent remains in 2820 2770 * the leaf, free the partial cluster if it isn't shared with the 2821 2771 * current extent. If it is shared with the current extent 2822 - * we zero partial_cluster because we've reached the start of the 2772 + * we reset the partial cluster because we've reached the start of the 2823 2773 * truncated/punched region and we're done removing blocks. 2824 2774 */ 2825 - if (*partial_cluster > 0 && ex >= EXT_FIRST_EXTENT(eh)) { 2775 + if (partial->state == tofree && ex >= EXT_FIRST_EXTENT(eh)) { 2826 2776 pblk = ext4_ext_pblock(ex) + ex_ee_len - 1; 2827 - if (*partial_cluster != (long long) EXT4_B2C(sbi, pblk)) { 2777 + if (partial->pclu != EXT4_B2C(sbi, pblk)) { 2778 + int flags = get_default_free_blocks_flags(inode); 2779 + 2780 + if (ext4_is_pending(inode, partial->lblk)) 2781 + flags |= EXT4_FREE_BLOCKS_RERESERVE_CLUSTER; 2828 2782 ext4_free_blocks(handle, inode, NULL, 2829 - EXT4_C2B(sbi, *partial_cluster), 2830 - sbi->s_cluster_ratio, 2831 - get_default_free_blocks_flags(inode)); 2783 + EXT4_C2B(sbi, partial->pclu), 2784 + sbi->s_cluster_ratio, flags); 2785 + if (flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER) 2786 + ext4_rereserve_cluster(inode, partial->lblk); 2832 2787 } 2833 - *partial_cluster = 0; 2788 + partial->state = initial; 2834 2789 } 2835 2790 2836 2791 /* if this leaf is free, then we should ··· 2874 2819 struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); 2875 2820 int depth = ext_depth(inode); 2876 2821 struct ext4_ext_path *path = NULL; 2877 - long long partial_cluster = 0; 2822 + struct partial_cluster partial; 2878 2823 handle_t *handle; 2879 2824 int i = 0, err = 0; 2825 + 2826 + partial.pclu = 0; 2827 + partial.lblk = 0; 2828 + partial.state = initial; 2880 2829 2881 2830 ext_debug("truncate since %u to %u\n", start, end); 2882 2831 ··· 2941 2882 */ 2942 2883 if (sbi->s_cluster_ratio > 1) { 2943 2884 pblk = ext4_ext_pblock(ex) + end - ee_block + 2; 2944 - partial_cluster = 2945 - -(long long) EXT4_B2C(sbi, pblk); 2885 + partial.pclu = EXT4_B2C(sbi, pblk); 2886 + partial.state = nofree; 2946 2887 } 2947 2888 2948 2889 /* ··· 2970 2911 &ex); 2971 2912 if (err) 2972 2913 goto out; 2973 - if (pblk) 2974 - partial_cluster = 2975 - -(long long) EXT4_B2C(sbi, pblk); 2914 + if (pblk) { 2915 + partial.pclu = EXT4_B2C(sbi, pblk); 2916 + partial.state = nofree; 2917 + } 2976 2918 } 2977 2919 } 2978 2920 /* ··· 3008 2948 if (i == depth) { 3009 2949 /* this is leaf block */ 3010 2950 err = ext4_ext_rm_leaf(handle, inode, path, 3011 - &partial_cluster, start, 3012 - end); 2951 + &partial, start, end); 3013 2952 /* root level has p_bh == NULL, brelse() eats this */ 3014 2953 brelse(path[i].p_bh); 3015 2954 path[i].p_bh = NULL; ··· 3080 3021 } 3081 3022 } 3082 3023 3083 - trace_ext4_ext_remove_space_done(inode, start, end, depth, 3084 - partial_cluster, path->p_hdr->eh_entries); 3024 + trace_ext4_ext_remove_space_done(inode, start, end, depth, &partial, 3025 + path->p_hdr->eh_entries); 3085 3026 3086 3027 /* 3087 - * If we still have something in the partial cluster and we have removed 3088 - * even the first extent, then we should free the blocks in the partial 3089 - * cluster as well. (This code will only run when there are no leaves 3090 - * to the immediate left of the truncated/punched region.) 3028 + * if there's a partial cluster and we have removed the first extent 3029 + * in the file, then we also free the partial cluster, if any 3091 3030 */ 3092 - if (partial_cluster > 0 && err == 0) { 3093 - /* don't zero partial_cluster since it's not used afterwards */ 3031 + if (partial.state == tofree && err == 0) { 3032 + int flags = get_default_free_blocks_flags(inode); 3033 + 3034 + if (ext4_is_pending(inode, partial.lblk)) 3035 + flags |= EXT4_FREE_BLOCKS_RERESERVE_CLUSTER; 3094 3036 ext4_free_blocks(handle, inode, NULL, 3095 - EXT4_C2B(sbi, partial_cluster), 3096 - sbi->s_cluster_ratio, 3097 - get_default_free_blocks_flags(inode)); 3037 + EXT4_C2B(sbi, partial.pclu), 3038 + sbi->s_cluster_ratio, flags); 3039 + if (flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER) 3040 + ext4_rereserve_cluster(inode, partial.lblk); 3041 + partial.state = initial; 3098 3042 } 3099 3043 3100 3044 /* TODO: flexible tree reduction should be here */
+11 -3
fs/ext4/mballoc.c
··· 4915 4915 &sbi->s_flex_groups[flex_group].free_clusters); 4916 4916 } 4917 4917 4918 - if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE)) 4919 - dquot_free_block(inode, EXT4_C2B(sbi, count_clusters)); 4920 - percpu_counter_add(&sbi->s_freeclusters_counter, count_clusters); 4918 + /* 4919 + * on a bigalloc file system, defer the s_freeclusters_counter 4920 + * update to the caller (ext4_remove_space and friends) so they 4921 + * can determine if a cluster freed here should be rereserved 4922 + */ 4923 + if (!(flags & EXT4_FREE_BLOCKS_RERESERVE_CLUSTER)) { 4924 + if (!(flags & EXT4_FREE_BLOCKS_NO_QUOT_UPDATE)) 4925 + dquot_free_block(inode, EXT4_C2B(sbi, count_clusters)); 4926 + percpu_counter_add(&sbi->s_freeclusters_counter, 4927 + count_clusters); 4928 + } 4921 4929 4922 4930 ext4_mb_unload_buddy(&e4b); 4923 4931
+40 -20
include/trace/events/ext4.h
··· 17 17 struct ext4_map_blocks; 18 18 struct extent_status; 19 19 struct ext4_fsmap; 20 + struct partial_cluster; 20 21 21 22 #define EXT4_I(inode) (container_of(inode, struct ext4_inode_info, vfs_inode)) 22 23 ··· 2036 2035 ); 2037 2036 2038 2037 TRACE_EVENT(ext4_remove_blocks, 2039 - TP_PROTO(struct inode *inode, struct ext4_extent *ex, 2040 - ext4_lblk_t from, ext4_fsblk_t to, 2041 - long long partial_cluster), 2038 + TP_PROTO(struct inode *inode, struct ext4_extent *ex, 2039 + ext4_lblk_t from, ext4_fsblk_t to, 2040 + struct partial_cluster *pc), 2042 2041 2043 - TP_ARGS(inode, ex, from, to, partial_cluster), 2042 + TP_ARGS(inode, ex, from, to, pc), 2044 2043 2045 2044 TP_STRUCT__entry( 2046 2045 __field( dev_t, dev ) 2047 2046 __field( ino_t, ino ) 2048 2047 __field( ext4_lblk_t, from ) 2049 2048 __field( ext4_lblk_t, to ) 2050 - __field( long long, partial ) 2051 2049 __field( ext4_fsblk_t, ee_pblk ) 2052 2050 __field( ext4_lblk_t, ee_lblk ) 2053 2051 __field( unsigned short, ee_len ) 2052 + __field( ext4_fsblk_t, pc_pclu ) 2053 + __field( ext4_lblk_t, pc_lblk ) 2054 + __field( int, pc_state) 2054 2055 ), 2055 2056 2056 2057 TP_fast_assign( ··· 2060 2057 __entry->ino = inode->i_ino; 2061 2058 __entry->from = from; 2062 2059 __entry->to = to; 2063 - __entry->partial = partial_cluster; 2064 2060 __entry->ee_pblk = ext4_ext_pblock(ex); 2065 2061 __entry->ee_lblk = le32_to_cpu(ex->ee_block); 2066 2062 __entry->ee_len = ext4_ext_get_actual_len(ex); 2063 + __entry->pc_pclu = pc->pclu; 2064 + __entry->pc_lblk = pc->lblk; 2065 + __entry->pc_state = pc->state; 2067 2066 ), 2068 2067 2069 2068 TP_printk("dev %d,%d ino %lu extent [%u(%llu), %u]" 2070 - "from %u to %u partial_cluster %lld", 2069 + "from %u to %u partial [pclu %lld lblk %u state %d]", 2071 2070 MAJOR(__entry->dev), MINOR(__entry->dev), 2072 2071 (unsigned long) __entry->ino, 2073 2072 (unsigned) __entry->ee_lblk, ··· 2077 2072 (unsigned short) __entry->ee_len, 2078 2073 (unsigned) __entry->from, 2079 2074 (unsigned) __entry->to, 2080 - (long long) __entry->partial) 2075 + (long long) __entry->pc_pclu, 2076 + (unsigned int) __entry->pc_lblk, 2077 + (int) __entry->pc_state) 2081 2078 ); 2082 2079 2083 2080 TRACE_EVENT(ext4_ext_rm_leaf, 2084 2081 TP_PROTO(struct inode *inode, ext4_lblk_t start, 2085 2082 struct ext4_extent *ex, 2086 - long long partial_cluster), 2083 + struct partial_cluster *pc), 2087 2084 2088 - TP_ARGS(inode, start, ex, partial_cluster), 2085 + TP_ARGS(inode, start, ex, pc), 2089 2086 2090 2087 TP_STRUCT__entry( 2091 2088 __field( dev_t, dev ) 2092 2089 __field( ino_t, ino ) 2093 - __field( long long, partial ) 2094 2090 __field( ext4_lblk_t, start ) 2095 2091 __field( ext4_lblk_t, ee_lblk ) 2096 2092 __field( ext4_fsblk_t, ee_pblk ) 2097 2093 __field( short, ee_len ) 2094 + __field( ext4_fsblk_t, pc_pclu ) 2095 + __field( ext4_lblk_t, pc_lblk ) 2096 + __field( int, pc_state) 2098 2097 ), 2099 2098 2100 2099 TP_fast_assign( 2101 2100 __entry->dev = inode->i_sb->s_dev; 2102 2101 __entry->ino = inode->i_ino; 2103 - __entry->partial = partial_cluster; 2104 2102 __entry->start = start; 2105 2103 __entry->ee_lblk = le32_to_cpu(ex->ee_block); 2106 2104 __entry->ee_pblk = ext4_ext_pblock(ex); 2107 2105 __entry->ee_len = ext4_ext_get_actual_len(ex); 2106 + __entry->pc_pclu = pc->pclu; 2107 + __entry->pc_lblk = pc->lblk; 2108 + __entry->pc_state = pc->state; 2108 2109 ), 2109 2110 2110 2111 TP_printk("dev %d,%d ino %lu start_lblk %u last_extent [%u(%llu), %u]" 2111 - "partial_cluster %lld", 2112 + "partial [pclu %lld lblk %u state %d]", 2112 2113 MAJOR(__entry->dev), MINOR(__entry->dev), 2113 2114 (unsigned long) __entry->ino, 2114 2115 (unsigned) __entry->start, 2115 2116 (unsigned) __entry->ee_lblk, 2116 2117 (unsigned long long) __entry->ee_pblk, 2117 2118 (unsigned short) __entry->ee_len, 2118 - (long long) __entry->partial) 2119 + (long long) __entry->pc_pclu, 2120 + (unsigned int) __entry->pc_lblk, 2121 + (int) __entry->pc_state) 2119 2122 ); 2120 2123 2121 2124 TRACE_EVENT(ext4_ext_rm_idx, ··· 2181 2168 2182 2169 TRACE_EVENT(ext4_ext_remove_space_done, 2183 2170 TP_PROTO(struct inode *inode, ext4_lblk_t start, ext4_lblk_t end, 2184 - int depth, long long partial, __le16 eh_entries), 2171 + int depth, struct partial_cluster *pc, __le16 eh_entries), 2185 2172 2186 - TP_ARGS(inode, start, end, depth, partial, eh_entries), 2173 + TP_ARGS(inode, start, end, depth, pc, eh_entries), 2187 2174 2188 2175 TP_STRUCT__entry( 2189 2176 __field( dev_t, dev ) ··· 2191 2178 __field( ext4_lblk_t, start ) 2192 2179 __field( ext4_lblk_t, end ) 2193 2180 __field( int, depth ) 2194 - __field( long long, partial ) 2181 + __field( ext4_fsblk_t, pc_pclu ) 2182 + __field( ext4_lblk_t, pc_lblk ) 2183 + __field( int, pc_state ) 2195 2184 __field( unsigned short, eh_entries ) 2196 2185 ), 2197 2186 ··· 2203 2188 __entry->start = start; 2204 2189 __entry->end = end; 2205 2190 __entry->depth = depth; 2206 - __entry->partial = partial; 2191 + __entry->pc_pclu = pc->pclu; 2192 + __entry->pc_lblk = pc->lblk; 2193 + __entry->pc_state = pc->state; 2207 2194 __entry->eh_entries = le16_to_cpu(eh_entries); 2208 2195 ), 2209 2196 2210 - TP_printk("dev %d,%d ino %lu since %u end %u depth %d partial %lld " 2197 + TP_printk("dev %d,%d ino %lu since %u end %u depth %d " 2198 + "partial [pclu %lld lblk %u state %d] " 2211 2199 "remaining_entries %u", 2212 2200 MAJOR(__entry->dev), MINOR(__entry->dev), 2213 2201 (unsigned long) __entry->ino, 2214 2202 (unsigned) __entry->start, 2215 2203 (unsigned) __entry->end, 2216 2204 __entry->depth, 2217 - (long long) __entry->partial, 2205 + (long long) __entry->pc_pclu, 2206 + (unsigned int) __entry->pc_lblk, 2207 + (int) __entry->pc_state, 2218 2208 (unsigned short) __entry->eh_entries) 2219 2209 ); 2220 2210