Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[pandora-kernel.git] / fs / btrfs / inode.c
index c9bc0af..bcc461a 100644 (file)
@@ -3902,7 +3902,7 @@ again:
        p = &root->inode_tree.rb_node;
        parent = NULL;
 
        p = &root->inode_tree.rb_node;
        parent = NULL;
 
-       if (hlist_unhashed(&inode->i_hash))
+       if (inode_unhashed(inode))
                return;
 
        spin_lock(&root->inode_lock);
                return;
 
        spin_lock(&root->inode_lock);
@@ -4109,8 +4109,6 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
        int index;
        int ret;
 
        int index;
        int ret;
 
-       dentry->d_op = &btrfs_dentry_operations;
-
        if (dentry->d_name.len > BTRFS_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
 
        if (dentry->d_name.len > BTRFS_NAME_LEN)
                return ERR_PTR(-ENAMETOOLONG);
 
@@ -4152,7 +4150,7 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry)
        return inode;
 }
 
        return inode;
 }
 
-static int btrfs_dentry_delete(struct dentry *dentry)
+static int btrfs_dentry_delete(const struct dentry *dentry)
 {
        struct btrfs_root *root;
 
 {
        struct btrfs_root *root;
 
@@ -4830,7 +4828,7 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir,
        }
 
        btrfs_set_trans_block_group(trans, dir);
        }
 
        btrfs_set_trans_block_group(trans, dir);
-       atomic_inc(&inode->i_count);
+       ihold(inode);
 
        err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index);
 
 
        err = btrfs_add_nondir(trans, dir, dentry, inode, 1, index);
 
@@ -6530,6 +6528,13 @@ struct inode *btrfs_alloc_inode(struct super_block *sb)
        return inode;
 }
 
        return inode;
 }
 
+static void btrfs_i_callback(struct rcu_head *head)
+{
+       struct inode *inode = container_of(head, struct inode, i_rcu);
+       INIT_LIST_HEAD(&inode->i_dentry);
+       kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
+}
+
 void btrfs_destroy_inode(struct inode *inode)
 {
        struct btrfs_ordered_extent *ordered;
 void btrfs_destroy_inode(struct inode *inode)
 {
        struct btrfs_ordered_extent *ordered;
@@ -6599,7 +6604,7 @@ void btrfs_destroy_inode(struct inode *inode)
        inode_tree_del(inode);
        btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
 free:
        inode_tree_del(inode);
        btrfs_drop_extent_cache(inode, 0, (u64)-1, 0);
 free:
-       kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode));
+       call_rcu(&inode->i_rcu, btrfs_i_callback);
 }
 
 int btrfs_drop_inode(struct inode *inode)
 }
 
 int btrfs_drop_inode(struct inode *inode)
@@ -7128,118 +7133,12 @@ int btrfs_prealloc_file_range_trans(struct inode *inode,
                                           min_size, actual_len, alloc_hint, trans);
 }
 
                                           min_size, actual_len, alloc_hint, trans);
 }
 
