]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/btrfs/inode.c
Btrfs: Add mount -o nodatasum to turn of file data checksumming
[mv-sheeva.git] / fs / btrfs / inode.c
index cefe740b6c7933e36196893632fcb07a0c434315..11885cb114e2186fe58de1d761e685227783202c 100644 (file)
@@ -116,10 +116,13 @@ int btrfs_writepage_io_hook(struct page *page, u64 start, u64 end)
        struct btrfs_root *root = BTRFS_I(inode)->root;
        struct btrfs_trans_handle *trans;
        char *kaddr;
-       int ret;
+       int ret = 0;
        u64 page_start = (u64)page->index << PAGE_CACHE_SHIFT;
        size_t offset = start - page_start;
 
+       if (btrfs_test_opt(root, NODATASUM))
+               return 0;
+
        mutex_lock(&root->fs_info->fs_mutex);
        trans = btrfs_start_transaction(root, 1);
        btrfs_set_trans_block_group(trans, inode);
@@ -143,6 +146,9 @@ int btrfs_readpage_io_hook(struct page *page, u64 start, u64 end)
        struct btrfs_path *path = NULL;
        u32 csum;
 
+       if (btrfs_test_opt(root, NODATASUM))
+               return 0;
+
        mutex_lock(&root->fs_info->fs_mutex);
        path = btrfs_alloc_path();
        item = btrfs_lookup_csum(NULL, root, path, inode->i_ino, start, 0);
@@ -176,6 +182,9 @@ int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end)
        u32 csum = ~(u32)0;
        unsigned long flags;
 
+       if (btrfs_test_opt(root, NODATASUM))
+               return 0;
+
        ret = get_state_private(em_tree, start, &private);
        local_irq_save(flags);
        kaddr = kmap_atomic(page, KM_IRQ0);
@@ -404,16 +413,14 @@ static int btrfs_unlink_trans(struct btrfs_trans_handle *trans,
        ret = btrfs_delete_one_dir_name(trans, root, path, di);
 
        dentry->d_inode->i_ctime = dir->i_ctime;
-       if (!S_ISLNK(dentry->d_inode->i_mode)) {
-               ret = btrfs_del_inode_ref(trans, root, name, name_len,
-                                         dentry->d_inode->i_ino,
-                                         dentry->d_parent->d_inode->i_ino);
-               if (ret) {
-                       printk("failed to delete reference to %.*s, "
-                              "inode %lu parent %lu\n", name_len, name,
-                              dentry->d_inode->i_ino,
-                              dentry->d_parent->d_inode->i_ino);
-               }
+       ret = btrfs_del_inode_ref(trans, root, name, name_len,
+                                 dentry->d_inode->i_ino,
+                                 dentry->d_parent->d_inode->i_ino);
+       if (ret) {
+               printk("failed to delete reference to %.*s, "
+                      "inode %lu parent %lu\n", name_len, name,
+                      dentry->d_inode->i_ino,
+                      dentry->d_parent->d_inode->i_ino);
        }
 err:
        btrfs_free_path(path);
@@ -859,7 +866,7 @@ static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
        path = btrfs_alloc_path();
        BUG_ON(!path);
 
-       if (namelen == 1 && strcmp(name, "..") == 0) {
+       if (namelen == 2 && strcmp(name, "..") == 0) {
                struct btrfs_key key;
                struct extent_buffer *leaf;
                u32 nritems;
@@ -1293,13 +1300,11 @@ static int btrfs_add_link(struct btrfs_trans_handle *trans,
                                    dentry->d_parent->d_inode->i_ino,
                                    &key, btrfs_inode_type(inode));
        if (ret == 0) {
-               if (!S_ISLNK(inode->i_mode)) {
-                       ret = btrfs_insert_inode_ref(trans, root,
-                                            dentry->d_name.name,
-                                            dentry->d_name.len,
-                                            inode->i_ino,
-                                            dentry->d_parent->d_inode->i_ino);
-               }
+               ret = btrfs_insert_inode_ref(trans, root,
+                                    dentry->d_name.name,
+                                    dentry->d_name.len,
+                                    inode->i_ino,
+                                    dentry->d_parent->d_inode->i_ino);
                parent_inode = dentry->d_parent->d_inode;
                parent_inode->i_size += dentry->d_name.len * 2;
                parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME;
@@ -1897,8 +1902,19 @@ static void btrfs_truncate(struct inode *inode)
 int btrfs_commit_write(struct file *file, struct page *page,
                       unsigned from, unsigned to)
 {
-       return extent_commit_write(&BTRFS_I(page->mapping->host)->extent_tree,
-                                  page->mapping->host, page, from, to);
+       loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+       struct inode *inode = page->mapping->host;
+
+       btrfs_cow_one_page(inode, page, PAGE_CACHE_SIZE);
+
+       set_page_extent_mapped(page);
+       set_page_dirty(page);
+
+       if (pos > inode->i_size) {
+               i_size_write(inode, pos);
+               mark_inode_dirty(inode);
+       }
+       return 0;
 }
 
 static int create_subvol(struct btrfs_root *root, char *name, int namelen)