Blame view
fs/ext4/mballoc.h
5.41 KB
f51667685
|
1 |
// SPDX-License-Identifier: GPL-2.0 |
8f6e39a7a
|
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/* * fs/ext4/mballoc.h * * Written by: Alex Tomas <alex@clusterfs.com> * */ #ifndef _EXT4_MBALLOC_H #define _EXT4_MBALLOC_H #include <linux/time.h> #include <linux/fs.h> #include <linux/namei.h> #include <linux/quotaops.h> #include <linux/buffer_head.h> #include <linux/module.h> #include <linux/swap.h> #include <linux/proc_fs.h> #include <linux/pagemap.h> #include <linux/seq_file.h> |
8a0aba733
|
21 |
#include <linux/blkdev.h> |
920313a72
|
22 |
#include <linux/mutex.h> |
8f6e39a7a
|
23 24 |
#include "ext4_jbd2.h" #include "ext4.h" |
8f6e39a7a
|
25 26 |
/* |
d3df14535
|
27 |
* mb_debug() dynamic printk msgs could be used to debug mballoc code. |
8f6e39a7a
|
28 |
*/ |
6ba495e92
|
29 |
#ifdef CONFIG_EXT4_DEBUG |
d3df14535
|
30 31 32 33 |
#define mb_debug(sb, fmt, ...) \ pr_debug("[%s/%d] EXT4-fs (%s): (%s, %d): %s: " fmt, \ current->comm, task_pid_nr(current), sb->s_id, \ __FILE__, __LINE__, __func__, ##__VA_ARGS__) |
8f6e39a7a
|
34 |
#else |
d3df14535
|
35 |
#define mb_debug(sb, fmt, ...) no_printk(fmt, ##__VA_ARGS__) |
8f6e39a7a
|
36 |
#endif |
8f6e39a7a
|
37 38 |
#define EXT4_MB_HISTORY_ALLOC 1 /* allocation */ #define EXT4_MB_HISTORY_PREALLOC 2 /* preallocated blocks used */ |
8f6e39a7a
|
39 40 41 42 43 44 45 46 47 48 49 50 |
/* * How long mballoc can look for a best extent (in found extents) */ #define MB_DEFAULT_MAX_TO_SCAN 200 /* * How long mballoc must look for a best extent */ #define MB_DEFAULT_MIN_TO_SCAN 10 /* |
8f6e39a7a
|
51 52 53 |
* with 'ext4_mb_stats' allocator will collect stats that will be * shown at umount. The collecting costs though! */ |
90576c0b9
|
54 |
#define MB_DEFAULT_STATS 0 |
8f6e39a7a
|
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
/* * files smaller than MB_DEFAULT_STREAM_THRESHOLD are served * by the stream allocator, which purpose is to pack requests * as close each to other as possible to produce smooth I/O traffic * We use locality group prealloc space for stream request. * We can tune the same via /proc/fs/ext4/<parition>/stream_req */ #define MB_DEFAULT_STREAM_THRESHOLD 16 /* 64K */ /* * for which requests use 2^N search using buddies */ #define MB_DEFAULT_ORDER2_REQS 2 /* * default group prealloc size 512 blocks */ #define MB_DEFAULT_GROUP_PREALLOC 512 |
27bc446e2
|
74 75 76 77 |
/* * maximum length of inode prealloc list */ #define MB_DEFAULT_MAX_INODE_PREALLOC 512 |
8f6e39a7a
|
78 |
|
c894058d6
|
79 |
struct ext4_free_data { |
a01543448
|
80 81 |
/* this links the free block information from sb_info */ struct list_head efd_list; |
8f6e39a7a
|
82 |
|
18aadd47f
|
83 84 |
/* this links the free block information from group_info */ struct rb_node efd_node; |
c894058d6
|
85 86 |
/* group which free block extent belongs */ |
18aadd47f
|
87 |
ext4_group_t efd_group; |
c894058d6
|
88 89 |
/* free block extent */ |
18aadd47f
|
90 91 |
ext4_grpblk_t efd_start_cluster; ext4_grpblk_t efd_count; |
c894058d6
|
92 93 |
/* transaction which freed this extent */ |
18aadd47f
|
94 |
tid_t efd_tid; |
8f6e39a7a
|
95 |
}; |
8f6e39a7a
|
96 97 98 99 100 101 102 103 104 105 106 107 |
struct ext4_prealloc_space { struct list_head pa_inode_list; struct list_head pa_group_list; union { struct list_head pa_tmp_list; struct rcu_head pa_rcu; } u; spinlock_t pa_lock; atomic_t pa_count; unsigned pa_deleted; ext4_fsblk_t pa_pstart; /* phys. block */ ext4_lblk_t pa_lstart; /* log. block */ |
a36b44988
|
108 109 |
ext4_grpblk_t pa_len; /* len of preallocated chunk */ ext4_grpblk_t pa_free; /* how many blocks are free */ |
cc0fb9ad7
|
110 |
unsigned short pa_type; /* pa type. inode or group */ |
8f6e39a7a
|
111 112 113 |
spinlock_t *pa_obj_lock; struct inode *pa_inode; /* hack, for history only */ }; |
cc0fb9ad7
|
114 115 116 117 |
enum { MB_INODE_PA = 0, MB_GROUP_PA = 1 }; |
8f6e39a7a
|
118 119 120 |
struct ext4_free_extent { ext4_lblk_t fe_logical; |
53accfa9f
|
121 |
ext4_grpblk_t fe_start; /* In cluster units */ |
8f6e39a7a
|
122 |
ext4_group_t fe_group; |
53accfa9f
|
123 |
ext4_grpblk_t fe_len; /* In cluster units */ |
8f6e39a7a
|
124 125 126 127 128 129 |
}; /* * Locality group: * we try to group all related changes together * so that writeback can flush/allocate them together as well |
6be2ded1d
|
130 131 132 |
* Size of lg_prealloc_list hash is determined by MB_DEFAULT_GROUP_PREALLOC * (512). We store prealloc space into the hash based on the pa_free blocks * order value.ie, fls(pa_free)-1; |
8f6e39a7a
|
133 |
*/ |
6be2ded1d
|
134 |
#define PREALLOC_TB_SIZE 10 |
8f6e39a7a
|
135 136 |
struct ext4_locality_group { /* for allocator */ |
6be2ded1d
|
137 138 139 140 |
/* to serialize allocates */ struct mutex lg_mutex; /* list of preallocations */ struct list_head lg_prealloc_list[PREALLOC_TB_SIZE]; |
8f6e39a7a
|
141 142 143 144 145 146 147 148 149 |
spinlock_t lg_prealloc_lock; }; struct ext4_allocation_context { struct inode *ac_inode; struct super_block *ac_sb; /* original request */ struct ext4_free_extent ac_o_ex; |
58696f3ab
|
150 |
/* goal request (normalized ac_o_ex) */ |
8f6e39a7a
|
151 152 153 154 |
struct ext4_free_extent ac_g_ex; /* the best found extent */ struct ext4_free_extent ac_b_ex; |
ff3fc1736
|
155 |
/* copy of the best found extent taken before preallocation efforts */ |
8f6e39a7a
|
156 |
struct ext4_free_extent ac_f_ex; |
8f6e39a7a
|
157 158 159 160 161 162 163 |
__u16 ac_groups_scanned; __u16 ac_found; __u16 ac_tail; __u16 ac_buddy; __u16 ac_flags; /* allocation hints */ __u8 ac_status; __u8 ac_criteria; |
8f6e39a7a
|
164 165 166 167 168 169 170 171 172 173 174 175 |
__u8 ac_2order; /* if request is to allocate 2^N blocks and * N > 0, the field stores N, otherwise 0 */ __u8 ac_op; /* operation, for history only */ struct page *ac_bitmap_page; struct page *ac_buddy_page; struct ext4_prealloc_space *ac_pa; struct ext4_locality_group *ac_lg; }; #define AC_STATUS_CONTINUE 1 #define AC_STATUS_FOUND 2 #define AC_STATUS_BREAK 3 |
8f6e39a7a
|
176 177 178 179 180 181 182 183 184 185 |
struct ext4_buddy { struct page *bd_buddy_page; void *bd_buddy; struct page *bd_bitmap_page; void *bd_bitmap; struct ext4_group_info *bd_info; struct super_block *bd_sb; __u16 bd_blkbits; ext4_group_t bd_group; }; |
8f6e39a7a
|
186 |
|
c3a326a65
|
187 |
static inline ext4_fsblk_t ext4_grp_offs_to_block(struct super_block *sb, |
8f6e39a7a
|
188 189 |
struct ext4_free_extent *fex) { |
3212a80a5
|
190 191 |
return ext4_group_first_block_no(sb, fex->fe_group) + (fex->fe_start << EXT4_SB(sb)->s_cluster_bits); |
8f6e39a7a
|
192 |
} |
0c9ec4bee
|
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
typedef int (*ext4_mballoc_query_range_fn)( struct super_block *sb, ext4_group_t agno, ext4_grpblk_t start, ext4_grpblk_t len, void *priv); int ext4_mballoc_query_range( struct super_block *sb, ext4_group_t agno, ext4_grpblk_t start, ext4_grpblk_t end, ext4_mballoc_query_range_fn formatter, void *priv); |
8f6e39a7a
|
209 |
#endif |