The JBD2 naming cleanups patch was missing a definition of JBD2_POISON_FREE
[ext4-patch-queue.git] / ext-truncate-mutex.patch
blobd586695a78bbf01d10a49981e36729634185135d
1 ext4_get_blocks_wrap take the truncate_mutex early.
3 From: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
5 When doing a migrate from ext3 to ext4 inode we need to make sure the test
6 for inode type and walking inode data happens inside lock. To make this
7 happen move truncate_mutex early before checking the i_flags.
10 This actually should enable us to remove the verify_chain().
13 Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com>
14 ---
16 fs/ext4/extents.c | 7 ++--
17 fs/ext4/inode.c | 69 +++++-------------------------------------------
18 include/linux/ext4_fs.h | 15 +++++++---
19 3 files changed, 23 insertions(+), 68 deletions(-)
22 Index: linux-2.6.23-rc6/fs/ext4/extents.c
23 ===================================================================
24 --- linux-2.6.23-rc6.orig/fs/ext4/extents.c 2007-09-18 17:18:59.000000000 -0700
25 +++ linux-2.6.23-rc6/fs/ext4/extents.c 2007-09-20 17:26:12.000000000 -0700
26 @@ -2227,6 +2227,10 @@ out:
27 return err ? err : allocated;
30 +/*
31 + * Need to be called with
32 + * mutex_lock(&EXT4_I(inode)->truncate_mutex);
33 + */
34 int ext4_ext_get_blocks(handle_t *handle, struct inode *inode,
35 ext4_fsblk_t iblock,
36 unsigned long max_blocks, struct buffer_head *bh_result,
37 @@ -2242,7 +2246,6 @@ int ext4_ext_get_blocks(handle_t *handle
38 __clear_bit(BH_New, &bh_result->b_state);
39 ext_debug("blocks %d/%lu requested for inode %u\n", (int) iblock,
40 max_blocks, (unsigned) inode->i_ino);
41 - mutex_lock(&EXT4_I(inode)->truncate_mutex);
43 /* check in cache */
44 goal = ext4_ext_in_cache(inode, iblock, &newex);
45 @@ -2416,8 +2419,6 @@ out2:
46 ext4_ext_drop_refs(path);
47 kfree(path);
49 - mutex_unlock(&EXT4_I(inode)->truncate_mutex);
51 return err ? err : allocated;
54 Index: linux-2.6.23-rc6/fs/ext4/inode.c
55 ===================================================================
56 --- linux-2.6.23-rc6.orig/fs/ext4/inode.c 2007-09-20 17:26:09.000000000 -0700
57 +++ linux-2.6.23-rc6/fs/ext4/inode.c 2007-09-20 17:26:12.000000000 -0700
58 @@ -245,13 +245,6 @@ static inline void add_chain(Indirect *p
59 p->bh = bh;
62 -static int verify_chain(Indirect *from, Indirect *to)
64 - while (from <= to && from->key == *from->p)
65 - from++;
66 - return (from > to);
69 /**
70 * ext4_block_to_path - parse the block number into array of offsets
71 * @inode: inode in question (we are only interested in its superblock)
72 @@ -346,10 +339,11 @@ static int ext4_block_to_path(struct ino
73 * (pointer to last triple returned, *@err == 0)
74 * or when it gets an IO error reading an indirect block
75 * (ditto, *@err == -EIO)
76 - * or when it notices that chain had been changed while it was reading
77 - * (ditto, *@err == -EAGAIN)
78 * or when it reads all @depth-1 indirect blocks successfully and finds
79 * the whole chain, all way to the data (returns %NULL, *err == 0).
80 + *
81 + * Need to be called with
82 + * mutex_lock(&EXT4_I(inode)->truncate_mutex)
84 static Indirect *ext4_get_branch(struct inode *inode, int depth, int *offsets,
85 Indirect chain[4], int *err)
86 @@ -367,9 +361,6 @@ static Indirect *ext4_get_branch(struct
87 bh = sb_bread(sb, le32_to_cpu(p->key));
88 if (!bh)
89 goto failure;
90 - /* Reader: pointers */
91 - if (!verify_chain(chain, p))
92 - goto changed;
93 add_chain(++p, bh, (__le32*)bh->b_data + *++offsets);
94 /* Reader: end */
95 if (!p->key)
96 @@ -377,10 +368,6 @@ static Indirect *ext4_get_branch(struct
98 return NULL;
100 -changed:
101 - brelse(bh);
102 - *err = -EAGAIN;
103 - goto no_block;
104 failure:
105 *err = -EIO;
106 no_block:
107 @@ -784,6 +771,10 @@ err_out:
108 * return > 0, # of blocks mapped or allocated.
109 * return = 0, if plain lookup failed.
110 * return < 0, error case.
113 + * Need to be called with
114 + * mutex_lock(&EXT4_I(inode)->truncate_mutex)
116 int ext4_get_blocks_handle(handle_t *handle, struct inode *inode,
117 sector_t iblock, unsigned long maxblocks,
118 @@ -821,18 +812,6 @@ int ext4_get_blocks_handle(handle_t *han
119 while (count < maxblocks && count <= blocks_to_boundary) {
120 ext4_fsblk_t blk;
122 - if (!verify_chain(chain, partial)) {
123 - /*
124 - * Indirect block might be removed by
125 - * truncate while we were reading it.
126 - * Handling of that case: forget what we've
127 - * got now. Flag the err as EAGAIN, so it
128 - * will reread.
129 - */
130 - err = -EAGAIN;
131 - count = 0;
132 - break;
134 blk = le32_to_cpu(*(chain[depth-1].p + count));
136 if (blk == first_block + count)
137 @@ -840,44 +819,13 @@ int ext4_get_blocks_handle(handle_t *han
138 else
139 break;
141 - if (err != -EAGAIN)
142 - goto got_it;
143 + goto got_it;
146 /* Next simple case - plain lookup or failed read of indirect block */
147 if (!create || err == -EIO)
148 goto cleanup;
150 - mutex_lock(&ei->truncate_mutex);
152 - /*
153 - * If the indirect block is missing while we are reading
154 - * the chain(ext4_get_branch() returns -EAGAIN err), or
155 - * if the chain has been changed after we grab the semaphore,
156 - * (either because another process truncated this branch, or
157 - * another get_block allocated this branch) re-grab the chain to see if
158 - * the request block has been allocated or not.
160 - * Since we already block the truncate/other get_block
161 - * at this point, we will have the current copy of the chain when we
162 - * splice the branch into the tree.
163 - */
164 - if (err == -EAGAIN || !verify_chain(chain, partial)) {
165 - while (partial > chain) {
166 - brelse(partial->bh);
167 - partial--;
169 - partial = ext4_get_branch(inode, depth, offsets, chain, &err);
170 - if (!partial) {
171 - count++;
172 - mutex_unlock(&ei->truncate_mutex);
173 - if (err)
174 - goto cleanup;
175 - clear_buffer_new(bh_result);
176 - goto got_it;
181 * Okay, we need to do block allocation. Lazily initialize the block
182 * allocation info here if necessary
183 @@ -919,7 +867,6 @@ int ext4_get_blocks_handle(handle_t *han
185 if (!err && extend_disksize && inode->i_size > ei->i_disksize)
186 ei->i_disksize = inode->i_size;
187 - mutex_unlock(&ei->truncate_mutex);
188 if (err)
189 goto cleanup;
191 Index: linux-2.6.23-rc6/include/linux/ext4_fs.h
192 ===================================================================
193 --- linux-2.6.23-rc6.orig/include/linux/ext4_fs.h 2007-09-20 17:26:09.000000000 -0700
194 +++ linux-2.6.23-rc6/include/linux/ext4_fs.h 2007-09-20 17:26:12.000000000 -0700
195 @@ -1099,11 +1099,18 @@ ext4_get_blocks_wrap(handle_t *handle, s
196 unsigned long max_blocks, struct buffer_head *bh,
197 int create, int extend_disksize)
199 - if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL)
200 - return ext4_ext_get_blocks(handle, inode, block, max_blocks,
201 + int retval;
202 + mutex_lock(&EXT4_I(inode)->truncate_mutex);
203 + if (EXT4_I(inode)->i_flags & EXT4_EXTENTS_FL) {
204 + retval = ext4_ext_get_blocks(handle, inode, block, max_blocks,
205 bh, create, extend_disksize);
206 - return ext4_get_blocks_handle(handle, inode, block, max_blocks, bh,
207 - create, extend_disksize);
208 + } else {
209 + retval = ext4_get_blocks_handle(handle, inode, block, max_blocks,
210 + bh, create, extend_disksize);
212 + mutex_unlock(&EXT4_I(inode)->truncate_mutex);
214 + return retval;