Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs...
authorLinus Torvalds <torvalds@linux-foundation.org>
Mon, 27 Jun 2011 20:32:14 +0000 (13:32 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Mon, 27 Jun 2011 20:32:14 +0000 (13:32 -0700)
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
  btrfs: fix inconsonant inode information
  Btrfs: make sure to update total_bitmaps when freeing cache V3
  Btrfs: fix type mismatch in find_free_extent()
  Btrfs: make sure to record the transid in new inodes

fs/btrfs/delayed-inode.c
fs/btrfs/delayed-inode.h
fs/btrfs/extent-tree.c
fs/btrfs/free-space-cache.c
fs/btrfs/inode.c

index f1cbd028f7b33e2a693292641cacd21b535a5e75..98c68e658a9b2eb08a8ba99d0b5691f16fc8a67d 100644 (file)
@@ -82,19 +82,16 @@ static inline struct btrfs_delayed_root *btrfs_get_delayed_root(
        return root->fs_info->delayed_root;
 }
 
-static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node(
-                                                       struct inode *inode)
+static struct btrfs_delayed_node *btrfs_get_delayed_node(struct inode *inode)
 {
-       struct btrfs_delayed_node *node;
        struct btrfs_inode *btrfs_inode = BTRFS_I(inode);
        struct btrfs_root *root = btrfs_inode->root;
        u64 ino = btrfs_ino(inode);
-       int ret;
+       struct btrfs_delayed_node *node;
 
-again:
        node = ACCESS_ONCE(btrfs_inode->delayed_node);
        if (node) {
-               atomic_inc(&node->refs);        /* can be accessed */
+               atomic_inc(&node->refs);
                return node;
        }
 
@@ -102,8 +99,10 @@ again:
        node = radix_tree_lookup(&root->delayed_nodes_tree, ino);
        if (node) {
                if (btrfs_inode->delayed_node) {
+                       atomic_inc(&node->refs);        /* can be accessed */
+                       BUG_ON(btrfs_inode->delayed_node != node);
                        spin_unlock(&root->inode_lock);
-                       goto again;
+                       return node;
                }
                btrfs_inode->delayed_node = node;
                atomic_inc(&node->refs);        /* can be accessed */
@@ -113,6 +112,23 @@ again:
        }
        spin_unlock(&root->inode_lock);
 
+       return NULL;
+}
+
+static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node(
+                                                       struct inode *inode)
+{
+       struct btrfs_delayed_node *node;
+       struct btrfs_inode *btrfs_inode = BTRFS_I(inode);
+       struct btrfs_root *root = btrfs_inode->root;
+       u64 ino = btrfs_ino(inode);
+       int ret;
+
+again:
+       node = btrfs_get_delayed_node(inode);
+       if (node)
+               return node;
+
        node = kmem_cache_alloc(delayed_node_cache, GFP_NOFS);
        if (!node)
                return ERR_PTR(-ENOMEM);
@@ -548,19 +564,6 @@ struct btrfs_delayed_item *__btrfs_next_delayed_item(
        return next;
 }
 
-static inline struct btrfs_delayed_node *btrfs_get_delayed_node(
-                                                       struct inode *inode)
-{
-       struct btrfs_inode *btrfs_inode = BTRFS_I(inode);
-       struct btrfs_delayed_node *delayed_node;
-
-       delayed_node = btrfs_inode->delayed_node;
-       if (delayed_node)
-               atomic_inc(&delayed_node->refs);
-
-       return delayed_node;
-}
-
 static inline struct btrfs_root *btrfs_get_fs_root(struct btrfs_root *root,
                                                   u64 root_id)
 {
@@ -1404,8 +1407,7 @@ end:
 
 int btrfs_inode_delayed_dir_index_count(struct inode *inode)
 {
-       struct btrfs_delayed_node *delayed_node = BTRFS_I(inode)->delayed_node;
-       int ret = 0;
+       struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
 
        if (!delayed_node)
                return -ENOENT;
@@ -1415,11 +1417,14 @@ int btrfs_inode_delayed_dir_index_count(struct inode *inode)
         * a new directory index is added into the delayed node and index_cnt
         * is updated now. So we needn't lock the delayed node.
         */
-       if (!delayed_node->index_cnt)
+       if (!delayed_node->index_cnt) {
+               btrfs_release_delayed_node(delayed_node);
                return -EINVAL;
+       }
 
        BTRFS_I(inode)->index_cnt = delayed_node->index_cnt;
-       return ret;
+       btrfs_release_delayed_node(delayed_node);
+       return 0;
 }
 
 void btrfs_get_delayed_items(struct inode *inode, struct list_head *ins_list,
@@ -1613,6 +1618,57 @@ static void fill_stack_inode_item(struct btrfs_trans_handle *trans,
                                      inode->i_ctime.tv_nsec);
 }
 
+int btrfs_fill_inode(struct inode *inode, u32 *rdev)
+{
+       struct btrfs_delayed_node *delayed_node;
+       struct btrfs_inode_item *inode_item;
+       struct btrfs_timespec *tspec;
+
+       delayed_node = btrfs_get_delayed_node(inode);
+       if (!delayed_node)
+               return -ENOENT;
+
+       mutex_lock(&delayed_node->mutex);
+       if (!delayed_node->inode_dirty) {
+               mutex_unlock(&delayed_node->mutex);
+               btrfs_release_delayed_node(delayed_node);
+               return -ENOENT;
+       }
+
+       inode_item = &delayed_node->inode_item;
+
+       inode->i_uid = btrfs_stack_inode_uid(inode_item);
+       inode->i_gid = btrfs_stack_inode_gid(inode_item);
+       btrfs_i_size_write(inode, btrfs_stack_inode_size(inode_item));
+       inode->i_mode = btrfs_stack_inode_mode(inode_item);
+       inode->i_nlink = btrfs_stack_inode_nlink(inode_item);
+       inode_set_bytes(inode, btrfs_stack_inode_nbytes(inode_item));
+       BTRFS_I(inode)->generation = btrfs_stack_inode_generation(inode_item);
+       BTRFS_I(inode)->sequence = btrfs_stack_inode_sequence(inode_item);
+       inode->i_rdev = 0;
+       *rdev = btrfs_stack_inode_rdev(inode_item);
+       BTRFS_I(inode)->flags = btrfs_stack_inode_flags(inode_item);
+
+       tspec = btrfs_inode_atime(inode_item);
+       inode->i_atime.tv_sec = btrfs_stack_timespec_sec(tspec);
+       inode->i_atime.tv_nsec = btrfs_stack_timespec_nsec(tspec);
+
+       tspec = btrfs_inode_mtime(inode_item);
+       inode->i_mtime.tv_sec = btrfs_stack_timespec_sec(tspec);
+       inode->i_mtime.tv_nsec = btrfs_stack_timespec_nsec(tspec);
+
+       tspec = btrfs_inode_ctime(inode_item);
+       inode->i_ctime.tv_sec = btrfs_stack_timespec_sec(tspec);
+       inode->i_ctime.tv_nsec = btrfs_stack_timespec_nsec(tspec);
+
+       inode->i_generation = BTRFS_I(inode)->generation;
+       BTRFS_I(inode)->index_cnt = (u64)-1;
+
+       mutex_unlock(&delayed_node->mutex);
+       btrfs_release_delayed_node(delayed_node);
+       return 0;
+}
+
 int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root, struct inode *inode)
 {
index d1a6a2915c668afe2500c187d731da0ea1f6bdaa..8d27af4bd8b99f00f073d18125589fa39e2269fa 100644 (file)
@@ -119,6 +119,7 @@ void btrfs_kill_delayed_inode_items(struct inode *inode);
 
 int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
                               struct btrfs_root *root, struct inode *inode);
+int btrfs_fill_inode(struct inode *inode, u32 *rdev);
 
 /* Used for drop dead root */
 void btrfs_kill_all_delayed_nodes(struct btrfs_root *root);
index 1f61bf5b4960404b063ddc4ab0587970687321d0..71cd456fdb60360d44edd113ab7c593bdacfa658 100644 (file)
@@ -4842,7 +4842,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
                                     u64 num_bytes, u64 empty_size,
                                     u64 search_start, u64 search_end,
                                     u64 hint_byte, struct btrfs_key *ins,
-                                    int data)
+                                    u64 data)
 {
        int ret = 0;
        struct btrfs_root *root = orig_root->fs_info->extent_root;
@@ -4869,7 +4869,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
 
        space_info = __find_space_info(root->fs_info, data);
        if (!space_info) {
-               printk(KERN_ERR "No space info for %d\n", data);
+               printk(KERN_ERR "No space info for %llu\n", data);
                return -ENOSPC;
        }
 
index 9f985a429877fdd5d04100514f3ff4a5f2abeb18..bf0d61567f3d65a24e9d11802acdd0c8c5abf32b 100644 (file)
@@ -1893,9 +1893,12 @@ void __btrfs_remove_free_space_cache_locked(struct btrfs_free_space_ctl *ctl)
 
        while ((node = rb_last(&ctl->free_space_offset)) != NULL) {
                info = rb_entry(node, struct btrfs_free_space, offset_index);
-               unlink_free_space(ctl, info);
-               kfree(info->bitmap);
-               kmem_cache_free(btrfs_free_space_cachep, info);
+               if (!info->bitmap) {
+                       unlink_free_space(ctl, info);
+                       kmem_cache_free(btrfs_free_space_cachep, info);
+               } else {
+                       free_bitmap(ctl, info);
+               }
                if (need_resched()) {
                        spin_unlock(&ctl->tree_lock);
                        cond_resched();
index 0a9b10c5b0a7458a6f2aca7a195c1980e1b88bb8..d340f63d8f07b2cf7c0e087fdf92ba384e31662e 100644 (file)
@@ -2509,6 +2509,11 @@ static void btrfs_read_locked_inode(struct inode *inode)
        int maybe_acls;
        u32 rdev;
        int ret;
+       bool filled = false;
+
+       ret = btrfs_fill_inode(inode, &rdev);
+       if (!ret)
+               filled = true;
 
        path = btrfs_alloc_path();
        BUG_ON(!path);
@@ -2520,6 +2525,10 @@ static void btrfs_read_locked_inode(struct inode *inode)
                goto make_bad;
 
        leaf = path->nodes[0];
+
+       if (filled)
+               goto cache_acl;
+
        inode_item = btrfs_item_ptr(leaf, path->slots[0],
                                    struct btrfs_inode_item);
        if (!leaf->map_token)
@@ -2556,7 +2565,7 @@ static void btrfs_read_locked_inode(struct inode *inode)
 
        BTRFS_I(inode)->index_cnt = (u64)-1;
        BTRFS_I(inode)->flags = btrfs_inode_flags(leaf, inode_item);
-
+cache_acl:
        /*
         * try to precache a NULL acl entry for files that don't have
         * any xattrs or acls
@@ -2572,7 +2581,6 @@ static void btrfs_read_locked_inode(struct inode *inode)
        }
 
        btrfs_free_path(path);
-       inode_item = NULL;
 
        switch (inode->i_mode & S_IFMT) {
        case S_IFREG:
@@ -4520,6 +4528,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
        inode_tree_add(inode);
 
        trace_btrfs_inode_new(inode);
+       btrfs_set_inode_last_trans(trans, inode);
 
        return inode;
 fail: