tail_conversion.c (d68caa9530a8ba54f97002e02bf6a0ad2462b8c0) tail_conversion.c (ee93961be1faddf9e9a638bc519145c20f0cfeba)
1/*
2 * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright details
3 */
4
5#include <linux/time.h>
6#include <linux/pagemap.h>
7#include <linux/buffer_head.h>
8#include <linux/reiserfs_fs.h>

--- 12 unchanged lines hidden (view full) ---

21 struct super_block *sb = inode->i_sb;
22 struct buffer_head *up_to_date_bh;
23 struct item_head *p_le_ih = PATH_PITEM_HEAD(path);
24 unsigned long total_tail = 0;
25 struct cpu_key end_key; /* Key to search for the last byte of the
26 converted item. */
27 struct item_head ind_ih; /* new indirect item to be inserted or
28 key of unfm pointer to be pasted */
1/*
2 * Copyright 1999 Hans Reiser, see reiserfs/README for licensing and copyright details
3 */
4
5#include <linux/time.h>
6#include <linux/pagemap.h>
7#include <linux/buffer_head.h>
8#include <linux/reiserfs_fs.h>

--- 12 unchanged lines hidden (view full) ---

21 struct super_block *sb = inode->i_sb;
22 struct buffer_head *up_to_date_bh;
23 struct item_head *p_le_ih = PATH_PITEM_HEAD(path);
24 unsigned long total_tail = 0;
25 struct cpu_key end_key; /* Key to search for the last byte of the
26 converted item. */
27 struct item_head ind_ih; /* new indirect item to be inserted or
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
31 that will be inserted in the
32 tree. */
33
34 BUG_ON(!th->t_trans_id);
35
36 REISERFS_SB(sb)->s_direct2indirect++;
37
30 unp_t unfm_ptr; /* Handle on an unformatted node
31 that will be inserted in the
32 tree. */
33
34 BUG_ON(!th->t_trans_id);
35
36 REISERFS_SB(sb)->s_direct2indirect++;
37
38 n_blk_size = sb->s_blocksize;
38 blk_size = sb->s_blocksize;
39
40 /* and key to search for append or insert pointer to the new
41 unformatted node. */
42 copy_item_head(&ind_ih, p_le_ih);
43 set_le_ih_k_offset(&ind_ih, tail_offset);
44 set_le_ih_k_type(&ind_ih, TYPE_INDIRECT);
45
46 /* Set the key to search for the place for new unfm pointer */

--- 12 unchanged lines hidden (view full) ---

59
60 unfm_ptr = cpu_to_le32(unbh->b_blocknr);
61
62 if (is_statdata_le_ih(p_le_ih)) {
63 /* Insert new indirect item. */
64 set_ih_free_space(&ind_ih, 0); /* delete at nearest future */
65 put_ih_item_len(&ind_ih, UNFM_P_SIZE);
66 PATH_LAST_POSITION(path)++;
39
40 /* and key to search for append or insert pointer to the new
41 unformatted node. */
42 copy_item_head(&ind_ih, p_le_ih);
43 set_le_ih_k_offset(&ind_ih, tail_offset);
44 set_le_ih_k_type(&ind_ih, TYPE_INDIRECT);
45
46 /* Set the key to search for the place for new unfm pointer */

--- 12 unchanged lines hidden (view full) ---

59
60 unfm_ptr = cpu_to_le32(unbh->b_blocknr);
61
62 if (is_statdata_le_ih(p_le_ih)) {
63 /* Insert new indirect item. */
64 set_ih_free_space(&ind_ih, 0); /* delete at nearest future */
65 put_ih_item_len(&ind_ih, UNFM_P_SIZE);
66 PATH_LAST_POSITION(path)++;
67 n_retval =
67 retval =
68 reiserfs_insert_item(th, path, &end_key, &ind_ih, inode,
69 (char *)&unfm_ptr);
70 } else {
71 /* Paste into last indirect item of an object. */
68 reiserfs_insert_item(th, path, &end_key, &ind_ih, inode,
69 (char *)&unfm_ptr);
70 } else {
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,
74 UNFM_P_SIZE);
75 }
73 (char *)&unfm_ptr,
74 UNFM_P_SIZE);
75 }
76 if (n_retval) {
77 return n_retval;
76 if (retval) {
77 return retval;
78 }
79 // note: from here there are two keys which have matching first
80 // three key components. They only differ by the fourth one.
81
82 /* Set the key to search for the direct items of the file */
83 make_cpu_key(&end_key, inode, max_reiserfs_offset(inode), TYPE_DIRECT,
84 4);
85

--- 7 unchanged lines hidden (view full) ---

93 if (search_for_position_by_key(sb, &end_key, path) ==
94 POSITION_FOUND)
95 reiserfs_panic(sb, "PAP-14050",
96 "direct item (%K) not found", &end_key);
97 p_le_ih = PATH_PITEM_HEAD(path);
98 RFALSE(!is_direct_le_ih(p_le_ih),
99 "vs-14055: direct item expected(%K), found %h",
100 &end_key, p_le_ih);
78 }
79 // note: from here there are two keys which have matching first
80 // three key components. They only differ by the fourth one.
81
82 /* Set the key to search for the direct items of the file */
83 make_cpu_key(&end_key, inode, max_reiserfs_offset(inode), TYPE_DIRECT,
84 4);
85

