aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-04-17 15:39:32 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-04-17 15:39:32 -0400
commit70b2befd0c8a4064715d8b340270650cc9d15af8 (patch)
tree81171607c9ddf501e5c0233dc24d20d1a5b19858
parentb18c6685810af8e6763760711aece31ccc7a8ea8 (diff)
Btrfs: rework csums and extent item ordering
Signed-off-by: Chris Mason <chris.mason@oracle.com>
-rw-r--r--fs/btrfs/ctree.c9
-rw-r--r--fs/btrfs/ctree.h17
-rw-r--r--fs/btrfs/dir-item.c28
-rw-r--r--fs/btrfs/disk-io.c2
-rw-r--r--fs/btrfs/file-item.c26
-rw-r--r--fs/btrfs/super.c123
6 files changed, 37 insertions, 168 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 43d4779abdd1..5c160c236773 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -115,14 +115,14 @@ static int comp_keys(struct btrfs_disk_key *disk, struct btrfs_key *k2)
115 return 1; 115 return 1;
116 if (k1.objectid < k2->objectid) 116 if (k1.objectid < k2->objectid)
117 return -1; 117 return -1;
118 if (k1.offset > k2->offset)
119 return 1;
120 if (k1.offset < k2->offset)
121 return -1;
122 if (k1.flags > k2->flags) 118 if (k1.flags > k2->flags)
123 return 1; 119 return 1;
124 if (k1.flags < k2->flags) 120 if (k1.flags < k2->flags)
125 return -1; 121 return -1;
122 if (k1.offset > k2->offset)
123 return 1;
124 if (k1.offset < k2->offset)
125 return -1;
126 return 0; 126 return 0;
127} 127}
128 128
@@ -1292,7 +1292,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
1292 ioff + size_diff); 1292 ioff + size_diff);
1293 } 1293 }
1294 /* shift the data */ 1294 /* shift the data */
1295printk("truncate item, new_size %u old_size %u, diff %u, bufp %p, dst, %p, num %u, old_data_start %u, data_end %u\n", new_size, old_size, size_diff, leaf, btrfs_leaf_data(leaf) + data_end + size_diff, old_data_start-data_end, old_data_start, data_end);
1296 btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) + 1295 btrfs_memmove(root, leaf, btrfs_leaf_data(leaf) +
1297 data_end + size_diff, btrfs_leaf_data(leaf) + 1296 data_end + size_diff, btrfs_leaf_data(leaf) +
1298 data_end, old_data_start + new_size - data_end); 1297 data_end, old_data_start + new_size - data_end);
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index ca3ab160f460..d75a4d5bc010 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -44,14 +44,14 @@ extern struct kmem_cache *btrfs_path_cachep;
44 */ 44 */
45struct btrfs_disk_key { 45struct btrfs_disk_key {
46 __le64 objectid; 46 __le64 objectid;
47 __le64 offset;
48 __le32 flags; 47 __le32 flags;
48 __le64 offset;
49} __attribute__ ((__packed__)); 49} __attribute__ ((__packed__));
50 50
51struct btrfs_key { 51struct btrfs_key {
52 u64 objectid; 52 u64 objectid;
53 u64 offset;
54 u32 flags; 53 u32 flags;
54 u64 offset;
55} __attribute__ ((__packed__)); 55} __attribute__ ((__packed__));
56 56
57/* 57/*
@@ -227,7 +227,6 @@ struct btrfs_file_extent_item {
227} __attribute__ ((__packed__)); 227} __attribute__ ((__packed__));
228 228
229struct btrfs_csum_item { 229struct btrfs_csum_item {
230 __le64 extent_offset;
231 u8 csum[BTRFS_CSUM_SIZE]; 230 u8 csum[BTRFS_CSUM_SIZE];
232} __attribute__ ((__packed__)); 231} __attribute__ ((__packed__));
233 232
@@ -925,17 +924,6 @@ static inline void btrfs_set_file_extent_num_blocks(struct
925 e->num_blocks = cpu_to_le64(val); 924 e->num_blocks = cpu_to_le64(val);
926} 925}
927 926
928static inline u64 btrfs_csum_extent_offset(struct btrfs_csum_item *c)
929{
930 return le64_to_cpu(c->extent_offset);
931}
932
933static inline void btrfs_set_csum_extent_offset(struct btrfs_csum_item *c,
934 u64 val)
935{
936 c->extent_offset = cpu_to_le64(val);
937}
938
939static inline u16 btrfs_device_pathlen(struct btrfs_device_item *d) 927static inline u16 btrfs_device_pathlen(struct btrfs_device_item *d)
940{ 928{
941 return le16_to_cpu(d->pathlen); 929 return le16_to_cpu(d->pathlen);
@@ -1091,7 +1079,6 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
1091int btrfs_csum_file_block(struct btrfs_trans_handle *trans, 1079int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
1092 struct btrfs_root *root, 1080 struct btrfs_root *root,
1093 u64 objectid, u64 offset, 1081 u64 objectid, u64 offset,
1094 u64 extent_offset,
1095 char *data, size_t len); 1082 char *data, size_t len);
1096int btrfs_csum_verify_file_block(struct btrfs_root *root, 1083int btrfs_csum_verify_file_block(struct btrfs_root *root,
1097 u64 objectid, u64 offset, 1084 u64 objectid, u64 offset,
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index 0ba46bc0da9a..cd4137a8b87e 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -103,7 +103,7 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
103 key.objectid = dir; 103 key.objectid = dir;
104 key.flags = 0; 104 key.flags = 0;
105 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY); 105 btrfs_set_key_type(&key, BTRFS_DIR_ITEM_KEY);
106 btrfs_set_key_overflow(&key, BTRFS_KEY_OVERFLOW_MAX - 1); 106 // btrfs_set_key_overflow(&key, BTRFS_KEY_OVERFLOW_MAX - 1);
107 ret = btrfs_name_hash(name, name_len, &key.offset); 107 ret = btrfs_name_hash(name, name_len, &key.offset);
108 BUG_ON(ret); 108 BUG_ON(ret);
109 while(1) { 109 while(1) {
@@ -146,19 +146,29 @@ int btrfs_lookup_dir_index_item(struct btrfs_trans_handle *trans,
146 int cow = mod != 0; 146 int cow = mod != 0;
147 struct btrfs_disk_key *found_key; 147 struct btrfs_disk_key *found_key;
148 struct btrfs_leaf *leaf; 148 struct btrfs_leaf *leaf;
149 int overflow = 0;
149 150
150 key.objectid = dir; 151 key.objectid = dir;
151 key.flags = 0; 152 key.flags = 0;
152 btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY); 153 btrfs_set_key_type(&key, BTRFS_DIR_INDEX_KEY);
153 btrfs_set_key_overflow(&key, BTRFS_KEY_OVERFLOW_MAX - 1);
154 key.offset = objectid; 154 key.offset = objectid;
155 ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow); 155
156 if (ret < 0) 156 while(1) {
157 return ret; 157 btrfs_set_key_overflow(&key, overflow);
158 if (ret > 0) { 158 ret = btrfs_search_slot(trans, root, &key, path, ins_len, cow);
159 if (path->slots[0] == 0) 159 if (ret < 0)
160 return 1; 160 return ret;
161 path->slots[0]--; 161 if (ret > 0) {
162 if (overflow >= BTRFS_KEY_OVERFLOW_MAX)
163 return 1;
164 overflow++;
165 btrfs_set_key_overflow(&key, overflow);
166 btrfs_release_path(root, path);
167 continue;
168 } else {
169 /* found */
170 break;
171 }
162 } 172 }
163 leaf = btrfs_buffer_leaf(path->nodes[0]); 173 leaf = btrfs_buffer_leaf(path->nodes[0]);
164 found_key = &leaf->items[path->slots[0]].key; 174 found_key = &leaf->items[path->slots[0]].key;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 06b969c14625..a2a3f529cada 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -24,7 +24,6 @@ int btrfs_insert_dev_radix(struct btrfs_root *root,
24 u64 num_blocks) 24 u64 num_blocks)
25{ 25{
26 struct dev_lookup *lookup; 26 struct dev_lookup *lookup;
27 char b[BDEVNAME_SIZE];
28 int ret; 27 int ret;
29 28
30 lookup = kmalloc(sizeof(*lookup), GFP_NOFS); 29 lookup = kmalloc(sizeof(*lookup), GFP_NOFS);
@@ -34,7 +33,6 @@ int btrfs_insert_dev_radix(struct btrfs_root *root,
34 lookup->num_blocks = num_blocks; 33 lookup->num_blocks = num_blocks;
35 lookup->bdev = bdev; 34 lookup->bdev = bdev;
36 lookup->device_id = device_id; 35 lookup->device_id = device_id;
37printk("inserting %s into dev radix %Lu %Lu\n", bdevname(bdev, b), block_start, num_blocks);
38 36
39 ret = radix_tree_insert(&root->fs_info->dev_radix, block_start + 37 ret = radix_tree_insert(&root->fs_info->dev_radix, block_start +
40 num_blocks - 1, lookup); 38 num_blocks - 1, lookup);
diff --git a/fs/btrfs/file-item.c b/fs/btrfs/file-item.c
index f49968ad0a07..ff8f3339c684 100644
--- a/fs/btrfs/file-item.c
+++ b/fs/btrfs/file-item.c
@@ -62,23 +62,19 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
62 file_key.offset = offset; 62 file_key.offset = offset;
63 file_key.flags = 0; 63 file_key.flags = 0;
64 btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); 64 btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
65printk("__lookup for %Lu\n", offset);
66 ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow); 65 ret = btrfs_search_slot(trans, root, &file_key, path, 0, cow);
67 if (ret < 0) 66 if (ret < 0)
68 goto fail; 67 goto fail;
69 leaf = btrfs_buffer_leaf(path->nodes[0]); 68 leaf = btrfs_buffer_leaf(path->nodes[0]);
70 if (ret > 0) { 69 if (ret > 0) {
71 ret = 1; 70 ret = 1;
72 if (path->slots[0] == 0) { 71 if (path->slots[0] == 0)
73printk("fail1\n");
74 goto fail; 72 goto fail;
75 }
76 path->slots[0]--; 73 path->slots[0]--;
77 btrfs_disk_key_to_cpu(&found_key, 74 btrfs_disk_key_to_cpu(&found_key,
78 &leaf->items[path->slots[0]].key); 75 &leaf->items[path->slots[0]].key);
79 if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || 76 if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY ||
80 found_key.objectid != objectid) { 77 found_key.objectid != objectid) {
81printk("fail2 type %u %Lu %Lu\n", btrfs_key_type(&found_key), found_key.objectid, objectid);
82 goto fail; 78 goto fail;
83 } 79 }
84 csum_offset = (offset - found_key.offset) >> 80 csum_offset = (offset - found_key.offset) >>
@@ -86,7 +82,6 @@ printk("fail2 type %u %Lu %Lu\n", btrfs_key_type(&found_key), found_key.objectid
86 if (csum_offset >= 82 if (csum_offset >=
87 btrfs_item_size(leaf->items + path->slots[0]) / 83 btrfs_item_size(leaf->items + path->slots[0]) /
88 sizeof(struct btrfs_csum_item)) { 84 sizeof(struct btrfs_csum_item)) {
89printk("fail3, csum offset %lu size %u\n", csum_offset, btrfs_item_size(leaf->items + path->slots[0]) / sizeof(struct btrfs_csum_item));
90 goto fail; 85 goto fail;
91 } 86 }
92 } 87 }
@@ -109,26 +104,18 @@ int btrfs_lookup_file_extent(struct btrfs_trans_handle *trans,
109 struct btrfs_key file_key; 104 struct btrfs_key file_key;
110 int ins_len = mod < 0 ? -1 : 0; 105 int ins_len = mod < 0 ? -1 : 0;
111 int cow = mod != 0; 106 int cow = mod != 0;
112 struct btrfs_csum_item *csum_item;
113 107
114 csum_item = btrfs_lookup_csum(trans, root, path, objectid, offset, 0);
115 if (IS_ERR(csum_item))
116 return PTR_ERR(csum_item);
117 file_key.objectid = objectid; 108 file_key.objectid = objectid;
118 file_key.offset = btrfs_csum_extent_offset(csum_item); 109 file_key.offset = offset;
119 file_key.flags = 0; 110 file_key.flags = 0;
120 btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY); 111 btrfs_set_key_type(&file_key, BTRFS_EXTENT_DATA_KEY);
121 btrfs_release_path(root, path);
122printk("lookup file extent searches for %Lu\n", file_key.offset);
123 ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow); 112 ret = btrfs_search_slot(trans, root, &file_key, path, ins_len, cow);
124printk("ret is %d\n", ret);
125 return ret; 113 return ret;
126} 114}
127 115
128int btrfs_csum_file_block(struct btrfs_trans_handle *trans, 116int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
129 struct btrfs_root *root, 117 struct btrfs_root *root,
130 u64 objectid, u64 offset, 118 u64 objectid, u64 offset,
131 u64 extent_offset,
132 char *data, size_t len) 119 char *data, size_t len)
133{ 120{
134 int ret; 121 int ret;
@@ -151,10 +138,8 @@ int btrfs_csum_file_block(struct btrfs_trans_handle *trans,
151 file_key.offset = offset; 138 file_key.offset = offset;
152 file_key.flags = 0; 139 file_key.flags = 0;
153 btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY); 140 btrfs_set_key_type(&file_key, BTRFS_CSUM_ITEM_KEY);
154printk("searching for csum %Lu %Lu\n", objectid, offset);
155 ret = btrfs_search_slot(trans, root, &file_key, path, 141 ret = btrfs_search_slot(trans, root, &file_key, path,
156 sizeof(struct btrfs_csum_item), 1); 142 sizeof(struct btrfs_csum_item), 1);
157printk("ret %d\n", ret);
158 if (ret < 0) 143 if (ret < 0)
159 goto fail; 144 goto fail;
160 if (ret == 0) { 145 if (ret == 0) {
@@ -167,15 +152,12 @@ printk("ret %d\n", ret);
167 path->slots[0]--; 152 path->slots[0]--;
168 leaf = btrfs_buffer_leaf(path->nodes[0]); 153 leaf = btrfs_buffer_leaf(path->nodes[0]);
169 btrfs_disk_key_to_cpu(&found_key, &leaf->items[path->slots[0]].key); 154 btrfs_disk_key_to_cpu(&found_key, &leaf->items[path->slots[0]].key);
170printk("found key %Lu %Lu %u\n", found_key.objectid, found_key.offset, found_key.flags);
171 csum_offset = (offset - found_key.offset) >> 155 csum_offset = (offset - found_key.offset) >>
172 root->fs_info->sb->s_blocksize_bits; 156 root->fs_info->sb->s_blocksize_bits;
173printk("csum_offset %Lu\n", csum_offset);
174 if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY || 157 if (btrfs_key_type(&found_key) != BTRFS_CSUM_ITEM_KEY ||
175 found_key.objectid != objectid || 158 found_key.objectid != objectid ||
176 csum_offset >= MAX_CSUM_ITEMS(root)) { 159 csum_offset >= MAX_CSUM_ITEMS(root)) {
177 btrfs_release_path(root, path); 160 btrfs_release_path(root, path);
178printk("insert1\n");
179 goto insert; 161 goto insert;
180 } 162 }
181 if (csum_offset >= btrfs_item_size(leaf->items + path->slots[0]) / 163 if (csum_offset >= btrfs_item_size(leaf->items + path->slots[0]) /
@@ -183,13 +165,11 @@ printk("insert1\n");
183 ret = btrfs_extend_item(trans, root, path, 165 ret = btrfs_extend_item(trans, root, path,
184 sizeof(struct btrfs_csum_item)); 166 sizeof(struct btrfs_csum_item));
185 BUG_ON(ret); 167 BUG_ON(ret);
186printk("item extended\n");
187 goto csum; 168 goto csum;
188 } 169 }
189 170
190insert: 171insert:
191 csum_offset = 0; 172 csum_offset = 0;
192printk("inserting item %Lu %Lu %u\n", file_key.objectid, file_key.offset, file_key.flags);
193 ret = btrfs_insert_empty_item(trans, root, path, &file_key, 173 ret = btrfs_insert_empty_item(trans, root, path, &file_key,
194 sizeof(struct btrfs_csum_item)); 174 sizeof(struct btrfs_csum_item));
195 if (ret != 0 && ret != -EEXIST) 175 if (ret != 0 && ret != -EEXIST)
@@ -201,12 +181,10 @@ csum:
201 item += csum_offset; 181 item += csum_offset;
202found: 182found:
203 ret = btrfs_csum_data(root, data, len, item->csum); 183 ret = btrfs_csum_data(root, data, len, item->csum);
204 btrfs_set_csum_extent_offset(item, extent_offset);
205 btrfs_mark_buffer_dirty(path->nodes[0]); 184 btrfs_mark_buffer_dirty(path->nodes[0]);
206fail: 185fail:
207 btrfs_release_path(root, path); 186 btrfs_release_path(root, path);
208 btrfs_free_path(path); 187 btrfs_free_path(path);
209printk("return ret %d\n", ret);
210 return ret; 188 return ret;
211} 189}
212 190
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 6a56416147e6..b2a2220d1352 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -524,7 +524,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
524 int advance; 524 int advance;
525 unsigned char d_type = DT_UNKNOWN; 525 unsigned char d_type = DT_UNKNOWN;
526 int over = 0; 526 int over = 0;
527 int key_type = BTRFS_DIR_INDEX_KEY; 527 int key_type = BTRFS_DIR_ITEM_KEY;
528 528
529 /* FIXME, use a real flag for deciding about the key type */ 529 /* FIXME, use a real flag for deciding about the key type */
530 if (root->fs_info->tree_root == root) 530 if (root->fs_info->tree_root == root)
@@ -561,9 +561,6 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
561 item = leaf->items + slot; 561 item = leaf->items + slot;
562 if (btrfs_disk_key_objectid(&item->key) != key.objectid) 562 if (btrfs_disk_key_objectid(&item->key) != key.objectid)
563 break; 563 break;
564 if (key_type == BTRFS_DIR_INDEX_KEY &&
565 btrfs_disk_key_offset(&item->key) > root->highest_inode)
566 break;
567 if (btrfs_disk_key_type(&item->key) != key_type) 564 if (btrfs_disk_key_type(&item->key) != key_type)
568 continue; 565 continue;
569 if (btrfs_disk_key_offset(&item->key) < filp->f_pos) 566 if (btrfs_disk_key_offset(&item->key) < filp->f_pos)
@@ -1119,7 +1116,6 @@ allocate:
1119out: 1116out:
1120 btrfs_release_path(root, path); 1117 btrfs_release_path(root, path);
1121 btrfs_free_path(path); 1118 btrfs_free_path(path);
1122printk("mapping iblock %lu to %lu\n", iblock, result->b_blocknr);
1123 if (trans) 1119 if (trans)
1124 btrfs_end_transaction(trans, root); 1120 btrfs_end_transaction(trans, root);
1125 return err; 1121 return err;
@@ -1233,7 +1229,6 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
1233 struct file *file, 1229 struct file *file,
1234 struct page **pages, 1230 struct page **pages,
1235 size_t num_pages, 1231 size_t num_pages,
1236 u64 extent_offset,
1237 loff_t pos, 1232 loff_t pos,
1238 size_t write_bytes) 1233 size_t write_bytes)
1239{ 1234{
@@ -1253,7 +1248,6 @@ static int dirty_and_release_pages(struct btrfs_trans_handle *trans,
1253 trans = btrfs_start_transaction(root, 1); 1248 trans = btrfs_start_transaction(root, 1);
1254 btrfs_csum_file_block(trans, root, inode->i_ino, 1249 btrfs_csum_file_block(trans, root, inode->i_ino,
1255 pages[i]->index << PAGE_CACHE_SHIFT, 1250 pages[i]->index << PAGE_CACHE_SHIFT,
1256 extent_offset,
1257 kmap(pages[i]), PAGE_CACHE_SIZE); 1251 kmap(pages[i]), PAGE_CACHE_SIZE);
1258 kunmap(pages[i]); 1252 kunmap(pages[i]);
1259 SetPageChecked(pages[i]); 1253 SetPageChecked(pages[i]);
@@ -1275,86 +1269,6 @@ failed:
1275 return err; 1269 return err;
1276} 1270}
1277 1271
1278static int drop_csums(struct btrfs_trans_handle *trans,
1279 struct btrfs_root *root,
1280 struct inode *inode,
1281 u64 start, u64 end)
1282{
1283 struct btrfs_path *path;
1284 struct btrfs_leaf *leaf;
1285 struct btrfs_key key;
1286 int slot;
1287 struct btrfs_csum_item *item;
1288 char *old_block = NULL;
1289 u64 cur = start;
1290 u64 found_end;
1291 u64 num_csums;
1292 u64 item_size;
1293 int ret;
1294
1295 path = btrfs_alloc_path();
1296 if (!path)
1297 return -ENOMEM;
1298 while(cur < end) {
1299 item = btrfs_lookup_csum(trans, root, path,
1300 inode->i_ino, cur, 1);
1301 if (IS_ERR(item)) {
1302 cur += root->blocksize;
1303 continue;
1304 }
1305 leaf = btrfs_buffer_leaf(path->nodes[0]);
1306 slot = path->slots[0];
1307 btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key);
1308 item_size = btrfs_item_size(leaf->items + slot);
1309 num_csums = item_size / sizeof(struct btrfs_csum_item);
1310 found_end = key.offset + (num_csums << inode->i_blkbits);
1311 cur = found_end;
1312
1313 if (found_end > end) {
1314 char *src;
1315 old_block = kmalloc(root->blocksize, GFP_NOFS);
1316 src = btrfs_item_ptr(leaf, slot, char);
1317 memcpy(old_block, src, item_size);
1318 }
1319 if (key.offset < start) {
1320 u64 new_size = (start - key.offset) >>
1321 inode->i_blkbits;
1322 new_size *= sizeof(struct btrfs_csum_item);
1323 ret = btrfs_truncate_item(trans, root, path, new_size);
1324 BUG_ON(ret);
1325 } else {
1326 btrfs_del_item(trans, root, path);
1327 }
1328 btrfs_release_path(root, path);
1329 if (found_end > end) {
1330 char *dst;
1331 int i;
1332 int new_size;
1333
1334 num_csums = (found_end - end) >> inode->i_blkbits;
1335 new_size = num_csums * sizeof(struct btrfs_csum_item);
1336 key.offset = end;
1337 ret = btrfs_insert_empty_item(trans, root, path,
1338 &key, new_size);
1339 BUG_ON(ret);
1340 dst = btrfs_item_ptr(btrfs_buffer_leaf(path->nodes[0]),
1341 path->slots[0], char);
1342 memcpy(dst, old_block + item_size - new_size,
1343 new_size);
1344 item = (struct btrfs_csum_item *)dst;
1345 for (i = 0; i < num_csums; i++) {
1346 btrfs_set_csum_extent_offset(item, end);
1347 item++;
1348 }
1349 mark_buffer_dirty(path->nodes[0]);
1350 kfree(old_block);
1351 break;
1352 }
1353 }
1354 btrfs_free_path(path);
1355 return 0;
1356}
1357
1358static int drop_extents(struct btrfs_trans_handle *trans, 1272static int drop_extents(struct btrfs_trans_handle *trans,
1359 struct btrfs_root *root, 1273 struct btrfs_root *root,
1360 struct inode *inode, 1274 struct inode *inode,
@@ -1376,12 +1290,16 @@ static int drop_extents(struct btrfs_trans_handle *trans,
1376 if (!path) 1290 if (!path)
1377 return -ENOMEM; 1291 return -ENOMEM;
1378search_again: 1292search_again:
1379printk("drop extent inode %lu start %Lu end %Lu\n", inode->i_ino, start, end);
1380 ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino, 1293 ret = btrfs_lookup_file_extent(trans, root, path, inode->i_ino,
1381 search_start, -1); 1294 search_start, -1);
1382 if (ret != 0) { 1295 if (ret < 0)
1383printk("lookup failed\n");
1384 goto out; 1296 goto out;
1297 if (ret > 0) {
1298 if (path->slots[0] == 0) {
1299 ret = -ENOENT;
1300 goto out;
1301 }
1302 path->slots[0]--;
1385 } 1303 }
1386 while(1) { 1304 while(1) {
1387 keep = 0; 1305 keep = 0;
@@ -1390,14 +1308,11 @@ printk("lookup failed\n");
1390 slot = path->slots[0]; 1308 slot = path->slots[0];
1391 btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key); 1309 btrfs_disk_key_to_cpu(&key, &leaf->items[slot].key);
1392 1310
1393printk("found key %Lu %Lu %u\n", key.objectid, key.offset, key.flags);
1394
1395 extent = btrfs_item_ptr(leaf, slot, 1311 extent = btrfs_item_ptr(leaf, slot,
1396 struct btrfs_file_extent_item); 1312 struct btrfs_file_extent_item);
1397 extent_end = key.offset + 1313 extent_end = key.offset +
1398 (btrfs_file_extent_num_blocks(extent) << 1314 (btrfs_file_extent_num_blocks(extent) <<
1399 inode->i_blkbits); 1315 inode->i_blkbits);
1400printk("extent end is %Lu\n", extent_end);
1401 if (key.offset >= end || key.objectid != inode->i_ino) { 1316 if (key.offset >= end || key.objectid != inode->i_ino) {
1402 ret = 0; 1317 ret = 0;
1403 goto out; 1318 goto out;
@@ -1420,16 +1335,12 @@ printk("extent end is %Lu\n", extent_end);
1420 keep = 1; 1335 keep = 1;
1421 WARN_ON(start & (root->blocksize - 1)); 1336 WARN_ON(start & (root->blocksize - 1));
1422 new_num = (start - key.offset) >> inode->i_blkbits; 1337 new_num = (start - key.offset) >> inode->i_blkbits;
1423printk("truncating existing extent, was %Lu ", btrfs_file_extent_num_blocks(extent));
1424 btrfs_set_file_extent_num_blocks(extent, new_num); 1338 btrfs_set_file_extent_num_blocks(extent, new_num);
1425printk("now %Lu\n", btrfs_file_extent_num_blocks(extent));
1426
1427 mark_buffer_dirty(path->nodes[0]); 1339 mark_buffer_dirty(path->nodes[0]);
1428 } 1340 }
1429 if (!keep) { 1341 if (!keep) {
1430 u64 disk_blocknr; 1342 u64 disk_blocknr;
1431 u64 disk_num_blocks; 1343 u64 disk_num_blocks;
1432printk("del old\n");
1433 disk_blocknr = btrfs_file_extent_disk_blocknr(extent); 1344 disk_blocknr = btrfs_file_extent_disk_blocknr(extent);
1434 disk_num_blocks = 1345 disk_num_blocks =
1435 btrfs_file_extent_disk_num_blocks(extent); 1346 btrfs_file_extent_disk_num_blocks(extent);
@@ -1454,15 +1365,12 @@ printk("del old\n");
1454 if (bookend) { 1365 if (bookend) {
1455 /* create bookend */ 1366 /* create bookend */
1456 struct btrfs_key ins; 1367 struct btrfs_key ins;
1457printk("bookend! extent end %Lu\n", extent_end);
1458 ins.objectid = inode->i_ino; 1368 ins.objectid = inode->i_ino;
1459 ins.offset = end; 1369 ins.offset = end;
1460 ins.flags = 0; 1370 ins.flags = 0;
1461 btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY); 1371 btrfs_set_key_type(&ins, BTRFS_EXTENT_DATA_KEY);
1462 1372
1463 btrfs_release_path(root, path); 1373 btrfs_release_path(root, path);
1464 ret = drop_csums(trans, root, inode, start, end);
1465 BUG_ON(ret);
1466 ret = btrfs_insert_empty_item(trans, root, path, &ins, 1374 ret = btrfs_insert_empty_item(trans, root, path, &ins,
1467 sizeof(*extent)); 1375 sizeof(*extent));
1468 BUG_ON(ret); 1376 BUG_ON(ret);
@@ -1486,10 +1394,9 @@ printk("bookend! extent end %Lu\n", extent_end);
1486 1394
1487 btrfs_set_file_extent_generation(extent, 1395 btrfs_set_file_extent_generation(extent,
1488 btrfs_file_extent_generation(&old)); 1396 btrfs_file_extent_generation(&old));
1489printk("new bookend at offset %Lu, file_extent_offset %Lu, file_extent_num_blocks %Lu\n", end, btrfs_file_extent_offset(extent), btrfs_file_extent_num_blocks(extent));
1490 btrfs_mark_buffer_dirty(path->nodes[0]); 1397 btrfs_mark_buffer_dirty(path->nodes[0]);
1491 ret = 0; 1398 ret = 0;
1492 goto out_nocsum; 1399 goto out;
1493 } 1400 }
1494next_leaf: 1401next_leaf:
1495 if (slot >= btrfs_header_nritems(&leaf->header) - 1) { 1402 if (slot >= btrfs_header_nritems(&leaf->header) - 1) {
@@ -1504,10 +1411,6 @@ next_leaf:
1504 } 1411 }
1505 1412
1506out: 1413out:
1507 ret = drop_csums(trans, root, inode, start, end);
1508 BUG_ON(ret);
1509
1510out_nocsum:
1511 btrfs_free_path(path); 1414 btrfs_free_path(path);
1512 return ret; 1415 return ret;
1513} 1416}
@@ -1556,7 +1459,6 @@ static int prepare_pages(struct btrfs_root *root,
1556 head = page_buffers(pages[i]); 1459 head = page_buffers(pages[i]);
1557 bh = head; 1460 bh = head;
1558 do { 1461 do {
1559printk("mapping page %lu to block %Lu\n", pages[i]->index, alloc_extent_start);
1560 err = btrfs_map_bh_to_logical(root, bh, 1462 err = btrfs_map_bh_to_logical(root, bh,
1561 alloc_extent_start); 1463 alloc_extent_start);
1562 BUG_ON(err); 1464 BUG_ON(err);
@@ -1597,7 +1499,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1597 u64 start_pos; 1499 u64 start_pos;
1598 u64 num_blocks; 1500 u64 num_blocks;
1599 u64 alloc_extent_start; 1501 u64 alloc_extent_start;
1600 u64 orig_extent_start;
1601 struct btrfs_trans_handle *trans; 1502 struct btrfs_trans_handle *trans;
1602 struct btrfs_key ins; 1503 struct btrfs_key ins;
1603 1504
@@ -1640,7 +1541,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1640 (pos + count + root->blocksize -1) & 1541 (pos + count + root->blocksize -1) &
1641 ~(root->blocksize - 1)); 1542 ~(root->blocksize - 1));
1642 } 1543 }
1643 orig_extent_start = start_pos;
1644 ret = btrfs_alloc_extent(trans, root, num_blocks, 1, 1544 ret = btrfs_alloc_extent(trans, root, num_blocks, 1,
1645 (u64)-1, &ins); 1545 (u64)-1, &ins);
1646 BUG_ON(ret); 1546 BUG_ON(ret);
@@ -1656,7 +1556,6 @@ static ssize_t btrfs_file_write(struct file *file, const char __user *buf,
1656 size_t write_bytes = min(count, PAGE_CACHE_SIZE - offset); 1556 size_t write_bytes = min(count, PAGE_CACHE_SIZE - offset);
1657 size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >> 1557 size_t num_pages = (write_bytes + PAGE_CACHE_SIZE - 1) >>
1658 PAGE_CACHE_SHIFT; 1558 PAGE_CACHE_SHIFT;
1659printk("num_pages is %lu\n", num_pages);
1660 1559
1661 memset(pages, 0, sizeof(pages)); 1560 memset(pages, 0, sizeof(pages));
1662 ret = prepare_pages(root, file, pages, num_pages, 1561 ret = prepare_pages(root, file, pages, num_pages,
@@ -1670,10 +1569,8 @@ printk("num_pages is %lu\n", num_pages);
1670 write_bytes, pages, buf); 1569 write_bytes, pages, buf);
1671 BUG_ON(ret); 1570 BUG_ON(ret);
1672 1571
1673printk("2num_pages is %lu\n", num_pages);
1674 ret = dirty_and_release_pages(NULL, root, file, pages, 1572 ret = dirty_and_release_pages(NULL, root, file, pages,
1675 num_pages, orig_extent_start, 1573 num_pages, pos, write_bytes);
1676 pos, write_bytes);
1677 BUG_ON(ret); 1574 BUG_ON(ret);
1678 btrfs_drop_pages(pages, num_pages); 1575 btrfs_drop_pages(pages, num_pages);
1679 1576