-static long btrfs_fallocate(struct inode *inode, int mode,
-                           loff_t offset, loff_t len)
-{
-       struct extent_state *cached_state = NULL;
-       u64 cur_offset;
-       u64 last_byte;
-       u64 alloc_start;
-       u64 alloc_end;
-       u64 alloc_hint = 0;
-       u64 locked_end;
-       u64 mask = BTRFS_I(inode)->root->sectorsize - 1;
-       struct extent_map *em;
-       int ret;
-
-       alloc_start = offset & ~mask;
-       alloc_end =  (offset + len + mask) & ~mask;
-
-       /*
-        * wait for ordered IO before we have any locks.  We'll loop again
-        * below with the locks held.
-        */
-       btrfs_wait_ordered_range(inode, alloc_start, alloc_end - alloc_start);
-
-       mutex_lock(&inode->i_mutex);
-       ret = inode_newsize_ok(inode, alloc_end);
-       if (ret)
-               goto out;
-
-       if (alloc_start > inode->i_size) {
-               ret = btrfs_cont_expand(inode, alloc_start);
-               if (ret)
-                       goto out;
-       }
-
-       ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
-       if (ret)
-               goto out;
-
-       locked_end = alloc_end - 1;
-       while (1) {
-               struct btrfs_ordered_extent *ordered;
-
-               /* the extent lock is ordered inside the running
-                * transaction
-                */
-               lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start,
-                                locked_end, 0, &cached_state, GFP_NOFS);
-               ordered = btrfs_lookup_first_ordered_extent(inode,
-                                                           alloc_end - 1);
-               if (ordered &&
-                   ordered->file_offset + ordered->len > alloc_start &&
-                   ordered->file_offset < alloc_end) {
-                       btrfs_put_ordered_extent(ordered);
-                       unlock_extent_cached(&BTRFS_I(inode)->io_tree,
-                                            alloc_start, locked_end,
-                                            &cached_state, GFP_NOFS);
-                       /*
-                        * we can't wait on the range with the transaction
-                        * running or with the extent lock held
-                        */
-                       btrfs_wait_ordered_range(inode, alloc_start,
-                                                alloc_end - alloc_start);
-               } else {
-                       if (ordered)
-                               btrfs_put_ordered_extent(ordered);
-                       break;
-               }
-       }
-
-       cur_offset = alloc_start;
-       while (1) {
-               em = btrfs_get_extent(inode, NULL, 0, cur_offset,
-                                     alloc_end - cur_offset, 0);
-               BUG_ON(IS_ERR(em) || !em);
-               last_byte = min(extent_map_end(em), alloc_end);
-               last_byte = (last_byte + mask) & ~mask;
-               if (em->block_start == EXTENT_MAP_HOLE ||
-                   (cur_offset >= inode->i_size &&
-                    !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
-                       ret = btrfs_prealloc_file_range(inode, mode, cur_offset,
-                                                       last_byte - cur_offset,
-                                                       1 << inode->i_blkbits,
-                                                       offset + len,
-                                                       &alloc_hint);
-                       if (ret < 0) {
-                               free_extent_map(em);
-                               break;
-                       }
-               }
-               free_extent_map(em);
-
-               cur_offset = last_byte;
-               if (cur_offset >= alloc_end) {
-                       ret = 0;
-                       break;
-               }
-       }
-       unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
-                            &cached_state, GFP_NOFS);
-
-       btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
-out:
-       mutex_unlock(&inode->i_mutex);
-       return ret;
-}
-
 static int btrfs_set_page_dirty(struct page *page)
 {
        return __set_page_dirty_nobuffers(page);
 }
 
 static int btrfs_set_page_dirty(struct page *page)
 {
        return __set_page_dirty_nobuffers(page);
 }
 
-static int btrfs_permission(struct inode *inode, int mask)
+static int btrfs_permission(struct inode *inode, int mask, unsigned int flags)
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
 
 {
        struct btrfs_root *root = BTRFS_I(inode)->root;
 
@@ -7247,7 +7146,7 @@ static int btrfs_permission(struct inode *inode, int mask)
                return -EROFS;
        if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE))
                return -EACCES;
                return -EROFS;
        if ((BTRFS_I(inode)->flags & BTRFS_INODE_READONLY) && (mask & MAY_WRITE))
                return -EACCES;
-       return generic_permission(inode, mask, btrfs_check_acl);
+       return generic_permission(inode, mask, flags, btrfs_check_acl);
 }
 
 static const struct inode_operations btrfs_dir_inode_operations = {
 }
 
 static const struct inode_operations btrfs_dir_inode_operations = {
@@ -7340,7 +7239,6 @@ static const struct inode_operations btrfs_file_inode_operations = {
        .listxattr      = btrfs_listxattr,
        .removexattr    = btrfs_removexattr,
        .permission     = btrfs_permission,
        .listxattr      = btrfs_listxattr,
        .removexattr    = btrfs_removexattr,
        .permission     = btrfs_permission,
-       .fallocate      = btrfs_fallocate,
        .fiemap         = btrfs_fiemap,
 };
 static const struct inode_operations btrfs_special_inode_operations = {
        .fiemap         = btrfs_fiemap,
 };
 static const struct inode_operations btrfs_special_inode_operations = {