--- 7 unchanged lines hidden (view full) ---

93 if (search_for_position_by_key(sb, &end_key, path) ==
94 POSITION_FOUND)
95 reiserfs_panic(sb, "PAP-14050",
96 "direct item (%K) not found", &end_key);
97 p_le_ih = PATH_PITEM_HEAD(path);
98 RFALSE(!is_direct_le_ih(p_le_ih),
99 "vs-14055: direct item expected(%K), found %h",
100 &end_key, p_le_ih);
101 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))
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 ** Special case: unbh->b_page will be NULL if we are coming through
108 ** DIRECT_IO handler here.
109 */
110 if (!unbh->b_page || buffer_uptodate(unbh)
111 || PageUptodate(unbh->b_page)) {
112 up_to_date_bh = NULL;
113 } else {
114 up_to_date_bh = unbh;
115 }
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 ** Special case: unbh->b_page will be NULL if we are coming through
108 ** DIRECT_IO handler here.
109 */
110 if (!unbh->b_page || buffer_uptodate(unbh)
111 || PageUptodate(unbh->b_page)) {
112 up_to_date_bh = NULL;
113 } else {
114 up_to_date_bh = unbh;
115 }
116 n_retval = reiserfs_delete_item(th, path, &end_key, inode,
116 retval = reiserfs_delete_item(th, path, &end_key, inode,
117 up_to_date_bh);
118
117 up_to_date_bh);
118
119 total_tail += n_retval;
120 if (tail_size == n_retval)
119 total_tail += retval;
120 if (tail_size == retval)
121 // done: file does not have direct items anymore
122 break;
123
124 }
125 /* if we've copied bytes from disk into the page, we need to zero
126 ** out the unused part of the block (it was not up to date before)
127 */
128 if (up_to_date_bh) {
129 unsigned pgoff =
130 (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
131 char *kaddr = kmap_atomic(up_to_date_bh->b_page, KM_USER0);
121 // done: file does not have direct items anymore
122 break;
123
124 }
125 /* if we've copied bytes from disk into the page, we need to zero
126 ** out the unused part of the block (it was not up to date before)
127 */
128 if (up_to_date_bh) {
129 unsigned pgoff =
130 (tail_offset + total_tail - 1) & (PAGE_CACHE_SIZE - 1);
131 char *kaddr = kmap_atomic(up_to_date_bh->b_page, KM_USER0);
132 memset(kaddr + pgoff, 0, n_blk_size - total_tail);
132 memset(kaddr + pgoff, 0, blk_size - total_tail);
133 kunmap_atomic(kaddr, KM_USER0);
134 }
135
136 REISERFS_I(inode)->i_first_direct_byte = U32_MAX;
137
138 return 0;
139}
140

--- 35 unchanged lines hidden (view full) ---

176 const struct cpu_key *item_key, /* Key to look for
177 * unformatted node
178 * pointer to be cut. */
179 loff_t n_new_file_size, /* New file size. */
180 char *mode)
181{
182 struct super_block *sb = inode->i_sb;
183 struct item_head s_ih;
133 kunmap_atomic(kaddr, KM_USER0);
134 }
135
136 REISERFS_I(inode)->i_first_direct_byte = U32_MAX;
137
138 return 0;
139}
140

