File: /usr/src/linux/fs/reiserfs/tail_conversion.c
1 /*
2 * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright details
3 */
4
5 #include <linux/config.h>
6 #include <linux/sched.h>
7 #include <linux/pagemap.h>
8 #include <linux/reiserfs_fs.h>
9 #include <linux/locks.h>
10
11 /* access to tail : when one is going to read tail it must make sure, that is not running.
12 direct2indirect and indirect2direct can not run concurrently */
13
14
15 /* Converts direct items to an unformatted node. Panics if file has no
16 tail. -ENOSPC if no disk space for conversion */
17 /* path points to first direct item of the file regarless of how many of
18 them are there */
19 int direct2indirect (struct reiserfs_transaction_handle *th, struct inode * inode,
20 struct path * path, struct buffer_head * unbh,
21 loff_t tail_offset)
22 {
23 struct super_block * sb = inode->i_sb;
24 struct buffer_head *up_to_date_bh ;
25 struct item_head * p_le_ih = PATH_PITEM_HEAD (path);
26 unsigned long total_tail = 0 ;
27 struct cpu_key end_key; /* Key to search for the last byte of the
28 converted item. */
29 struct item_head ind_ih; /* new indirect item to be inserted or
30 key of unfm pointer to be pasted */
31 int n_blk_size,
32 n_retval; /* returned value for reiserfs_insert_item and clones */
33 struct unfm_nodeinfo unfm_ptr; /* Handle on an unformatted node
34 that will be inserted in the
35 tree. */
36
37
38 sb->u.reiserfs_sb.s_direct2indirect ++;
39
40 n_blk_size = sb->s_blocksize;
41
42 /* and key to search for append or insert pointer to the new
43 unformatted node. */
44 copy_item_head (&ind_ih, p_le_ih);
45 set_le_ih_k_offset (&ind_ih, tail_offset);
46 set_le_ih_k_type (&ind_ih, TYPE_INDIRECT);
47
48 /* Set the key to search for the place for new unfm pointer */
49 make_cpu_key (&end_key, inode, tail_offset, TYPE_INDIRECT, 4);
50
51 // FIXME: we could avoid this
52 if ( search_for_position_by_key (sb, &end_key, path) == POSITION_FOUND )
53 reiserfs_panic (sb, "PAP-14030: direct2indirect: "
54 "pasted or inserted byte exists in the tree");
55
56 p_le_ih = PATH_PITEM_HEAD (path);
57
58 unfm_ptr.unfm_nodenum = cpu_to_le32 (unbh->b_blocknr);
59 unfm_ptr.unfm_freespace = 0; // ???
60
61 if ( is_statdata_le_ih (p_le_ih) ) {
62 /* Insert new indirect item. */
63 set_ih_free_space (&ind_ih, 0); /* delete at nearest future */
64 ind_ih.ih_item_len = cpu_to_le16 (UNFM_P_SIZE);
65 PATH_LAST_POSITION (path)++;
66 n_retval = reiserfs_insert_item (th, path, &end_key, &ind_ih,
67 (char *)&unfm_ptr);
68 } else {
69 /* Paste into last indirect item of an object. */
70 n_retval = reiserfs_paste_into_item(th, path, &end_key,
71 (char *)&unfm_ptr, UNFM_P_SIZE);
72 }
73 if ( n_retval ) {
74 return n_retval;
75 }
76
77 // note: from here there are two keys which have matching first
78 // three key components. They only differ by the fourth one.
79
80
81 /* Set the key to search for the direct items of the file */
82 make_cpu_key (&end_key, inode, max_reiserfs_offset (inode), TYPE_DIRECT, 4);
83
84 /* Move bytes from the direct items to the new unformatted node
85 and delete them. */
86 while (1) {
87 int tail_size;
88
89 /* end_key.k_offset is set so, that we will always have found
90 last item of the file */
91 if ( search_for_position_by_key (sb, &end_key, path) == POSITION_FOUND )
92 reiserfs_panic (sb, "PAP-14050: direct2indirect: "
93 "direct item (%k) not found", &end_key);
94 p_le_ih = PATH_PITEM_HEAD (path);
95 #ifdef CONFIG_REISERFS_CHECK
96 if (!is_direct_le_ih (p_le_ih))
97 reiserfs_panic (sb, "vs-14055: direct2indirect: "
98 "direct item expected(%k), found %h",
99 &end_key, p_le_ih);
100 #endif
101 tail_size = (le_ih_k_offset (p_le_ih) & (n_blk_size - 1))
102 + ih_item_len(p_le_ih) - 1;
103
104 /* we only send the unbh pointer if the buffer is not up to date.
105 ** this avoids overwriting good data from writepage() with old data
106 ** from the disk or buffer cache
107 */
108 if (buffer_uptodate(unbh) || Page_Uptodate(unbh->b_page)) {
109 up_to_date_bh = NULL ;
110 } else {
111 up_to_date_bh = unbh ;
112 }
113 n_retval = reiserfs_delete_item (th, path, &end_key, inode,
114 up_to_date_bh) ;
115
116 total_tail += n_retval ;
117 if (tail_size == n_retval)
118 // done: file does not have direct items anymore
119 break;
120
121 }
122 /* if we've copied bytes from disk into the page, we need to zero
123 ** out the unused part of the block (it was not up to date before)
124 ** the page is still kmapped (by whoever called reiserfs_get_block)
125 */
126 if (up_to_date_bh) {
127 unsigned pgoff = (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
128 memset(page_address(unbh->b_page) + pgoff, 0, n_blk_size - total_tail) ;
129 }
130
131 inode->u.reiserfs_i.i_first_direct_byte = U32_MAX;
132
133 return 0;
134 }
135
136
137 /* stolen from fs/buffer.c */
138 void reiserfs_unmap_buffer(struct buffer_head *bh) {
139 if (buffer_mapped(bh)) {
140 if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
141 BUG() ;
142 }
143 mark_buffer_clean(bh) ;
144 lock_buffer(bh) ;
145 clear_bit(BH_Mapped, &bh->b_state) ;
146 clear_bit(BH_Req, &bh->b_state) ;
147 clear_bit(BH_New, &bh->b_state) ;
148 unlock_buffer(bh) ;
149 }
150 }
151
152 static void
153 unmap_buffers(struct page *page, loff_t pos) {
154 struct buffer_head *bh ;
155 struct buffer_head *head ;
156 struct buffer_head *next ;
157 unsigned long tail_index ;
158 unsigned long cur_index ;
159
160 if (page) {
161 if (page->buffers) {
162 tail_index = pos & (PAGE_CACHE_SIZE - 1) ;
163 cur_index = 0 ;
164 head = page->buffers ;
165 bh = head ;
166 do {
167 next = bh->b_this_page ;
168
169 /* we want to unmap the buffers that contain the tail, and
170 ** all the buffers after it (since the tail must be at the
171 ** end of the file). We don't want to unmap file data
172 ** before the tail, since it might be dirty and waiting to
173 ** reach disk
174 */
175 cur_index += bh->b_size ;
176 if (cur_index > tail_index) {
177 reiserfs_unmap_buffer(bh) ;
178 }
179 bh = next ;
180 } while (bh != head) ;
181 }
182 }
183 }
184
185 /* this first locks inode (neither reads nor sync are permitted),
186 reads tail through page cache, insert direct item. When direct item
187 inserted successfully inode is left locked. Return value is always
188 what we expect from it (number of cut bytes). But when tail remains
189 in the unformatted node, we set mode to SKIP_BALANCING and unlock
190 inode */
191 int indirect2direct (struct reiserfs_transaction_handle *th,
192 struct inode * p_s_inode,
193 struct page *page,
194 struct path * p_s_path, /* path to the indirect item. */
195 struct cpu_key * p_s_item_key, /* Key to look for unformatted node pointer to be cut. */
196 loff_t n_new_file_size, /* New file size. */
197 char * p_c_mode)
198 {
199 struct super_block * p_s_sb = p_s_inode->i_sb;
200 struct item_head s_ih;
201 unsigned long n_block_size = p_s_sb->s_blocksize;
202 char * tail;
203 int tail_len, round_tail_len;
204 loff_t pos, pos1; /* position of first byte of the tail */
205 struct cpu_key key;
206
207 p_s_sb->u.reiserfs_sb.s_indirect2direct ++;
208
209 *p_c_mode = M_SKIP_BALANCING;
210
211 /* store item head path points to. */
212 copy_item_head (&s_ih, PATH_PITEM_HEAD(p_s_path));
213
214 tail_len = (n_new_file_size & (n_block_size - 1));
215 if (!old_format_only (p_s_sb))
216 round_tail_len = ROUND_UP (tail_len);
217 else
218 round_tail_len = tail_len;
219
220 pos = le_ih_k_offset (&s_ih) - 1 + (le16_to_cpu (s_ih.ih_item_len) / UNFM_P_SIZE - 1) * p_s_sb->s_blocksize;
221 pos1 = pos;
222
223 // we are protected by i_sem. The tail can not disapper, not
224 // append can be done either
225 // we are in truncate or packing tail in file_release
226
227 tail = (char *)kmap(page) ; /* this can schedule */
228
229 if (path_changed (&s_ih, p_s_path)) {
230 /* re-search indirect item */
231 if ( search_for_position_by_key (p_s_sb, p_s_item_key, p_s_path) == POSITION_NOT_FOUND )
232 reiserfs_panic(p_s_sb, "PAP-5520: indirect2direct: "
233 "item to be converted %k does not exist", p_s_item_key);
234 copy_item_head(&s_ih, PATH_PITEM_HEAD(p_s_path));
235 #ifdef CONFIG_REISERFS_CHECK
236 pos = le_ih_k_offset (&s_ih) - 1 +
237 (le16_to_cpu (s_ih.ih_item_len) / UNFM_P_SIZE - 1) * p_s_sb->s_blocksize;
238 if (pos != pos1)
239 reiserfs_panic (p_s_sb, "vs-5530: indirect2direct: "
240 "tail position changed while we were reading it");
241 #endif
242 }
243
244
245 /* Set direct item header to insert. */
246 make_le_item_head (&s_ih, 0, inode_items_version (p_s_inode), pos1 + 1,
247 TYPE_DIRECT, round_tail_len, 0xffff/*ih_free_space*/);
248
249 /* we want a pointer to the first byte of the tail in the page.
250 ** the page was locked and this part of the page was up to date when
251 ** indirect2direct was called, so we know the bytes are still valid
252 */
253 tail = tail + (pos & (PAGE_CACHE_SIZE - 1)) ;
254
255 PATH_LAST_POSITION(p_s_path)++;
256
257 key = *p_s_item_key;
258 set_cpu_key_k_type (&key, TYPE_DIRECT);
259 key.key_length = 4;
260 /* Insert tail as new direct item in the tree */
261 if ( reiserfs_insert_item(th, p_s_path, &key, &s_ih,
262 tail ? tail : NULL) < 0 ) {
263 /* No disk memory. So we can not convert last unformatted node
264 to the direct item. In this case we used to adjust
265 indirect items's ih_free_space. Now ih_free_space is not
266 used, it would be ideal to write zeros to corresponding
267 unformatted node. For now i_size is considered as guard for
268 going out of file size */
269 kunmap(page) ;
270 return n_block_size - round_tail_len;
271 }
272 kunmap(page) ;
273
274 /* this will invalidate all the buffers in the page after
275 ** pos1
276 */
277 unmap_buffers(page, pos1) ;
278
279 // note: we have now the same as in above direct2indirect
280 // conversion: there are two keys which have matching first three
281 // key components. They only differ by the fouhth one.
282
283 /* We have inserted new direct item and must remove last
284 unformatted node. */
285 p_s_inode->i_blocks += (p_s_sb->s_blocksize / 512);
286 *p_c_mode = M_CUT;
287
288 /* we store position of first direct item in the in-core inode */
289 //mark_file_with_tail (p_s_inode, pos1 + 1);
290 p_s_inode->u.reiserfs_i.i_first_direct_byte = pos1 + 1;
291
292 return n_block_size - round_tail_len;
293 }
294
295
296
297