Update to indicate that we have rebased to 2.6.23-rc7
[ext4-patch-queue.git] / new-extent-function.patch
blobc0399de111c3cc2de394532e0f61fe4a1cbf9dad
1 Add some new function for searching extent tree.
3 From: Alex Tomas <alex@clusterfs.com>
5 ext4_ext_search_left
6 ext4_ext_search_right
8 These functions are used by mballoc during ext4_ext_get_blocks
9 to decided whether to merge extent information.
11 Signed-off-by: Alex Tomas <alex@clusterfs.com>
12 Signed-off-by: Andreas Dilger <adilger@clusterfs.com>
13 Signed-off-by: Johann Lombardi <johann@clusterfs.com>
14 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
15 ---
17 fs/ext4/extents.c | 142 ++++++++++++++++++++++++++++++++++++++++
18 include/linux/ext4_fs_extents.h | 2
19 2 files changed, 144 insertions(+)
22 Index: linux-2.6.23-rc5/fs/ext4/extents.c
23 ===================================================================
24 --- linux-2.6.23-rc5.orig/fs/ext4/extents.c 2007-09-12 16:14:08.000000000 -0700
25 +++ linux-2.6.23-rc5/fs/ext4/extents.c 2007-09-12 16:15:53.000000000 -0700
26 @@ -1015,6 +1015,148 @@ out:
30 + * search the closest allocated block to the left for *logical
31 + * and returns it at @logical + it's physical address at @phys
32 + * if *logical is the smallest allocated block, the function
33 + * returns 0 at @phys
34 + * return value contains 0 (success) or error code
35 + */
36 +int
37 +ext4_ext_search_left(struct inode *inode, struct ext4_ext_path *path,
38 + ext4_fsblk_t *logical, ext4_fsblk_t *phys)
40 + struct ext4_extent_idx *ix;
41 + struct ext4_extent *ex;
42 + int depth;
44 + BUG_ON(path == NULL);
45 + depth = path->p_depth;
46 + *phys = 0;
48 + if (depth == 0 && path->p_ext == NULL)
49 + return 0;
51 + /* usually extent in the path covers blocks smaller
52 + * then *logical, but it can be that extent is the
53 + * first one in the file */
55 + ex = path[depth].p_ext;
56 + if (*logical < le32_to_cpu(ex->ee_block)) {
57 + BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
58 + while (--depth >= 0) {
59 + ix = path[depth].p_idx;
60 + BUG_ON(ix != EXT_FIRST_INDEX(path[depth].p_hdr));
61 + }
62 + return 0;
63 + }
65 + BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));
67 + *logical = le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len) - 1;
68 + *phys = ext_pblock(ex) + le16_to_cpu(ex->ee_len) - 1;
69 + return 0;
72 +/*
73 + * search the closest allocated block to the right for *logical
74 + * and returns it at @logical + it's physical address at @phys
75 + * if *logical is the smallest allocated block, the function
76 + * returns 0 at @phys
77 + * return value contains 0 (success) or error code
78 + */
79 +int
80 +ext4_ext_search_right(struct inode *inode, struct ext4_ext_path *path,
81 + ext4_fsblk_t *logical, ext4_fsblk_t *phys)
83 + struct buffer_head *bh = NULL;
84 + struct ext4_extent_header *eh;
85 + struct ext4_extent_idx *ix;
86 + struct ext4_extent *ex;
87 + ext4_fsblk_t block;
88 + int depth;
90 + BUG_ON(path == NULL);
91 + depth = path->p_depth;
92 + *phys = 0;
94 + if (depth == 0 && path->p_ext == NULL)
95 + return 0;
97 + /* usually extent in the path covers blocks smaller
98 + * then *logical, but it can be that extent is the
99 + * first one in the file */
101 + ex = path[depth].p_ext;
102 + if (*logical < le32_to_cpu(ex->ee_block)) {
103 + BUG_ON(EXT_FIRST_EXTENT(path[depth].p_hdr) != ex);
104 + while (--depth >= 0) {
105 + ix = path[depth].p_idx;
106 + BUG_ON(ix != EXT_FIRST_INDEX(path[depth].p_hdr));
108 + *logical = le32_to_cpu(ex->ee_block);
109 + *phys = ext_pblock(ex);
110 + return 0;
113 + BUG_ON(*logical < le32_to_cpu(ex->ee_block) + le16_to_cpu(ex->ee_len));
115 + if (ex != EXT_LAST_EXTENT(path[depth].p_hdr)) {
116 + /* next allocated block in this leaf */
117 + ex++;
118 + *logical = le32_to_cpu(ex->ee_block);
119 + *phys = ext_pblock(ex);
120 + return 0;
123 + /* go up and search for index to the right */
124 + while (--depth >= 0) {
125 + ix = path[depth].p_idx;
126 + if (ix != EXT_LAST_INDEX(path[depth].p_hdr))
127 + break;
130 + if (depth < 0) {
131 + /* we've gone up to the root and
132 + * found no index to the right */
133 + return 0;
136 + /* we've found index to the right, let's
137 + * follow it and find the closest allocated
138 + * block to the right */
139 + ix++;
140 + block = idx_pblock(ix);
141 + while (++depth < path->p_depth) {
142 + bh = sb_bread(inode->i_sb, block);
143 + if (bh == NULL)
144 + return -EIO;
145 + eh = ext_block_hdr(bh);
146 + if (ext4_ext_check_header(inode, eh, depth)) {
147 + brelse(bh);
148 + return -EIO;
150 + ix = EXT_FIRST_INDEX(eh);
151 + block = idx_pblock(ix);
152 + brelse(bh);
155 + bh = sb_bread(inode->i_sb, block);
156 + if (bh == NULL)
157 + return -EIO;
158 + eh = ext_block_hdr(bh);
159 + if (ext4_ext_check_header(inode, eh, path->p_depth - depth)) {
160 + brelse(bh);
161 + return -EIO;
163 + ex = EXT_FIRST_EXTENT(eh);
164 + *logical = le32_to_cpu(ex->ee_block);
165 + *phys = ext_pblock(ex);
166 + brelse(bh);
167 + return 0;
172 * ext4_ext_next_allocated_block:
173 * returns allocated block in subsequent extent or EXT_MAX_BLOCK.
174 * NOTE: it considers block number from index entry as
175 Index: linux-2.6.23-rc5/include/linux/ext4_fs_extents.h
176 ===================================================================
177 --- linux-2.6.23-rc5.orig/include/linux/ext4_fs_extents.h 2007-09-11 18:15:51.000000000 -0700
178 +++ linux-2.6.23-rc5/include/linux/ext4_fs_extents.h 2007-09-12 16:14:13.000000000 -0700
179 @@ -236,5 +236,7 @@ extern int ext4_ext_insert_extent(handle
180 extern int ext4_ext_walk_space(struct inode *, unsigned long, unsigned long, ext_prepare_callback, void *);
181 extern struct ext4_ext_path * ext4_ext_find_extent(struct inode *, int, struct ext4_ext_path *);
183 +extern int ext4_ext_search_left(struct inode *, struct ext4_ext_path *, ext4_fsblk_t *, ext4_fsblk_t *);
184 +extern int ext4_ext_search_right(struct inode *, struct ext4_ext_path *, ext4_fsblk_t *, ext4_fsblk_t *);
185 #endif /* _LINUX_EXT4_EXTENTS */