--- 35 unchanged lines hidden (view full) ---

176 const struct cpu_key *item_key, /* Key to look for
177 * unformatted node
178 * pointer to be cut. */
179 loff_t n_new_file_size, /* New file size. */
180 char *mode)
181{
182 struct super_block *sb = inode->i_sb;
183 struct item_head s_ih;
184 unsigned long n_block_size = sb->s_blocksize;
184 unsigned long block_size = sb->s_blocksize;
185 char *tail;
186 int tail_len, round_tail_len;
187 loff_t pos, pos1; /* position of first byte of the tail */
188 struct cpu_key key;
189
190 BUG_ON(!th->t_trans_id);
191
192 REISERFS_SB(sb)->s_indirect2direct++;
193
194 *mode = M_SKIP_BALANCING;
195
196 /* store item head path points to. */
197 copy_item_head(&s_ih, PATH_PITEM_HEAD(path));
198
185 char *tail;
186 int tail_len, round_tail_len;
187 loff_t pos, pos1; /* position of first byte of the tail */
188 struct cpu_key key;
189
190 BUG_ON(!th->t_trans_id);
191
192 REISERFS_SB(sb)->s_indirect2direct++;
193
194 *mode = M_SKIP_BALANCING;
195
196 /* store item head path points to. */
197 copy_item_head(&s_ih, PATH_PITEM_HEAD(path));
198
199 tail_len = (n_new_file_size & (n_block_size - 1));
199 tail_len = (n_new_file_size & (block_size - 1));
200 if (get_inode_sd_version(inode) == STAT_DATA_V2)
201 round_tail_len = ROUND_UP(tail_len);
202 else
203 round_tail_len = tail_len;
204
205 pos =
206 le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE -
207 1) * sb->s_blocksize;

--- 44 unchanged lines hidden (view full) ---

252 tail ? tail : NULL) < 0) {
253 /* No disk memory. So we can not convert last unformatted node
254 to the direct item. In this case we used to adjust
255 indirect items's ih_free_space. Now ih_free_space is not
256 used, it would be ideal to write zeros to corresponding
257 unformatted node. For now i_size is considered as guard for
258 going out of file size */
259 kunmap(page);
200 if (get_inode_sd_version(inode) == STAT_DATA_V2)
201 round_tail_len = ROUND_UP(tail_len);
202 else
203 round_tail_len = tail_len;
204
205 pos =
206 le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE -
207 1) * sb->s_blocksize;

--- 44 unchanged lines hidden (view full) ---

252 tail ? tail : NULL) < 0) {
253 /* No disk memory. So we can not convert last unformatted node
254 to the direct item. In this case we used to adjust
255 indirect items's ih_free_space. Now ih_free_space is not
256 used, it would be ideal to write zeros to corresponding
257 unformatted node. For now i_size is considered as guard for
258 going out of file size */
259 kunmap(page);
260 return n_block_size - round_tail_len;
260 return block_size - round_tail_len;
261 }
262 kunmap(page);
263
264 /* make sure to get the i_blocks changes from reiserfs_insert_item */
265 reiserfs_update_sd(th, inode);
266
267 // note: we have now the same as in above direct2indirect
268 // conversion: there are two keys which have matching first three
269 // key components. They only differ by the fouhth one.
270
271 /* We have inserted new direct item and must remove last
272 unformatted node. */
273 *mode = M_CUT;
274
275 /* we store position of first direct item in the in-core inode */
276 /* mark_file_with_tail (inode, pos1 + 1); */
277 REISERFS_I(inode)->i_first_direct_byte = pos1 + 1;
278
261 }
262 kunmap(page);
263
264 /* make sure to get the i_blocks changes from reiserfs_insert_item */
265 reiserfs_update_sd(th, inode);
266
267 // note: we have now the same as in above direct2indirect
268 // conversion: there are two keys which have matching first three
269 // key components. They only differ by the fouhth one.
270
271 /* We have inserted new direct item and must remove last
272 unformatted node. */
273 *mode = M_CUT;
274
275 /* we store position of first direct item in the in-core inode */
276 /* mark_file_with_tail (inode, pos1 + 1); */
277 REISERFS_I(inode)->i_first_direct_byte = pos1 + 1;
278
279 return n_block_size - round_tail_len;
279 return block_size - round_tail_len;
280}
280}