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