Btrfs: convert the inode bit field to use the actual bit operations
[firefly-linux-kernel-4.4.55.git] / fs / btrfs / file.c
index e8d06b6b9194af2839c686d9a651a56852876f96..c9005f216975f0d33cda5a8e90410e0a0b761c84 100644 (file)
@@ -103,7 +103,7 @@ static void __btrfs_add_inode_defrag(struct inode *inode,
                        goto exists;
                }
        }
-       BTRFS_I(inode)->in_defrag = 1;
+       set_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags);
        rb_link_node(&defrag->rb_node, parent, p);
        rb_insert_color(&defrag->rb_node, &root->fs_info->defrag_inodes);
        return;
@@ -131,7 +131,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
        if (btrfs_fs_closing(root->fs_info))
                return 0;
 
-       if (BTRFS_I(inode)->in_defrag)
+       if (test_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags))
                return 0;
 
        if (trans)
@@ -148,7 +148,7 @@ int btrfs_add_inode_defrag(struct btrfs_trans_handle *trans,
        defrag->root = root->root_key.objectid;
 
        spin_lock(&root->fs_info->defrag_inodes_lock);
-       if (!BTRFS_I(inode)->in_defrag)
+       if (!test_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags))
                __btrfs_add_inode_defrag(inode, defrag);
        else
                kfree(defrag);
@@ -252,7 +252,7 @@ int btrfs_run_defrag_inodes(struct btrfs_fs_info *fs_info)
                        goto next;
 
                /* do a chunk of defrag */
-               BTRFS_I(inode)->in_defrag = 0;
+               clear_bit(BTRFS_INODE_IN_DEFRAG, &BTRFS_I(inode)->runtime_flags);
                range.start = defrag->last_offset;
                num_defrag = btrfs_defrag_file(inode, NULL, &range, defrag->transid,
                                               defrag_batch);
@@ -452,7 +452,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                        split = alloc_extent_map();
                if (!split2)
                        split2 = alloc_extent_map();
-               BUG_ON(!split || !split2);
+               BUG_ON(!split || !split2); /* -ENOMEM */
 
                write_lock(&em_tree->lock);
                em = lookup_extent_mapping(em_tree, start, len);
@@ -494,7 +494,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                        split->flags = flags;
                        split->compress_type = em->compress_type;
                        ret = add_extent_mapping(em_tree, split);
-                       BUG_ON(ret);
+                       BUG_ON(ret); /* Logic error */
                        free_extent_map(split);
                        split = split2;
                        split2 = NULL;
@@ -520,7 +520,7 @@ int btrfs_drop_extent_cache(struct inode *inode, u64 start, u64 end,
                        }
 
                        ret = add_extent_mapping(em_tree, split);
-                       BUG_ON(ret);
+                       BUG_ON(ret); /* Logic error */
                        free_extent_map(split);
                        split = NULL;
                }
@@ -567,6 +567,7 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,
        int extent_type;
        int recow;
        int ret;
+       int modify_tree = -1;
 
        if (drop_cache)
                btrfs_drop_extent_cache(inode, start, end - 1, 0);
@@ -575,10 +576,13 @@ int btrfs_drop_extents(struct btrfs_trans_handle *trans, struct inode *inode,
        if (!path)
                return -ENOMEM;
 
+       if (start >= BTRFS_I(inode)->disk_i_size)
+               modify_tree = 0;
+
        while (1) {
                recow = 0;
                ret = btrfs_lookup_file_extent(trans, root, path, ino,
-                                              search_start, -1);
+                                              search_start, modify_tree);
                if (ret < 0)
                        break;
                if (ret > 0 && path->slots[0] > 0 && search_start == start) {
@@ -634,7 +638,8 @@ next_slot:
                }
 
                search_start = max(key.offset, start);
-               if (recow) {
+               if (recow || !modify_tree) {
+                       modify_tree = -1;
                        btrfs_release_path(path);
                        continue;
                }
@@ -679,7 +684,7 @@ next_slot:
                                                root->root_key.objectid,
                                                new_key.objectid,
                                                start - extent_offset, 0);
-                               BUG_ON(ret);
+                               BUG_ON(ret); /* -ENOMEM */
                                *hint_byte = disk_bytenr;
                        }
                        key.offset = start;
@@ -754,7 +759,7 @@ next_slot:
                                                root->root_key.objectid,
                                                key.objectid, key.offset -
                                                extent_offset, 0);
-                               BUG_ON(ret);
+                               BUG_ON(ret); /* -ENOMEM */
                                inode_sub_bytes(inode,
                                                extent_end - key.offset);
                                *hint_byte = disk_bytenr;
@@ -770,7 +775,10 @@ next_slot:
 
                        ret = btrfs_del_items(trans, root, path, del_slot,
                                              del_nr);
-                       BUG_ON(ret);
+                       if (ret) {
+                               btrfs_abort_transaction(trans, root, ret);
+                               goto out;
+                       }
 
                        del_nr = 0;
                        del_slot = 0;
@@ -782,11 +790,13 @@ next_slot:
                BUG_ON(1);
        }
 
-       if (del_nr > 0) {
+       if (!ret && del_nr > 0) {
                ret = btrfs_del_items(trans, root, path, del_slot, del_nr);
-               BUG_ON(ret);
+               if (ret)
+                       btrfs_abort_transaction(trans, root, ret);
        }
 
+out:
        btrfs_free_path(path);
        return ret;
 }
