#include <linux/module.h>
 #include "ctree.h"
 #include "disk-io.h"
+#include "transaction.h"
 
 static int split_node(struct btrfs_trans_handle *trans, struct btrfs_root
                      *root, struct btrfs_path *path, int level);
        struct buffer_head *cow;
        struct btrfs_node *cow_node;
 
-       if (buffer_dirty(buf)) {
+       if (btrfs_header_generation(btrfs_buffer_header(buf)) ==
+                                   trans->transid) {
                *cow_ret = buf;
                return 0;
        }
        cow_node = btrfs_buffer_node(cow);
        memcpy(cow_node, btrfs_buffer_node(buf), root->blocksize);
        btrfs_set_header_blocknr(&cow_node->header, cow->b_blocknr);
+       btrfs_set_header_generation(&cow_node->header, trans->transid);
        *cow_ret = cow;
        mark_buffer_dirty(cow);
        btrfs_inc_ref(trans, root, buf);
        btrfs_set_header_nritems(&c->header, 1);
        btrfs_set_header_level(&c->header, level);
        btrfs_set_header_blocknr(&c->header, t->b_blocknr);
+       btrfs_set_header_generation(&c->header, trans->transid);
        btrfs_set_header_parentid(&c->header,
              btrfs_header_parentid(btrfs_buffer_header(root->node)));
        lower = btrfs_buffer_node(path->nodes[level-1]);
        split = btrfs_buffer_node(split_buffer);
        btrfs_set_header_flags(&split->header, btrfs_header_flags(&c->header));
        btrfs_set_header_blocknr(&split->header, split_buffer->b_blocknr);
+       btrfs_set_header_generation(&split->header, trans->transid);
        btrfs_set_header_parentid(&split->header,
              btrfs_header_parentid(btrfs_buffer_header(root->node)));
        mid = (c_nritems + 1) / 2;
        }
        btrfs_set_header_nritems(&right->header, nritems - mid);
        btrfs_set_header_blocknr(&right->header, right_buffer->b_blocknr);
+       btrfs_set_header_generation(&right->header, trans->transid);
        btrfs_set_header_level(&right->header, 0);
        btrfs_set_header_parentid(&right->header,
              btrfs_header_parentid(btrfs_buffer_header(root->node)));
 
 struct btrfs_header {
        u8 fsid[16]; /* FS specific uuid */
        __le64 blocknr; /* which block this node is supposed to live in */
+       __le64 generation;
        __le64 parentid; /* objectid of the tree root */
        __le32 csum;
        __le32 ham;
        h->blocknr = cpu_to_le64(blocknr);
 }
 
+static inline u64 btrfs_header_generation(struct btrfs_header *h)
+{
+       return le64_to_cpu(h->generation);
+}
+
+static inline void btrfs_set_header_generation(struct btrfs_header *h,
+                                              u64 val)
+{
+       h->generation = cpu_to_le64(val);
+}
+
 static inline u64 btrfs_header_parentid(struct btrfs_header *h)
 {
        return le64_to_cpu(h->parentid);
                          *root, struct btrfs_path *path, u64 dir,
                          const char *name, int name_len, int mod);
 int btrfs_match_dir_item_name(struct btrfs_root *root, struct btrfs_path *path,
-                             char *name, int name_len);
+                             const char *name, int name_len);
 int btrfs_find_free_objectid(struct btrfs_trans_handle *trans,
                             struct btrfs_root *fs_root,
                             u64 dirid, u64 *objectid);
 
 }
 
 int btrfs_match_dir_item_name(struct btrfs_root *root,
-                             struct btrfs_path *path, char
-                             *name, int name_len)
+                             struct btrfs_path *path,
+                             const char *name, int name_len)
 {
        struct btrfs_dir_item *dir_item;
        char *name_ptr;
 
                BUG();
        if (root->node && btrfs_header_parentid(&node->header) !=
            btrfs_header_parentid(btrfs_buffer_header(root->node))) {
-               printk("block %Lu parentids don't match buf %Lu, root %Lu\n",
-                      buf->b_blocknr,
-                      btrfs_header_parentid(&node->header),
-                      btrfs_header_parentid(btrfs_buffer_header(root->node)));
-               WARN_ON(1);
+               BUG();
        }
        return 0;
 }
 
        btrfs_init_path(&path);
        ret = btrfs_lookup_dir_item(NULL, root, &path, dir->i_ino, name,
                                    namelen, 0);
-       if (ret) {
+       if (ret || !btrfs_match_dir_item_name(root, &path, name, namelen)) {
                *ino = 0;
                goto out;
        }
        int slot;
        int advance;
        unsigned char d_type = DT_UNKNOWN;
-       int over;
+       int over = 0;
 
        key.objectid = inode->i_ino;
        key.flags = 0;
        if (ret < 0) {
                goto err;
        }
-       advance = filp->f_pos > 0 && ret != 0;
+       advance = 0;
        while(1) {
                leaf = btrfs_buffer_leaf(path.nodes[0]);
                nritems = btrfs_header_nritems(&leaf->header);
                        break;
                if (btrfs_disk_key_type(&item->key) != BTRFS_DIR_ITEM_KEY)
                        continue;
+               if (btrfs_disk_key_offset(&item->key) < filp->f_pos)
+                       continue;
                di = btrfs_item_ptr(leaf, slot, struct btrfs_dir_item);
                over = filldir(dirent, (const char *)(di + 1),
                               btrfs_dir_name_len(di),
                               btrfs_disk_key_offset(&item->key),
                               btrfs_dir_objectid(di), d_type);
-               if (over)
+               if (over) {
+                       filp->f_pos = btrfs_disk_key_offset(&item->key);
                        break;
+               }
                filp->f_pos = btrfs_disk_key_offset(&item->key) + 1;
        }
        ret = 0;
                                    dentry->d_name.name, dentry->d_name.len,
                                    dentry->d_parent->d_inode->i_ino,
                                    inode->i_ino, 0);
-       BUG_ON(ret);
        return ret;
 }
 
 {
        sb->s_dirt = 0;
 printk("btrfs write_super!\n");
+       filemap_flush(sb->s_bdev->bd_inode->i_mapping);
 }
 
 static int btrfs_sync_fs(struct super_block *sb, int wait)