diff options
author | Alex Tomas <alex@clusterfs.com> | 2008-01-29 00:19:52 -0500 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2008-01-29 00:19:52 -0500 |
commit | c9de560ded61faa5b754137b7753da252391c55a (patch) | |
tree | 2c4311377c4aa72450e27f531e198fe3e1c67db0 /include | |
parent | 1988b51e476bd097d910c9245b53f2e38aedaf0d (diff) |
ext4: Add multi block allocator for ext4
Signed-off-by: Alex Tomas <alex@clusterfs.com>
Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/ext4_fs.h | 76 | ||||
-rw-r--r-- | include/linux/ext4_fs_i.h | 4 | ||||
-rw-r--r-- | include/linux/ext4_fs_sb.h | 52 |
3 files changed, 131 insertions, 1 deletions
diff --git a/include/linux/ext4_fs.h b/include/linux/ext4_fs.h index d0b7ca99b91f..1852313fc7c7 100644 --- a/include/linux/ext4_fs.h +++ b/include/linux/ext4_fs.h | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/blkdev.h> | 20 | #include <linux/blkdev.h> |
21 | #include <linux/magic.h> | 21 | #include <linux/magic.h> |
22 | 22 | ||
23 | #include <linux/ext4_fs_i.h> | ||
24 | |||
23 | /* | 25 | /* |
24 | * The second extended filesystem constants/structures | 26 | * The second extended filesystem constants/structures |
25 | */ | 27 | */ |
@@ -51,6 +53,50 @@ | |||
51 | #define ext4_debug(f, a...) do {} while (0) | 53 | #define ext4_debug(f, a...) do {} while (0) |
52 | #endif | 54 | #endif |
53 | 55 | ||
56 | #define EXT4_MULTIBLOCK_ALLOCATOR 1 | ||
57 | |||
58 | /* prefer goal again. length */ | ||
59 | #define EXT4_MB_HINT_MERGE 1 | ||
60 | /* blocks already reserved */ | ||
61 | #define EXT4_MB_HINT_RESERVED 2 | ||
62 | /* metadata is being allocated */ | ||
63 | #define EXT4_MB_HINT_METADATA 4 | ||
64 | /* first blocks in the file */ | ||
65 | #define EXT4_MB_HINT_FIRST 8 | ||
66 | /* search for the best chunk */ | ||
67 | #define EXT4_MB_HINT_BEST 16 | ||
68 | /* data is being allocated */ | ||
69 | #define EXT4_MB_HINT_DATA 32 | ||
70 | /* don't preallocate (for tails) */ | ||
71 | #define EXT4_MB_HINT_NOPREALLOC 64 | ||
72 | /* allocate for locality group */ | ||
73 | #define EXT4_MB_HINT_GROUP_ALLOC 128 | ||
74 | /* allocate goal blocks or none */ | ||
75 | #define EXT4_MB_HINT_GOAL_ONLY 256 | ||
76 | /* goal is meaningful */ | ||
77 | #define EXT4_MB_HINT_TRY_GOAL 512 | ||
78 | |||
79 | struct ext4_allocation_request { | ||
80 | /* target inode for block we're allocating */ | ||
81 | struct inode *inode; | ||
82 | /* logical block in target inode */ | ||
83 | ext4_lblk_t logical; | ||
84 | /* phys. target (a hint) */ | ||
85 | ext4_fsblk_t goal; | ||
86 | /* the closest logical allocated block to the left */ | ||
87 | ext4_lblk_t lleft; | ||
88 | /* phys. block for ^^^ */ | ||
89 | ext4_fsblk_t pleft; | ||
90 | /* the closest logical allocated block to the right */ | ||
91 | ext4_lblk_t lright; | ||
92 | /* phys. block for ^^^ */ | ||
93 | ext4_fsblk_t pright; | ||
94 | /* how many blocks we want to allocate */ | ||
95 | unsigned long len; | ||
96 | /* flags. see above EXT4_MB_HINT_* */ | ||
97 | unsigned long flags; | ||
98 | }; | ||
99 | |||
54 | /* | 100 | /* |
55 | * Special inodes numbers | 101 | * Special inodes numbers |
56 | */ | 102 | */ |
@@ -474,6 +520,7 @@ do { \ | |||
474 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ | 520 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ |
475 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ | 521 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ |
476 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ | 522 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ |
523 | #define EXT4_MOUNT_MBALLOC 0x4000000 /* Buddy allocation support */ | ||
477 | /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ | 524 | /* Compatibility, for having both ext2_fs.h and ext4_fs.h included at once */ |
478 | #ifndef _LINUX_EXT2_FS_H | 525 | #ifndef _LINUX_EXT2_FS_H |
479 | #define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt | 526 | #define clear_opt(o, opt) o &= ~EXT4_MOUNT_##opt |
@@ -912,7 +959,7 @@ extern ext4_fsblk_t ext4_new_blocks (handle_t *handle, struct inode *inode, | |||
912 | extern ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, | 959 | extern ext4_fsblk_t ext4_new_blocks_old(handle_t *handle, struct inode *inode, |
913 | ext4_fsblk_t goal, unsigned long *count, int *errp); | 960 | ext4_fsblk_t goal, unsigned long *count, int *errp); |
914 | extern void ext4_free_blocks (handle_t *handle, struct inode *inode, | 961 | extern void ext4_free_blocks (handle_t *handle, struct inode *inode, |
915 | ext4_fsblk_t block, unsigned long count); | 962 | ext4_fsblk_t block, unsigned long count, int metadata); |
916 | extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb, | 963 | extern void ext4_free_blocks_sb (handle_t *handle, struct super_block *sb, |
917 | ext4_fsblk_t block, unsigned long count, | 964 | ext4_fsblk_t block, unsigned long count, |
918 | unsigned long *pdquot_freed_blocks); | 965 | unsigned long *pdquot_freed_blocks); |
@@ -950,6 +997,20 @@ extern unsigned long ext4_count_dirs (struct super_block *); | |||
950 | extern void ext4_check_inodes_bitmap (struct super_block *); | 997 | extern void ext4_check_inodes_bitmap (struct super_block *); |
951 | extern unsigned long ext4_count_free (struct buffer_head *, unsigned); | 998 | extern unsigned long ext4_count_free (struct buffer_head *, unsigned); |
952 | 999 | ||
1000 | /* mballoc.c */ | ||
1001 | extern long ext4_mb_stats; | ||
1002 | extern long ext4_mb_max_to_scan; | ||
1003 | extern int ext4_mb_init(struct super_block *, int); | ||
1004 | extern int ext4_mb_release(struct super_block *); | ||
1005 | extern ext4_fsblk_t ext4_mb_new_blocks(handle_t *, | ||
1006 | struct ext4_allocation_request *, int *); | ||
1007 | extern int ext4_mb_reserve_blocks(struct super_block *, int); | ||
1008 | extern void ext4_mb_discard_inode_preallocations(struct inode *); | ||
1009 | extern int __init init_ext4_mballoc(void); | ||
1010 | extern void exit_ext4_mballoc(void); | ||
1011 | extern void ext4_mb_free_blocks(handle_t *, struct inode *, | ||
1012 | unsigned long, unsigned long, int, unsigned long *); | ||
1013 | |||
953 | 1014 | ||
954 | /* inode.c */ | 1015 | /* inode.c */ |
955 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, | 1016 | int ext4_forget(handle_t *handle, int is_metadata, struct inode *inode, |
@@ -1080,6 +1141,19 @@ static inline void ext4_isize_set(struct ext4_inode *raw_inode, loff_t i_size) | |||
1080 | raw_inode->i_size_high = cpu_to_le32(i_size >> 32); | 1141 | raw_inode->i_size_high = cpu_to_le32(i_size >> 32); |
1081 | } | 1142 | } |
1082 | 1143 | ||
1144 | static inline | ||
1145 | struct ext4_group_info *ext4_get_group_info(struct super_block *sb, | ||
1146 | ext4_group_t group) | ||
1147 | { | ||
1148 | struct ext4_group_info ***grp_info; | ||
1149 | long indexv, indexh; | ||
1150 | grp_info = EXT4_SB(sb)->s_group_info; | ||
1151 | indexv = group >> (EXT4_DESC_PER_BLOCK_BITS(sb)); | ||
1152 | indexh = group & ((EXT4_DESC_PER_BLOCK(sb)) - 1); | ||
1153 | return grp_info[indexv][indexh]; | ||
1154 | } | ||
1155 | |||
1156 | |||
1083 | #define ext4_std_error(sb, errno) \ | 1157 | #define ext4_std_error(sb, errno) \ |
1084 | do { \ | 1158 | do { \ |
1085 | if ((errno)) \ | 1159 | if ((errno)) \ |
diff --git a/include/linux/ext4_fs_i.h b/include/linux/ext4_fs_i.h index 4377d249d378..d5508d3cf290 100644 --- a/include/linux/ext4_fs_i.h +++ b/include/linux/ext4_fs_i.h | |||
@@ -158,6 +158,10 @@ struct ext4_inode_info { | |||
158 | * struct timespec i_{a,c,m}time in the generic inode. | 158 | * struct timespec i_{a,c,m}time in the generic inode. |
159 | */ | 159 | */ |
160 | struct timespec i_crtime; | 160 | struct timespec i_crtime; |
161 | |||
162 | /* mballoc */ | ||
163 | struct list_head i_prealloc_list; | ||
164 | spinlock_t i_prealloc_lock; | ||
161 | }; | 165 | }; |
162 | 166 | ||
163 | #endif /* _LINUX_EXT4_FS_I */ | 167 | #endif /* _LINUX_EXT4_FS_I */ |
diff --git a/include/linux/ext4_fs_sb.h b/include/linux/ext4_fs_sb.h index 38a47ec06df9..abaae2c8cccf 100644 --- a/include/linux/ext4_fs_sb.h +++ b/include/linux/ext4_fs_sb.h | |||
@@ -91,6 +91,58 @@ struct ext4_sb_info { | |||
91 | unsigned long s_ext_blocks; | 91 | unsigned long s_ext_blocks; |
92 | unsigned long s_ext_extents; | 92 | unsigned long s_ext_extents; |
93 | #endif | 93 | #endif |
94 | |||
95 | /* for buddy allocator */ | ||
96 | struct ext4_group_info ***s_group_info; | ||
97 | struct inode *s_buddy_cache; | ||
98 | long s_blocks_reserved; | ||
99 | spinlock_t s_reserve_lock; | ||
100 | struct list_head s_active_transaction; | ||
101 | struct list_head s_closed_transaction; | ||
102 | struct list_head s_committed_transaction; | ||
103 | spinlock_t s_md_lock; | ||
104 | tid_t s_last_transaction; | ||
105 | unsigned short *s_mb_offsets, *s_mb_maxs; | ||
106 | |||
107 | /* tunables */ | ||
108 | unsigned long s_stripe; | ||
109 | unsigned long s_mb_stream_request; | ||
110 | unsigned long s_mb_max_to_scan; | ||
111 | unsigned long s_mb_min_to_scan; | ||
112 | unsigned long s_mb_stats; | ||
113 | unsigned long s_mb_order2_reqs; | ||
114 | unsigned long s_mb_group_prealloc; | ||
115 | /* where last allocation was done - for stream allocation */ | ||
116 | unsigned long s_mb_last_group; | ||
117 | unsigned long s_mb_last_start; | ||
118 | |||
119 | /* history to debug policy */ | ||
120 | struct ext4_mb_history *s_mb_history; | ||
121 | int s_mb_history_cur; | ||
122 | int s_mb_history_max; | ||
123 | int s_mb_history_num; | ||
124 | struct proc_dir_entry *s_mb_proc; | ||
125 | spinlock_t s_mb_history_lock; | ||
126 | int s_mb_history_filter; | ||
127 | |||
128 | /* stats for buddy allocator */ | ||
129 | spinlock_t s_mb_pa_lock; | ||
130 | atomic_t s_bal_reqs; /* number of reqs with len > 1 */ | ||
131 | atomic_t s_bal_success; /* we found long enough chunks */ | ||
132 | atomic_t s_bal_allocated; /* in blocks */ | ||
133 | atomic_t s_bal_ex_scanned; /* total extents scanned */ | ||
134 | atomic_t s_bal_goals; /* goal hits */ | ||
135 | atomic_t s_bal_breaks; /* too long searches */ | ||
136 | atomic_t s_bal_2orders; /* 2^order hits */ | ||
137 | spinlock_t s_bal_lock; | ||
138 | unsigned long s_mb_buddies_generated; | ||
139 | unsigned long long s_mb_generation_time; | ||
140 | atomic_t s_mb_lost_chunks; | ||
141 | atomic_t s_mb_preallocated; | ||
142 | atomic_t s_mb_discarded; | ||
143 | |||
144 | /* locality groups */ | ||
145 | struct ext4_locality_group *s_locality_groups; | ||
94 | }; | 146 | }; |
95 | 147 | ||
96 | #endif /* _LINUX_EXT4_FS_SB */ | 148 | #endif /* _LINUX_EXT4_FS_SB */ |