@@ -944,7 +954,10 @@ again:
                        btrfs_release_path(path);
                        goto again;
                }
-               BUG_ON(ret < 0);
+               if (ret < 0) {
+                       btrfs_abort_transaction(trans, root, ret);
+                       goto out;
+               }
 
                leaf = path->nodes[0];
                fi = btrfs_item_ptr(leaf, path->slots[0] - 1,
@@ -963,7 +976,7 @@ again:
                ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0,
                                           root->root_key.objectid,
                                           ino, orig_offset, 0);
-               BUG_ON(ret);
+               BUG_ON(ret); /* -ENOMEM */
 
                if (split == start) {
                        key.offset = start;
@@ -990,7 +1003,7 @@ again:
                ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
                                        0, root->root_key.objectid,
                                        ino, orig_offset, 0);
-               BUG_ON(ret);
+               BUG_ON(ret); /* -ENOMEM */
        }
        other_start = 0;
        other_end = start;
@@ -1007,7 +1020,7 @@ again:
                ret = btrfs_free_extent(trans, root, bytenr, num_bytes,
                                        0, root->root_key.objectid,
                                        ino, orig_offset, 0);
-               BUG_ON(ret);
+               BUG_ON(ret); /* -ENOMEM */
        }
        if (del_nr == 0) {
                fi = btrfs_item_ptr(leaf, path->slots[0],
@@ -1025,7 +1038,10 @@ again:
                btrfs_mark_buffer_dirty(leaf);
 
                ret = btrfs_del_items(trans, root, path, del_slot, del_nr);
-               BUG_ON(ret);
+               if (ret < 0) {
+                       btrfs_abort_transaction(trans, root, ret);
+                       goto out;
+               }
        }
 out:
        btrfs_free_path(path);
@@ -1105,8 +1121,7 @@ again:
        if (start_pos < inode->i_size) {
                struct btrfs_ordered_extent *ordered;
                lock_extent_bits(&BTRFS_I(inode)->io_tree,
-                                start_pos, last_pos - 1, 0, &cached_state,
-                                GFP_NOFS);
+                                start_pos, last_pos - 1, 0, &cached_state);
                ordered = btrfs_lookup_first_ordered_extent(inode,
                                                            last_pos - 1);
                if (ordered &&
@@ -1394,7 +1409,6 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,
                mutex_unlock(&inode->i_mutex);
                goto out;
        }
-       BTRFS_I(inode)->sequence++;
 
        start_pos = round_down(pos, root->sectorsize);
        if (start_pos > i_size_read(inode)) {
@@ -1451,8 +1465,8 @@ int btrfs_release_file(struct inode *inode, struct file *filp)
         * flush down new bytes that may have been written if the
         * application were using truncate to replace a file in place.
         */
-       if (BTRFS_I(inode)->ordered_data_close) {
-               BTRFS_I(inode)->ordered_data_close = 0;
+       if (test_and_clear_bit(BTRFS_INODE_ORDERED_DATA_CLOSE,
+                              &BTRFS_I(inode)->runtime_flags)) {
                btrfs_add_ordered_operation(NULL, BTRFS_I(inode)->root, inode);
                if (inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT)
                        filemap_flush(inode->i_mapping);
@@ -1483,14 +1497,15 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)
 
        trace_btrfs_sync_file(file, datasync);
 
-       ret = filemap_write_and_wait_range(inode->i_mapping, start, end);
-       if (ret)
-               return ret;
        mutex_lock(&inode->i_mutex);
 
-       /* we wait first, since the writeback may change the inode */
+       /*
+        * we wait first, since the writeback may change the inode, also wait
+        * ordered range does a filemape_write_and_wait_range which is why we
+        * don't do it above like other file systems.
+        */
        root->log_batch++;
-       btrfs_wait_ordered_range(inode, 0, (u64)-1);
+       btrfs_wait_ordered_range(inode, start, end);
        root->log_batch++;
 
        /*
@@ -1638,7 +1653,7 @@ static long btrfs_fallocate(struct file *file, int mode,
                 * transaction
                 */
                lock_extent_bits(&BTRFS_I(inode)->io_tree, alloc_start,
-                                locked_end, 0, &cached_state, GFP_NOFS);
+                                locked_end, 0, &cached_state);
                ordered = btrfs_lookup_first_ordered_extent(inode,
                                                            alloc_end - 1);
                if (ordered &&
@@ -1667,7 +1682,13 @@ static long btrfs_fallocate(struct file *file, int mode,
 
                em = btrfs_get_extent(inode, NULL, 0, cur_offset,
                                      alloc_end - cur_offset, 0);
-               BUG_ON(IS_ERR_OR_NULL(em));
+               if (IS_ERR_OR_NULL(em)) {
+                       if (!em)
+                               ret = -ENOMEM;
+                       else
+                               ret = PTR_ERR(em);
+                       break;
+               }
                last_byte = min(extent_map_end(em), alloc_end);
                actual_end = min_t(u64, extent_map_end(em), offset + len);
                last_byte = (last_byte + mask) & ~mask;
@@ -1737,7 +1758,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
                return -ENXIO;
 
        lock_extent_bits(&BTRFS_I(inode)->io_tree, lockstart, lockend, 0,
-                        &cached_state, GFP_NOFS);
+                        &cached_state);
 
        /*
         * Delalloc is such a pain.  If we have a hole and we have pending