minix: replace inode uid,gid,mode init with helper
[safe/jmp/linux-2.6] / fs / btrfs / ordered-data.c
index 9b16073..a127c0e 100644 (file)
@@ -16,7 +16,6 @@
  * Boston, MA 021110-1307, USA.
  */
 
-#include <linux/gfp.h>
 #include <linux/slab.h>
 #include <linux/blkdev.h>
 #include <linux/writeback.h>
@@ -174,7 +173,6 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
        if (!entry)
                return -ENOMEM;
 
-       mutex_lock(&tree->mutex);
        entry->file_offset = file_offset;
        entry->start = start;
        entry->len = len;
@@ -190,16 +188,17 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
        INIT_LIST_HEAD(&entry->list);
        INIT_LIST_HEAD(&entry->root_extent_list);
 
+       spin_lock(&tree->lock);
        node = tree_insert(&tree->tree, file_offset,
                           &entry->rb_node);
        BUG_ON(node);
+       spin_unlock(&tree->lock);
 
        spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
        list_add_tail(&entry->root_extent_list,
                      &BTRFS_I(inode)->root->fs_info->ordered_extents);
        spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
 
-       mutex_unlock(&tree->mutex);
        BUG_ON(node);
        return 0;
 }
@@ -216,9 +215,9 @@ int btrfs_add_ordered_sum(struct inode *inode,
        struct btrfs_ordered_inode_tree *tree;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        list_add_tail(&sum->list, &entry->list);
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        return 0;
 }
 
@@ -232,15 +231,16 @@ int btrfs_add_ordered_sum(struct inode *inode,
  * to make sure this function only returns 1 once for a given ordered extent.
  */
 int btrfs_dec_test_ordered_pending(struct inode *inode,
+                                  struct btrfs_ordered_extent **cached,
                                   u64 file_offset, u64 io_size)
 {
        struct btrfs_ordered_inode_tree *tree;
        struct rb_node *node;
-       struct btrfs_ordered_extent *entry;
+       struct btrfs_ordered_extent *entry = NULL;
        int ret;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        node = tree_search(tree, file_offset);
        if (!node) {
                ret = 1;
@@ -264,7 +264,11 @@ int btrfs_dec_test_ordered_pending(struct inode *inode,
        else
                ret = 1;
 out:
-       mutex_unlock(&tree->mutex);
+       if (!ret && cached && entry) {
+               *cached = entry;
+               atomic_inc(&entry->refs);
+       }
+       spin_unlock(&tree->lock);
        return ret == 0;
 }
 
@@ -291,13 +295,14 @@ int btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
 
 /*
  * remove an ordered extent from the tree.  No references are dropped
- * and you must wake_up entry->wait.  You must hold the tree mutex
+ * and you must wake_up entry->wait.  You must hold the tree lock
  * while you call this function.
  */
 static int __btrfs_remove_ordered_extent(struct inode *inode,
                                struct btrfs_ordered_extent *entry)
 {
        struct btrfs_ordered_inode_tree *tree;
+       struct btrfs_root *root = BTRFS_I(inode)->root;
        struct rb_node *node;
 
        tree = &BTRFS_I(inode)->ordered_tree;
@@ -307,12 +312,13 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
        set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags);
 
        spin_lock(&BTRFS_I(inode)->accounting_lock);
+       WARN_ON(!BTRFS_I(inode)->outstanding_extents);
        BTRFS_I(inode)->outstanding_extents--;
        spin_unlock(&BTRFS_I(inode)->accounting_lock);
        btrfs_unreserve_metadata_for_delalloc(BTRFS_I(inode)->root,
                                              inode, 1);
 
-       spin_lock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
+       spin_lock(&root->fs_info->ordered_extent_lock);
        list_del_init(&entry->root_extent_list);
 
        /*
@@ -324,7 +330,7 @@ static int __btrfs_remove_ordered_extent(struct inode *inode,
            !mapping_tagged(inode->i_mapping, PAGECACHE_TAG_DIRTY)) {
                list_del_init(&BTRFS_I(inode)->ordered_operations);
        }
-       spin_unlock(&BTRFS_I(inode)->root->fs_info->ordered_extent_lock);
+       spin_unlock(&root->fs_info->ordered_extent_lock);
 
        return 0;
 }
@@ -340,9 +346,9 @@ int btrfs_remove_ordered_extent(struct inode *inode,
        int ret;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        ret = __btrfs_remove_ordered_extent(inode, entry);
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        wake_up(&entry->wait);
 
        return ret;
@@ -352,7 +358,8 @@ int btrfs_remove_ordered_extent(struct inode *inode,
  * wait for all the ordered extents in a root.  This is done when balancing
  * space between drives.
  */
-int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only)
+int btrfs_wait_ordered_extents(struct btrfs_root *root,
+                              int nocow_only, int delay_iput)
 {
        struct list_head splice;
        struct list_head *cur;
@@ -389,7 +396,10 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only)
                if (inode) {
                        btrfs_start_ordered_extent(inode, ordered, 1);
                        btrfs_put_ordered_extent(ordered);
-                       iput(inode);
+                       if (delay_iput)
+                               btrfs_add_delayed_iput(inode);
+                       else
+                               iput(inode);
                } else {
                        btrfs_put_ordered_extent(ordered);
                }
@@ -447,7 +457,7 @@ again:
                                btrfs_wait_ordered_range(inode, 0, (u64)-1);
                        else
                                filemap_flush(inode->i_mapping);
-                       iput(inode);
+                       btrfs_add_delayed_iput(inode);
                }
 
                cond_resched();
@@ -563,7 +573,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
        struct btrfs_ordered_extent *entry = NULL;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        node = tree_search(tree, file_offset);
        if (!node)
                goto out;
@@ -574,7 +584,7 @@ struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
        if (entry)
                atomic_inc(&entry->refs);
 out:
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        return entry;
 }
 
@@ -590,7 +600,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
        struct btrfs_ordered_extent *entry = NULL;
 
        tree = &BTRFS_I(inode)->ordered_tree;
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        node = tree_search(tree, file_offset);
        if (!node)
                goto out;
@@ -598,7 +608,7 @@ btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
        entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
        atomic_inc(&entry->refs);
 out:
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        return entry;
 }
 
@@ -622,8 +632,10 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
 
        if (ordered)
                offset = entry_end(ordered);
+       else
+               offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);
 
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        disk_i_size = BTRFS_I(inode)->disk_i_size;
 
        /* truncate file */
@@ -729,7 +741,7 @@ out:
         */
        if (ordered)
                __btrfs_remove_ordered_extent(inode, ordered);
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        if (ordered)
                wake_up(&ordered->wait);
        return ret;
@@ -756,7 +768,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
        if (!ordered)
                return 1;
 
-       mutex_lock(&tree->mutex);
+       spin_lock(&tree->lock);
        list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
                if (disk_bytenr >= ordered_sum->bytenr) {
                        num_sectors = ordered_sum->len / sectorsize;
@@ -771,7 +783,7 @@ int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
                }
        }
 out:
-       mutex_unlock(&tree->mutex);
+       spin_unlock(&tree->lock);
        btrfs_put_ordered_extent(ordered);
        return ret;
 }