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