0001
0002
0003
0004
0005
0006
0007 #include <linux/time.h>
0008 #include <linux/pagemap.h>
0009 #include <linux/buffer_head.h>
0010 #include "reiserfs.h"
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 int direct2indirect(struct reiserfs_transaction_handle *th, struct inode *inode,
0026 struct treepath *path, struct buffer_head *unbh,
0027 loff_t tail_offset)
0028 {
0029 struct super_block *sb = inode->i_sb;
0030 struct buffer_head *up_to_date_bh;
0031 struct item_head *p_le_ih = tp_item_head(path);
0032 unsigned long total_tail = 0;
0033
0034
0035 struct cpu_key end_key;
0036
0037
0038
0039
0040
0041 struct item_head ind_ih;
0042 int blk_size;
0043
0044 int retval;
0045
0046 unp_t unfm_ptr;
0047
0048 BUG_ON(!th->t_trans_id);
0049
0050 REISERFS_SB(sb)->s_direct2indirect++;
0051
0052 blk_size = sb->s_blocksize;
0053
0054
0055
0056
0057
0058 copy_item_head(&ind_ih, p_le_ih);
0059 set_le_ih_k_offset(&ind_ih, tail_offset);
0060 set_le_ih_k_type(&ind_ih, TYPE_INDIRECT);
0061
0062
0063 make_cpu_key(&end_key, inode, tail_offset, TYPE_INDIRECT, 4);
0064
0065
0066 if (search_for_position_by_key(sb, &end_key, path) == POSITION_FOUND) {
0067 reiserfs_error(sb, "PAP-14030",
0068 "pasted or inserted byte exists in "
0069 "the tree %K. Use fsck to repair.", &end_key);
0070 pathrelse(path);
0071 return -EIO;
0072 }
0073
0074 p_le_ih = tp_item_head(path);
0075
0076 unfm_ptr = cpu_to_le32(unbh->b_blocknr);
0077
0078 if (is_statdata_le_ih(p_le_ih)) {
0079
0080 set_ih_free_space(&ind_ih, 0);
0081 put_ih_item_len(&ind_ih, UNFM_P_SIZE);
0082 PATH_LAST_POSITION(path)++;
0083 retval =
0084 reiserfs_insert_item(th, path, &end_key, &ind_ih, inode,
0085 (char *)&unfm_ptr);
0086 } else {
0087
0088 retval = reiserfs_paste_into_item(th, path, &end_key, inode,
0089 (char *)&unfm_ptr,
0090 UNFM_P_SIZE);
0091 }
0092 if (retval) {
0093 return retval;
0094 }
0095
0096
0097
0098
0099
0100
0101 make_cpu_key(&end_key, inode, max_reiserfs_offset(inode), TYPE_DIRECT,
0102 4);
0103
0104
0105
0106
0107
0108 while (1) {
0109 int tail_size;
0110
0111
0112
0113
0114
0115 if (search_for_position_by_key(sb, &end_key, path) ==
0116 POSITION_FOUND)
0117 reiserfs_panic(sb, "PAP-14050",
0118 "direct item (%K) not found", &end_key);
0119 p_le_ih = tp_item_head(path);
0120 RFALSE(!is_direct_le_ih(p_le_ih),
0121 "vs-14055: direct item expected(%K), found %h",
0122 &end_key, p_le_ih);
0123 tail_size = (le_ih_k_offset(p_le_ih) & (blk_size - 1))
0124 + ih_item_len(p_le_ih) - 1;
0125
0126
0127
0128
0129
0130
0131
0132
0133 if (!unbh->b_page || buffer_uptodate(unbh)
0134 || PageUptodate(unbh->b_page)) {
0135 up_to_date_bh = NULL;
0136 } else {
0137 up_to_date_bh = unbh;
0138 }
0139 retval = reiserfs_delete_item(th, path, &end_key, inode,
0140 up_to_date_bh);
0141
0142 total_tail += retval;
0143
0144
0145 if (tail_size == retval)
0146 break;
0147
0148 }
0149
0150
0151
0152
0153 if (up_to_date_bh) {
0154 unsigned pgoff =
0155 (tail_offset + total_tail - 1) & (PAGE_SIZE - 1);
0156 char *kaddr = kmap_atomic(up_to_date_bh->b_page);
0157 memset(kaddr + pgoff, 0, blk_size - total_tail);
0158 kunmap_atomic(kaddr);
0159 }
0160
0161 REISERFS_I(inode)->i_first_direct_byte = U32_MAX;
0162
0163 return 0;
0164 }
0165
0166
0167 void reiserfs_unmap_buffer(struct buffer_head *bh)
0168 {
0169 lock_buffer(bh);
0170 if (buffer_journaled(bh) || buffer_journal_dirty(bh)) {
0171 BUG();
0172 }
0173 clear_buffer_dirty(bh);
0174
0175
0176
0177
0178
0179 if ((!list_empty(&bh->b_assoc_buffers) || bh->b_private) && bh->b_page) {
0180 struct inode *inode = bh->b_page->mapping->host;
0181 struct reiserfs_journal *j = SB_JOURNAL(inode->i_sb);
0182 spin_lock(&j->j_dirty_buffers_lock);
0183 list_del_init(&bh->b_assoc_buffers);
0184 reiserfs_free_jh(bh);
0185 spin_unlock(&j->j_dirty_buffers_lock);
0186 }
0187 clear_buffer_mapped(bh);
0188 clear_buffer_req(bh);
0189 clear_buffer_new(bh);
0190 bh->b_bdev = NULL;
0191 unlock_buffer(bh);
0192 }
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202 int indirect2direct(struct reiserfs_transaction_handle *th,
0203 struct inode *inode, struct page *page,
0204 struct treepath *path,
0205 const struct cpu_key *item_key,
0206
0207
0208 loff_t n_new_file_size,
0209 char *mode)
0210 {
0211 struct super_block *sb = inode->i_sb;
0212 struct item_head s_ih;
0213 unsigned long block_size = sb->s_blocksize;
0214 char *tail;
0215 int tail_len, round_tail_len;
0216 loff_t pos, pos1;
0217 struct cpu_key key;
0218
0219 BUG_ON(!th->t_trans_id);
0220
0221 REISERFS_SB(sb)->s_indirect2direct++;
0222
0223 *mode = M_SKIP_BALANCING;
0224
0225
0226 copy_item_head(&s_ih, tp_item_head(path));
0227
0228 tail_len = (n_new_file_size & (block_size - 1));
0229 if (get_inode_sd_version(inode) == STAT_DATA_V2)
0230 round_tail_len = ROUND_UP(tail_len);
0231 else
0232 round_tail_len = tail_len;
0233
0234 pos =
0235 le_ih_k_offset(&s_ih) - 1 + (ih_item_len(&s_ih) / UNFM_P_SIZE -
0236 1) * sb->s_blocksize;
0237 pos1 = pos;
0238
0239
0240
0241
0242
0243
0244
0245 tail = (char *)kmap(page);
0246
0247 if (path_changed(&s_ih, path)) {
0248
0249 if (search_for_position_by_key(sb, item_key, path)
0250 == POSITION_NOT_FOUND)
0251 reiserfs_panic(sb, "PAP-5520",
0252 "item to be converted %K does not exist",
0253 item_key);
0254 copy_item_head(&s_ih, tp_item_head(path));
0255 #ifdef CONFIG_REISERFS_CHECK
0256 pos = le_ih_k_offset(&s_ih) - 1 +
0257 (ih_item_len(&s_ih) / UNFM_P_SIZE -
0258 1) * sb->s_blocksize;
0259 if (pos != pos1)
0260 reiserfs_panic(sb, "vs-5530", "tail position "
0261 "changed while we were reading it");
0262 #endif
0263 }
0264
0265
0266 make_le_item_head(&s_ih, NULL, get_inode_item_key_version(inode),
0267 pos1 + 1, TYPE_DIRECT, round_tail_len,
0268 0xffff );
0269
0270
0271
0272
0273
0274
0275 tail = tail + (pos & (PAGE_SIZE - 1));
0276
0277 PATH_LAST_POSITION(path)++;
0278
0279 key = *item_key;
0280 set_cpu_key_k_type(&key, TYPE_DIRECT);
0281 key.key_length = 4;
0282
0283 if (reiserfs_insert_item(th, path, &key, &s_ih, inode,
0284 tail ? tail : NULL) < 0) {
0285
0286
0287
0288
0289
0290
0291
0292
0293 kunmap(page);
0294 return block_size - round_tail_len;
0295 }
0296 kunmap(page);
0297
0298
0299 reiserfs_update_sd(th, inode);
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311 *mode = M_CUT;
0312
0313
0314
0315 REISERFS_I(inode)->i_first_direct_byte = pos1 + 1;
0316
0317 return block_size - round_tail_len;
0318 }