Merge tag 'renesas-soc-for-v3.13' of git://git.kernel.org/pub/scm/linux/kernel/git...
[firefly-linux-kernel-4.4.55.git] / fs / btrfs / ordered-data.c
index 81369827e5146552edd7428911faef52ca3e1de6..c702cb62f78a310c8d430fe0d98cfb1173479a0f 100644 (file)
@@ -67,7 +67,7 @@ static void ordered_data_tree_panic(struct inode *inode, int errno,
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
        btrfs_panic(fs_info, errno, "Inconsistency in ordered tree at offset "
-                   "%llu\n", (unsigned long long)offset);
+                   "%llu\n", offset);
 }
 
 /*
@@ -205,6 +205,7 @@ static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
        entry->bytes_left = len;
        entry->inode = igrab(inode);
        entry->compress_type = compress_type;
+       entry->truncated_len = (u64)-1;
        if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE)
                set_bit(type, &entry->flags);
 
@@ -336,14 +337,12 @@ int btrfs_dec_test_first_ordered_pending(struct inode *inode,
        *file_offset = dec_end;
        if (dec_start > dec_end) {
                printk(KERN_CRIT "bad ordering dec_start %llu end %llu\n",
-                      (unsigned long long)dec_start,
-                      (unsigned long long)dec_end);
+                      dec_start, dec_end);
        }
        to_dec = dec_end - dec_start;
        if (to_dec > entry->bytes_left) {
                printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n",
-                      (unsigned long long)entry->bytes_left,
-                      (unsigned long long)to_dec);
+                      entry->bytes_left, to_dec);
        }
        entry->bytes_left -= to_dec;
        if (!uptodate)
@@ -403,8 +402,7 @@ have_entry:
 
        if (io_size > entry->bytes_left) {
                printk(KERN_CRIT "bad ordered accounting left %llu size %llu\n",
-                      (unsigned long long)entry->bytes_left,
-                      (unsigned long long)io_size);
+                      entry->bytes_left, io_size);
        }
        entry->bytes_left -= io_size;
        if (!uptodate)
@@ -565,11 +563,10 @@ static void btrfs_run_ordered_extent_work(struct btrfs_work *work)
  * wait for all the ordered extents in a root.  This is done when balancing
  * space between drives.
  */
-void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
+void btrfs_wait_ordered_extents(struct btrfs_root *root)
 {
        struct list_head splice, works;
        struct btrfs_ordered_extent *ordered, *next;
-       struct inode *inode;
 
        INIT_LIST_HEAD(&splice);
        INIT_LIST_HEAD(&works);
@@ -582,15 +579,6 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
                                           root_extent_list);
                list_move_tail(&ordered->root_extent_list,
                               &root->ordered_extents);
-               /*
-                * the inode may be getting freed (in sys_unlink path).
-                */
-               inode = igrab(ordered->inode);
-               if (!inode) {
-                       cond_resched_lock(&root->ordered_extent_lock);
-                       continue;
-               }
-
                atomic_inc(&ordered->refs);
                spin_unlock(&root->ordered_extent_lock);
 
@@ -607,21 +595,13 @@ void btrfs_wait_ordered_extents(struct btrfs_root *root, int delay_iput)
        list_for_each_entry_safe(ordered, next, &works, work_list) {
                list_del_init(&ordered->work_list);
                wait_for_completion(&ordered->completion);
-
-               inode = ordered->inode;
                btrfs_put_ordered_extent(ordered);
-               if (delay_iput)
-                       btrfs_add_delayed_iput(inode);
-               else
-                       iput(inode);
-
                cond_resched();
        }
        mutex_unlock(&root->fs_info->ordered_operations_mutex);
 }
 
-void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info,
-                                   int delay_iput)
+void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info)
 {
        struct btrfs_root *root;
        struct list_head splice;
@@ -639,7 +619,7 @@ void btrfs_wait_all_ordered_extents(struct btrfs_fs_info *fs_info,
                               &fs_info->ordered_roots);
                spin_unlock(&fs_info->ordered_root_lock);
 
-               btrfs_wait_ordered_extents(root, delay_iput);
+               btrfs_wait_ordered_extents(root);
                btrfs_put_fs_root(root);
 
                spin_lock(&fs_info->ordered_root_lock);
@@ -671,7 +651,7 @@ int btrfs_run_ordered_operations(struct btrfs_trans_handle *trans,
        INIT_LIST_HEAD(&splice);
        INIT_LIST_HEAD(&works);
 
-       mutex_lock(&root->fs_info->ordered_operations_mutex);
+       mutex_lock(&root->fs_info->ordered_extent_flush_mutex);
        spin_lock(&root->fs_info->ordered_root_lock);
        list_splice_init(&cur_trans->ordered_operations, &splice);
        while (!list_empty(&splice)) {
@@ -718,7 +698,7 @@ out:
                list_del_init(&work->list);
                btrfs_wait_and_free_delalloc_work(work);
        }
-       mutex_unlock(&root->fs_info->ordered_operations_mutex);
+       mutex_unlock(&root->fs_info->ordered_extent_flush_mutex);
        return ret;
 }
 
@@ -923,12 +903,16 @@ int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
        struct btrfs_ordered_extent *test;
        int ret = 1;
 
-       if (ordered)
+       spin_lock_irq(&tree->lock);
+       if (ordered) {
                offset = entry_end(ordered);
-       else
+               if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered->flags))
+                       offset = min(offset,
+                                    ordered->file_offset +
+                                    ordered->truncated_len);
+       } else {
                offset = ALIGN(offset, BTRFS_I(inode)->root->sectorsize);
-
-       spin_lock_irq(&tree->lock);
+       }
        disk_i_size = BTRFS_I(inode)->disk_i_size;
 
        /* truncate file */