aboutsummaryrefslogtreecommitdiffstats
path: root/fs/reiserfs/tail_conversion.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/reiserfs/tail_conversion.c')
-rw-r--r--fs/reiserfs/tail_conversion.c96
1 files changed, 49 insertions, 47 deletions
diff --git a/fs/reiserfs/tail_conversion.c b/fs/reiserfs/tail_conversion.c
index f8121a1147e8..d7f6e51bef2a 100644
--- a/fs/reiserfs/tail_conversion.c
+++ b/fs/reiserfs/tail_conversion.c
@@ -26,7 +26,7 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
26 converted item. */ 26 converted item. */
27 struct item_head ind_ih; /* new indirect item to be inserted or 27 struct item_head ind_ih; /* new indirect item to be inserted or
28 key of unfm pointer to be pasted */ 28 key of unfm pointer to be pasted */
29 int n_blk_size, n_retval; /* returned value for reiserfs_insert_item and clones */ 29 int blk_size, retval; /* returned value for reiserfs_insert_item and clones */
30 unp_t unfm_ptr; /* Handle on an unformatted node 30 unp_t unfm_ptr; /* Handle on an unformatted node
31 that will be inserted in the 31 that will be inserted in the
32 tree. */ 32 tree. */
@@ -35,7 +35,7 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
35 35
36 REISERFS_SB(sb)->s_direct2indirect++; 36 REISERFS_SB(sb)->s_direct2indirect++;
37 37
38 n_blk_size = sb->s_blocksize; 38 blk_size = sb->s_blocksize;
39 39
40 /* and key to search for append or insert pointer to the new 40 /* and key to search for append or insert pointer to the new
41 unformatted node. */ 41 unformatted node. */
@@ -46,11 +46,11 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
46 /* Set the key to search for the place for new unfm pointer */ 46 /* Set the key to search for the place for new unfm pointer */
47 make_cpu_key(&end_key, inode, tail_offset, TYPE_INDIRECT, 4); 47 make_cpu_key(&end_key, inode, tail_offset, TYPE_INDIRECT, 4);
48 48
49 // FIXME: we could avoid this 49 /* FIXME: we could avoid this */
50 if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) { 50 if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) {
51 reiserfs_warning(sb, "PAP-14030: direct2indirect: " 51 reiserfs_error(sb, "PAP-14030",
52 "pasted or inserted byte exists in the tree %K. " 52 "pasted or inserted byte exists in "
53 "Use fsck to repair.", &end_key); 53 "the tree %K. Use fsck to repair.", &end_key);
54 pathrelse(path); 54 pathrelse(path);
55 return -EIO; 55 return -EIO;
56 } 56 }
@@ -64,17 +64,17 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
64 set_ih_free_space(&ind_ih, 0); /* delete at nearest future */ 64 set_ih_free_space(&ind_ih, 0); /* delete at nearest future */
65 put_ih_item_len(&ind_ih, UNFM_P_SIZE); 65 put_ih_item_len(&ind_ih, UNFM_P_SIZE);
66 PATH_LAST_POSITION(path)++; 66 PATH_LAST_POSITION(path)++;
67 n_retval = 67 retval =
68 reiserfs_insert_item(th, path, &end_key, &ind_ih, inode, 68 reiserfs_insert_item(th, path, &end_key, &ind_ih, inode,
69 (char *)&unfm_ptr); 69 (char *)&unfm_ptr);
70 } else { 70 } else {
71 /* Paste into last indirect item of an object. */ 71 /* Paste into last indirect item of an object. */
72 n_retval = reiserfs_paste_into_item(th, path, &end_key, inode, 72 retval = reiserfs_paste_into_item(th, path, &end_key, inode,
73 (char *)&unfm_ptr, 73 (char *)&unfm_ptr,
74 UNFM_P_SIZE); 74 UNFM_P_SIZE);
75 } 75 }
76 if (n_retval) { 76 if (retval) {
77 return n_retval; 77 return retval;
78 } 78 }
79 // note: from here there are two keys which have matching first 79 // note: from here there are two keys which have matching first
80 // three key components. They only differ by the fourth one. 80 // three key components. They only differ by the fourth one.
@@ -92,14 +92,13 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
92 last item of the file */ 92 last item of the file */
93 if (search_for_position_by_key(sb, &end_key, path) == 93 if (search_for_position_by_key(sb, &end_key, path) ==
94 POSITION_FOUND) 94 POSITION_FOUND)
95 reiserfs_panic(sb, 95 reiserfs_panic(sb, "PAP-14050",
96 "PAP-14050: direct2indirect: "
97 "direct item (%K) not found", &end_key); 96 "direct item (%K) not found", &end_key);
98 p_le_ih = PATH_PITEM_HEAD(path); 97 p_le_ih = PATH_PITEM_HEAD(path);
99 RFALSE(!is_direct_le_ih(p_le_ih), 98 RFALSE(!is_direct_le_ih(p_le_ih),
100 "vs-14055: direct item expected(%K), found %h", 99 "vs-14055: direct item expected(%K), found %h",
101 &end_key, p_le_ih); 100 &end_key, p_le_ih);
102 tail_size = (le_ih_k_offset(p_le_ih) & (n_blk_size - 1)) 101 tail_size = (le_ih_k_offset(p_le_ih) & (blk_size - 1))
103 + ih_item_len(p_le_ih) - 1; 102 + ih_item_len(p_le_ih) - 1;
104 103
105 /* we only send the unbh pointer if the buffer is not up to date. 104 /* we only send the unbh pointer if the buffer is not up to date.
@@ -114,11 +113,11 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
114 } else { 113 } else {
115 up_to_date_bh = unbh; 114 up_to_date_bh = unbh;
116 } 115 }
117 n_retval = reiserfs_delete_item(th, path, &end_key, inode, 116 retval = reiserfs_delete_item(th, path, &end_key, inode,
118 up_to_date_bh); 117 up_to_date_bh);
119 118
120 total_tail += n_retval; 119 total_tail += retval;
121 if (tail_size == n_retval) 120 if (tail_size == retval)
122 // done: file does not have direct items anymore 121 // done: file does not have direct items anymore
123 break; 122 break;
124 123
@@ -130,7 +129,7 @@ int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
130 unsigned pgoff = 129 unsigned pgoff =
131 (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1); 130 (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
132 char *kaddr = kmap_atomic(up_to_date_bh->b_page, KM_USER0); 131 char *kaddr = kmap_atomic(up_to_date_bh->b_page, KM_USER0);
133 memset(kaddr + pgoff, 0, n_blk_size - total_tail); 132 memset(kaddr + pgoff, 0, blk_size - total_tail);
134 kunmap_atomic(kaddr, KM_USER0); 133 kunmap_atomic(kaddr, KM_USER0);
135 } 134 }
136 135
@@ -171,14 +170,18 @@ void reiserfs_unmap_buffer(struct buffer_head *bh)
171 what we expect from it (number of cut bytes). But when tail remains 170 what we expect from it (number of cut bytes). But when tail remains
172 in the unformatted node, we set mode to SKIP_BALANCING and unlock 171 in the unformatted node, we set mode to SKIP_BALANCING and unlock
173 inode */ 172 inode */
174int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_inode, struct page *page, struct treepath *p_s_path, /* path to the indirect item. */ 173int indirect2direct(struct reiserfs_transaction_handle *th,
175 const struct cpu_key *p_s_item_key, /* Key to look for unformatted node pointer to be cut. */ 174 struct inode *inode, struct page *page,
175 struct treepath *path, /* path to the indirect item. */
176 const struct cpu_key *item_key, /* Key to look for
177 * unformatted node
178 * pointer to be cut. */
176 loff_t n_new_file_size, /* New file size. */ 179 loff_t n_new_file_size, /* New file size. */
177 char *p_c_mode) 180 char *mode)
178{ 181{
179 struct super_block *p_s_sb = p_s_inode->i_sb; 182 struct super_block *sb = inode->i_sb;
180 struct item_head s_ih; 183 struct item_head s_ih;
181 unsigned long n_block_size = p_s_sb->s_blocksize; 184 unsigned long block_size = sb->s_blocksize;
182 char *tail; 185 char *tail;
183 int tail_len, round_tail_len; 186 int tail_len, round_tail_len;
184 loff_t pos, pos1; /* position of first byte of the tail */ 187 loff_t pos, pos1; /* position of first byte of the tail */
@@ -186,22 +189,22 @@ int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_in
186 189
187 BUG_ON(!th->t_trans_id); 190 BUG_ON(!th->t_trans_id);
188 191
189 REISERFS_SB(p_s_sb)->s_indirect2direct++; 192 REISERFS_SB(sb)->s_indirect2direct++;
190 193
191 *p_c_mode = M_SKIP_BALANCING; 194 *mode = M_SKIP_BALANCING;
192 195
193 /* store item head path points to. */ 196 /* store item head path points to. */
194 copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path)); 197 copy_item_head(&s_ih, PATH_PITEM_HEAD(path));
195 198
196 tail_len = (n_new_file_size & (n_block_size - 1)); 199 tail_len = (n_new_file_size & (block_size - 1));
197 if (get_inode_sd_version(p_s_inode) == STAT_DATA_V2) 200 if (get_inode_sd_version(inode) == STAT_DATA_V2)
198 round_tail_len = ROUND_UP(tail_len); 201 round_tail_len = ROUND_UP(tail_len);
199 else 202 else
200 round_tail_len = tail_len; 203 round_tail_len = tail_len;
201 204
202 pos = 205 pos =
203 le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE - 206 le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE -
204 1) * p_s_sb->s_blocksize; 207 1) * sb->s_blocksize;
205 pos1 = pos; 208 pos1 = pos;
206 209
207 // we are protected by i_mutex. The tail can not disapper, not 210 // we are protected by i_mutex. The tail can not disapper, not
@@ -210,27 +213,26 @@ int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_in
210 213
211 tail = (char *)kmap(page); /* this can schedule */ 214 tail = (char *)kmap(page); /* this can schedule */
212 215
213 if (path_changed(&s_ih, p_s_path)) { 216 if (path_changed(&s_ih, path)) {
214 /* re-search indirect item */ 217 /* re-search indirect item */
215 if (search_for_position_by_key(p_s_sb, p_s_item_key, p_s_path) 218 if (search_for_position_by_key(sb, item_key, path)
216 == POSITION_NOT_FOUND) 219 == POSITION_NOT_FOUND)
217 reiserfs_panic(p_s_sb, 220 reiserfs_panic(sb, "PAP-5520",
218 "PAP-5520: indirect2direct: "
219 "item to be converted %K does not exist", 221 "item to be converted %K does not exist",
220 p_s_item_key); 222 item_key);
221 copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path)); 223 copy_item_head(&s_ih, PATH_PITEM_HEAD(path));
222#ifdef CONFIG_REISERFS_CHECK 224#ifdef CONFIG_REISERFS_CHECK
223 pos = le_ih_k_offset(&s_ih) - 1 + 225 pos = le_ih_k_offset(&s_ih) - 1 +
224 (ih_item_len(&s_ih) / UNFM_P_SIZE - 226 (ih_item_len(&s_ih) / UNFM_P_SIZE -
225 1) * p_s_sb->s_blocksize; 227 1) * sb->s_blocksize;
226 if (pos != pos1) 228 if (pos != pos1)
227 reiserfs_panic(p_s_sb, "vs-5530: indirect2direct: " 229 reiserfs_panic(sb, "vs-5530", "tail position "
228 "tail position changed while we were reading it"); 230 "changed while we were reading it");
229#endif 231#endif
230 } 232 }
231 233
232 /* Set direct item header to insert. */ 234 /* Set direct item header to insert. */
233 make_le_item_head(&s_ih, NULL, get_inode_item_key_version(p_s_inode), 235 make_le_item_head(&s_ih, NULL, get_inode_item_key_version(inode),
234 pos1 + 1, TYPE_DIRECT, round_tail_len, 236 pos1 + 1, TYPE_DIRECT, round_tail_len,
235 0xffff /*ih_free_space */ ); 237 0xffff /*ih_free_space */ );
236 238
@@ -240,13 +242,13 @@ int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_in
240 */ 242 */
241 tail = tail + (pos & (PAGE_CACHE_SIZE - 1)); 243 tail = tail + (pos & (PAGE_CACHE_SIZE - 1));
242 244
243 PATH_LAST_POSITION(p_s_path)++; 245 PATH_LAST_POSITION(path)++;
244 246
245 key = *p_s_item_key; 247 key = *item_key;
246 set_cpu_key_k_type(&key, TYPE_DIRECT); 248 set_cpu_key_k_type(&key, TYPE_DIRECT);
247 key.key_length = 4; 249 key.key_length = 4;
248 /* Insert tail as new direct item in the tree */ 250 /* Insert tail as new direct item in the tree */
249 if (reiserfs_insert_item(th, p_s_path, &key, &s_ih, p_s_inode, 251 if (reiserfs_insert_item(th, path, &key, &s_ih, inode,
250 tail ? tail : NULL) < 0) { 252 tail ? tail : NULL) < 0) {
251 /* No disk memory. So we can not convert last unformatted node 253 /* No disk memory. So we can not convert last unformatted node
252 to the direct item. In this case we used to adjust 254 to the direct item. In this case we used to adjust
@@ -255,12 +257,12 @@ int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_in
255 unformatted node. For now i_size is considered as guard for 257 unformatted node. For now i_size is considered as guard for
256 going out of file size */ 258 going out of file size */
257 kunmap(page); 259 kunmap(page);
258 return n_block_size - round_tail_len; 260 return block_size - round_tail_len;
259 } 261 }
260 kunmap(page); 262 kunmap(page);
261 263
262 /* make sure to get the i_blocks changes from reiserfs_insert_item */ 264 /* make sure to get the i_blocks changes from reiserfs_insert_item */
263 reiserfs_update_sd(th, p_s_inode); 265 reiserfs_update_sd(th, inode);
264 266
265 // note: we have now the same as in above direct2indirect 267 // note: we have now the same as in above direct2indirect
266 // conversion: there are two keys which have matching first three 268 // conversion: there are two keys which have matching first three
@@ -268,11 +270,11 @@ int indirect2direct(struct reiserfs_transaction_handle *th, struct inode *p_s_in
268 270
269 /* We have inserted new direct item and must remove last 271 /* We have inserted new direct item and must remove last
270 unformatted node. */ 272 unformatted node. */
271 *p_c_mode = M_CUT; 273 *mode = M_CUT;
272 274
273 /* we store position of first direct item in the in-core inode */ 275 /* we store position of first direct item in the in-core inode */
274 //mark_file_with_tail (p_s_inode, pos1 + 1); 276 /* mark_file_with_tail (inode, pos1 + 1); */
275 REISERFS_I(p_s_inode)->i_first_direct_byte = pos1 + 1; 277 REISERFS_I(inode)->i_first_direct_byte = pos1 + 1;
276 278
277 return n_block_size - round_tail_len; 279 return block_size - round_tail_len;
278} 280}