aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-23 15:56:19 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-23 15:56:19 -0400
commit7f5c15160e1436a53d01f9190db11c2a3a4d788a (patch)
treeae9894ab743aca4ff4c1f50ada5a5ed665a88c21 /fs/btrfs
parentdf2ce34c8801af8e00c7f82435fcb1e4b45a2759 (diff)
Add generation number to btrfs_header, readdir fixes, hash collision fixes
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/ctree.c8
-rw-r--r--fs/btrfs/ctree.h14
-rw-r--r--fs/btrfs/dir-item.c4
-rw-r--r--fs/btrfs/disk-io.c6
-rw-r--r--fs/btrfs/super.c14
5 files changed, 32 insertions, 14 deletions
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 052434a328ec..b33a6bfaf327 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -1,6 +1,7 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include "ctree.h" 2#include "ctree.h"
3#include "disk-io.h" 3#include "disk-io.h"
4#include "transaction.h"
4 5
5static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root 6static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
6 *root, struct btrfs_path *path, int level); 7 *root, struct btrfs_path *path, int level);
@@ -39,7 +40,8 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
39 struct buffer_head *cow; 40 struct buffer_head *cow;
40 struct btrfs_node *cow_node; 41 struct btrfs_node *cow_node;
41 42
42 if (buffer_dirty(buf)) { 43 if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
44 trans->transid) {
43 *cow_ret = buf; 45 *cow_ret = buf;
44 return 0; 46 return 0;
45 } 47 }
@@ -47,6 +49,7 @@ static int btrfs_cow_block(struct btrfs_trans_handle *trans, struct btrfs_root
47 cow_node = btrfs_buffer_node(cow); 49 cow_node = btrfs_buffer_node(cow);
48 memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize); 50 memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
49 btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr); 51 btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr);
52 btrfs_set_header_generation(&cow_node->header, trans->transid);
50 *cow_ret = cow; 53 *cow_ret = cow;
51 mark_buffer_dirty(cow); 54 mark_buffer_dirty(cow);
52 btrfs_inc_ref(trans, root, buf); 55 btrfs_inc_ref(trans, root, buf);
@@ -661,6 +664,7 @@ static int insert_new_root(struct btrfs_trans_handle *trans, struct btrfs_root
661 btrfs_set_header_nritems(&c->header, 1); 664 btrfs_set_header_nritems(&c->header, 1);
662 btrfs_set_header_level(&c->header, level); 665 btrfs_set_header_level(&c->header, level);
663 btrfs_set_header_blocknr(&c->header, t->b_blocknr); 666 btrfs_set_header_blocknr(&c->header, t->b_blocknr);
667 btrfs_set_header_generation(&c->header, trans->transid);
664 btrfs_set_header_parentid(&c->header, 668 btrfs_set_header_parentid(&c->header,
665 btrfs_header_parentid(btrfs_buffer_header(root->node))); 669 btrfs_header_parentid(btrfs_buffer_header(root->node)));
666 lower = btrfs_buffer_node(path->nodes[level-1]); 670 lower = btrfs_buffer_node(path->nodes[level-1]);
@@ -750,6 +754,7 @@ static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
750 split = btrfs_buffer_node(split_buffer); 754 split = btrfs_buffer_node(split_buffer);
751 btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header)); 755 btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
752 btrfs_set_header_blocknr(&split->header, split_buffer->b_blocknr); 756 btrfs_set_header_blocknr(&split->header, split_buffer->b_blocknr);
757 btrfs_set_header_generation(&split->header, trans->transid);
753 btrfs_set_header_parentid(&split->header, 758 btrfs_set_header_parentid(&split->header,
754 btrfs_header_parentid(btrfs_buffer_header(root->node))); 759 btrfs_header_parentid(btrfs_buffer_header(root->node)));
755 mid = (c_nritems + 1) / 2; 760 mid = (c_nritems + 1) / 2;
@@ -1096,6 +1101,7 @@ static int split_leaf(struct btrfs_trans_handle *trans, struct btrfs_root
1096 } 1101 }
1097 btrfs_set_header_nritems(&right->header, nritems - mid); 1102 btrfs_set_header_nritems(&right->header, nritems - mid);
1098 btrfs_set_header_blocknr(&right->header, right_buffer->b_blocknr); 1103 btrfs_set_header_blocknr(&right->header, right_buffer->b_blocknr);
1104 btrfs_set_header_generation(&right->header, trans->transid);
1099 btrfs_set_header_level(&right->header, 0); 1105 btrfs_set_header_level(&right->header, 0);
1100 btrfs_set_header_parentid(&right->header, 1106 btrfs_set_header_parentid(&right->header,
1101 btrfs_header_parentid(btrfs_buffer_header(root->node))); 1107 btrfs_header_parentid(btrfs_buffer_header(root->node)));
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 983e3cc9ae9f..96cec6352f12 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -52,6 +52,7 @@ struct btrfs_key {
52struct btrfs_header { 52struct btrfs_header {
53 u8 fsid[16]; /* FS specific uuid */ 53 u8 fsid[16]; /* FS specific uuid */
54 __le64 blocknr; /* which block this node is supposed to live in */ 54 __le64 blocknr; /* which block this node is supposed to live in */
55 __le64 generation;
55 __le64 parentid; /* objectid of the tree root */ 56 __le64 parentid; /* objectid of the tree root */
56 __le32 csum; 57 __le32 csum;
57 __le32 ham; 58 __le32 ham;
@@ -600,6 +601,17 @@ static inline void btrfs_set_header_blocknr(struct btrfs_header *h, u64 blocknr)
600 h->blocknr = cpu_to_le64(blocknr); 601 h->blocknr = cpu_to_le64(blocknr);
601} 602}
602 603
604static inline u64 btrfs_header_generation(struct btrfs_header *h)
605{
606 return le64_to_cpu(h->generation);
607}
608
609static inline void btrfs_set_header_generation(struct btrfs_header *h,
610 u64 val)
611{
612 h->generation = cpu_to_le64(val);
613}
614
603static inline u64 btrfs_header_parentid(struct btrfs_header *h) 615static inline u64 btrfs_header_parentid(struct btrfs_header *h)
604{ 616{
605 return le64_to_cpu(h->parentid); 617 return le64_to_cpu(h->parentid);
@@ -839,7 +851,7 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
839 *root, struct btrfs_path *path, u64 dir, 851 *root, struct btrfs_path *path, u64 dir,
840 const char *name, int name_len, int mod); 852 const char *name, int name_len, int mod);
841int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path, 853int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path,
842 char *name, int name_len); 854 const char *name, int name_len);
843int btrfs_find_free_objectid(struct btrfs_trans_handle *trans, 855int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
844 struct btrfs_root *fs_root, 856 struct btrfs_root *fs_root,
845 u64 dirid, u64 *objectid); 857 u64 dirid, u64 *objectid);
diff --git a/fs/btrfs/dir-item.c b/fs/btrfs/dir-item.c
index f81cbcc83b66..c18f81797a88 100644
--- a/fs/btrfs/dir-item.c
+++ b/fs/btrfs/dir-item.c
@@ -60,8 +60,8 @@ int btrfs_lookup_dir_item(struct btrfs_trans_handle *trans, struct btrfs_root
60} 60}
61 61
62int btrfs_match_dir_item_name(struct btrfs_root *root, 62int btrfs_match_dir_item_name(struct btrfs_root *root,
63 struct btrfs_path *path, char 63 struct btrfs_path *path,
64 *name, int name_len) 64 const char *name, int name_len)
65{ 65{
66 struct btrfs_dir_item *dir_item; 66 struct btrfs_dir_item *dir_item;
67 char *name_ptr; 67 char *name_ptr;
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 2f1eb4ae4e1d..3dea757d4cbb 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -11,11 +11,7 @@ static int check_tree_block(struct btrfs_root *root, struct buffer_head *buf)
11 BUG(); 11 BUG();
12 if (root->node && btrfs_header_parentid(&node->header) != 12 if (root->node && btrfs_header_parentid(&node->header) !=
13 btrfs_header_parentid(btrfs_buffer_header(root->node))) { 13 btrfs_header_parentid(btrfs_buffer_header(root->node))) {
14 printk("block %Lu parentids don't match buf %Lu, root %Lu\n", 14 BUG();
15 buf->b_blocknr,
16 btrfs_header_parentid(&node->header),
17 btrfs_header_parentid(btrfs_buffer_header(root->node)));
18 WARN_ON(1);
19 } 15 }
20 return 0; 16 return 0;
21} 17}
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 8970e9a82156..a2db05594695 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -199,7 +199,7 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
199 btrfs_init_path(&path); 199 btrfs_init_path(&path);
200 ret = btrfs_lookup_dir_item(NULL, root, &path, dir->i_ino, name, 200 ret = btrfs_lookup_dir_item(NULL, root, &path, dir->i_ino, name,
201 namelen, 0); 201 namelen, 0);
202 if (ret) { 202 if (ret || !btrfs_match_dir_item_name(root, &path, name, namelen)) {
203 *ino = 0; 203 *ino = 0;
204 goto out; 204 goto out;
205 } 205 }
@@ -247,7 +247,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
247 int slot; 247 int slot;
248 int advance; 248 int advance;
249 unsigned char d_type = DT_UNKNOWN; 249 unsigned char d_type = DT_UNKNOWN;
250 int over; 250 int over = 0;
251 251
252 key.objectid = inode->i_ino; 252 key.objectid = inode->i_ino;
253 key.flags = 0; 253 key.flags = 0;
@@ -258,7 +258,7 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
258 if (ret < 0) { 258 if (ret < 0) {
259 goto err; 259 goto err;
260 } 260 }
261 advance = filp->f_pos > 0 && ret != 0; 261 advance = 0;
262 while(1) { 262 while(1) {
263 leaf = btrfs_buffer_leaf(path.nodes[0]); 263 leaf = btrfs_buffer_leaf(path.nodes[0]);
264 nritems = btrfs_header_nritems(&leaf->header); 264 nritems = btrfs_header_nritems(&leaf->header);
@@ -282,13 +282,17 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
282 break; 282 break;
283 if (btrfs_disk_key_type(&item->key) != BTRFS_DIR_ITEM_KEY) 283 if (btrfs_disk_key_type(&item->key) != BTRFS_DIR_ITEM_KEY)
284 continue; 284 continue;
285 if (btrfs_disk_key_offset(&item->key) < filp->f_pos)
286 continue;
285 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item); 287 di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
286 over = filldir(dirent, (const char *)(di + 1), 288 over = filldir(dirent, (const char *)(di + 1),
287 btrfs_dir_name_len(di), 289 btrfs_dir_name_len(di),
288 btrfs_disk_key_offset(&item->key), 290 btrfs_disk_key_offset(&item->key),
289 btrfs_dir_objectid(di), d_type); 291 btrfs_dir_objectid(di), d_type);
290 if (over) 292 if (over) {
293 filp->f_pos = btrfs_disk_key_offset(&item->key);
291 break; 294 break;
295 }
292 filp->f_pos = btrfs_disk_key_offset(&item->key) + 1; 296 filp->f_pos = btrfs_disk_key_offset(&item->key) + 1;
293 } 297 }
294 ret = 0; 298 ret = 0;
@@ -425,7 +429,6 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
425 dentry->d_name.name, dentry->d_name.len, 429 dentry->d_name.name, dentry->d_name.len,
426 dentry->d_parent->d_inode->i_ino, 430 dentry->d_parent->d_inode->i_ino,
427 inode->i_ino, 0); 431 inode->i_ino, 0);
428 BUG_ON(ret);
429 return ret; 432 return ret;
430} 433}
431 434
@@ -466,6 +469,7 @@ static void btrfs_write_super(struct super_block *sb)
466{ 469{
467 sb->s_dirt = 0; 470 sb->s_dirt = 0;
468printk("btrfs write_super!\n"); 471printk("btrfs write_super!\n");
472 filemap_flush(sb->s_bdev->bd_inode->i_mapping);
469} 473}
470 474
471static int btrfs_sync_fs(struct super_block *sb, int wait) 475static int btrfs_sync_fs(struct super_block *sb, int wait)