btrfs: Remove extent_io_ops::split_extent_hook callback
[sfrench/cifs-2.6.git] / fs / btrfs / inode.c
index d3df5b52278cea06c05384ef7bf63aaed6b5404f..a097f5fde31df5c6829375bff9f79d84104c60d7 100644 (file)
@@ -109,8 +109,8 @@ static void __endio_write_update_ordered(struct inode *inode,
  * extent_clear_unlock_delalloc() to clear both the bits EXTENT_DO_ACCOUNTING
  * and EXTENT_DELALLOC simultaneously, because that causes the reserved metadata
  * to be released, which we want to happen only when finishing the ordered
- * extent (btrfs_finish_ordered_io()). Also note that the caller of the
- * fill_delalloc() callback already does proper cleanup for the first page of
+ * extent (btrfs_finish_ordered_io()). Also note that the caller of
+ * btrfs_run_delalloc_range already does proper cleanup for the first page of
  * the range, that is, it invokes the callback writepage_end_io_hook() for the
  * range of the first page.
  */
@@ -847,14 +847,14 @@ retry:
                                    ins.offset, async_extent->pages,
                                    async_extent->nr_pages,
                                    async_cow->write_flags)) {
-                       struct extent_io_tree *tree = &BTRFS_I(inode)->io_tree;
                        struct page *p = async_extent->pages[0];
                        const u64 start = async_extent->start;
                        const u64 end = start + async_extent->ram_size - 1;
 
                        p->mapping = inode->i_mapping;
-                       tree->ops->writepage_end_io_hook(p, start, end,
-                                                        NULL, 0);
+                       btrfs_writepage_endio_finish_ordered(p, start, end,
+                                                            NULL, 0);
+
                        p->mapping = NULL;
                        extent_clear_unlock_delalloc(inode, start, end, end,
                                                     NULL, 0,
@@ -1531,12 +1531,11 @@ out_check:
        }
        btrfs_release_path(path);
 
-       if (cur_offset <= end && cow_start == (u64)-1) {
+       if (cur_offset <= end && cow_start == (u64)-1)
                cow_start = cur_offset;
-               cur_offset = end;
-       }
 
        if (cow_start != (u64)-1) {
+               cur_offset = end;
                ret = cow_file_range(inode, locked_page, cow_start, end, end,
                                     page_started, nr_written, 1, NULL);
                if (ret)
@@ -1577,12 +1576,12 @@ static inline int need_force_cow(struct inode *inode, u64 start, u64 end)
 }
 
 /*
- * extent_io.c call back to do delayed allocation processing
+ * Function to process delayed allocation (create CoW) for ranges which are
+ * being touched for the first time.
  */
-static int run_delalloc_range(void *private_data, struct page *locked_page,
-                             u64 start, u64 end, int *page_started,
-                             unsigned long *nr_written,
-                             struct writeback_control *wbc)
+int btrfs_run_delalloc_range(void *private_data, struct page *locked_page,
+               u64 start, u64 end, int *page_started, unsigned long *nr_written,
+               struct writeback_control *wbc)
 {
        struct inode *inode = private_data;
        int ret;
@@ -1610,10 +1609,9 @@ static int run_delalloc_range(void *private_data, struct page *locked_page,
        return ret;
 }
 
-static void btrfs_split_extent_hook(void *private_data,
-                                   struct extent_state *orig, u64 split)
+void btrfs_split_delalloc_extent(struct inode *inode,
+                                struct extent_state *orig, u64 split)
 {
-       struct inode *inode = private_data;
        u64 size;
 
        /* not delalloc, ignore it */
@@ -1626,7 +1624,7 @@ static void btrfs_split_extent_hook(void *private_data,
                u64 new_size;
 
                /*
-                * See the explanation in btrfs_merge_extent_hook, the same
+                * See the explanation in btrfs_merge_delalloc_extent, the same
                 * applies here, just in reverse.
                 */
                new_size = orig->end - split + 1;
@@ -1643,16 +1641,13 @@ static void btrfs_split_extent_hook(void *private_data,
 }
 
 /*
- * extent_io.c merge_extent_hook, used to track merged delayed allocation
- * extents so we can keep track of new extents that are just merged onto old
- * extents, such as when we are doing sequential writes, so we can properly
- * account for the metadata space we'll need.
+ * Handle merged delayed allocation extents so we can keep track of new extents
+ * that are just merged onto old extents, such as when we are doing sequential
+ * writes, so we can properly account for the metadata space we'll need.
  */
-static void btrfs_merge_extent_hook(void *private_data,
-                                   struct extent_state *new,
-                                   struct extent_state *other)
+void btrfs_merge_delalloc_extent(struct inode *inode, struct extent_state *new,
+                                struct extent_state *other)
 {
-       struct inode *inode = private_data;
        u64 new_size, old_size;
        u32 num_extents;
 
@@ -1756,15 +1751,12 @@ static void btrfs_del_delalloc_inode(struct btrfs_root *root,
 }
 
 /*
- * extent_io.c set_bit_hook, used to track delayed allocation
- * bytes in this file, and to maintain the list of inodes that
- * have pending delalloc work to be done.
+ * Properly track delayed allocation bytes in the inode and to maintain the
+ * list of inodes that have pending delalloc work to be done.
  */
-static void btrfs_set_bit_hook(void *private_data,
-                              struct extent_state *state, unsigned *bits)
+void btrfs_set_delalloc_extent(struct inode *inode, struct extent_state *state,
+                              unsigned *bits)
 {
-       struct inode *inode = private_data;
-
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
 
        if ((*bits & EXTENT_DEFRAG) && !(*bits & EXTENT_DELALLOC))
@@ -1810,14 +1802,14 @@ static void btrfs_set_bit_hook(void *private_data,
 }
 
 /*
- * extent_io.c clear_bit_hook, see set_bit_hook for why
+ * Once a range is no longer delalloc this function ensures that proper
+ * accounting happens.
  */
-static void btrfs_clear_bit_hook(void *private_data,
-                                struct extent_state *state,
-                                unsigned *bits)
+void btrfs_clear_delalloc_extent(struct inode *vfs_inode,
+                                struct extent_state *state, unsigned *bits)
 {
-       struct btrfs_inode *inode = BTRFS_I((struct inode *)private_data);
-       struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
+       struct btrfs_inode *inode = BTRFS_I(vfs_inode);
+       struct btrfs_fs_info *fs_info = btrfs_sb(vfs_inode->i_sb);
        u64 len = state->end + 1 - state->start;
        u32 num_extents = count_max_extents(len);
 
@@ -2153,7 +2145,7 @@ out_page:
  * to fix it up.  The async helper will wait for ordered extents, set
  * the delalloc bit and make it safe to write the page.
  */
-static int btrfs_writepage_start_hook(struct page *page, u64 start, u64 end)
+int btrfs_writepage_cow_fixup(struct page *page, u64 start, u64 end)
 {
        struct inode *inode = page->mapping->host;
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
@@ -3160,7 +3152,7 @@ static void finish_ordered_fn(struct btrfs_work *work)
        btrfs_finish_ordered_io(ordered_extent);
 }
 
-static void btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end,
+void btrfs_writepage_endio_finish_ordered(struct page *page, u64 start, u64 end,
                                struct extent_state *state, int uptodate)
 {
        struct inode *inode = page->mapping->host;
@@ -3570,10 +3562,11 @@ static noinline int acls_after_inode_item(struct extent_buffer *leaf,
 /*
  * read an inode from the btree into the in-memory inode
  */
-static int btrfs_read_locked_inode(struct inode *inode)
+static int btrfs_read_locked_inode(struct inode *inode,
+                                  struct btrfs_path *in_path)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
-       struct btrfs_path *path;
+       struct btrfs_path *path = in_path;
        struct extent_buffer *leaf;
        struct btrfs_inode_item *inode_item;
        struct btrfs_root *root = BTRFS_I(inode)->root;
@@ -3589,15 +3582,18 @@ static int btrfs_read_locked_inode(struct inode *inode)
        if (!ret)
                filled = true;
 
-       path = btrfs_alloc_path();
-       if (!path)
-               return -ENOMEM;
+       if (!path) {
+               path = btrfs_alloc_path();
+               if (!path)
+                       return -ENOMEM;
+       }
 
        memcpy(&location, &BTRFS_I(inode)->location, sizeof(location));
 
        ret = btrfs_lookup_inode(NULL, root, path, &location, 0);
        if (ret) {
-               btrfs_free_path(path);
+               if (path != in_path)
+                       btrfs_free_path(path);
                return ret;
        }
 
@@ -3722,7 +3718,8 @@ cache_acl:
                                  btrfs_ino(BTRFS_I(inode)),
                                  root->root_key.objectid, ret);
        }
-       btrfs_free_path(path);
+       if (path != in_path)
+               btrfs_free_path(path);
 
        if (!maybe_acls)
                cache_no_acl(inode);
@@ -5644,8 +5641,9 @@ static struct inode *btrfs_iget_locked(struct super_block *s,
 /* Get an inode object given its location and corresponding root.
  * Returns in *is_new if the inode was read from disk
  */
-struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
-                        struct btrfs_root *root, int *new)
+struct inode *btrfs_iget_path(struct super_block *s, struct btrfs_key *location,
+                             struct btrfs_root *root, int *new,
+                             struct btrfs_path *path)
 {
        struct inode *inode;
 
@@ -5656,7 +5654,7 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
        if (inode->i_state & I_NEW) {
                int ret;
 
-               ret = btrfs_read_locked_inode(inode);
+               ret = btrfs_read_locked_inode(inode, path);
                if (!ret) {
                        inode_tree_add(inode);
                        unlock_new_inode(inode);
@@ -5678,6 +5676,12 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
        return inode;
 }
 
+struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location,
+                        struct btrfs_root *root, int *new)
+{
+       return btrfs_iget_path(s, location, root, new, NULL);
+}
+
 static struct inode *new_simple_dir(struct super_block *s,
                                    struct btrfs_key *key,
                                    struct btrfs_root *root)
@@ -10440,20 +10444,6 @@ static int btrfs_readpage_io_failed_hook(struct page *page, int failed_mirror)
        return -EAGAIN;
 }
 
-static void btrfs_check_extent_io_range(void *private_data, const char *caller,
-                                       u64 start, u64 end)
-{
-       struct inode *inode = private_data;
-       u64 isize;
-
-       isize = i_size_read(inode);
-       if (end >= PAGE_SIZE && (end % 2) == 0 && end != isize - 1) {
-               btrfs_debug_rl(BTRFS_I(inode)->root->fs_info,
-                   "%s: ino %llu isize %llu odd range [%llu,%llu]",
-                       caller, btrfs_ino(BTRFS_I(inode)), isize, start, end);
-       }
-}
-
 void btrfs_set_range_writeback(struct extent_io_tree *tree, u64 start, u64 end)
 {
        struct inode *inode = tree->private_data;
@@ -10513,16 +10503,6 @@ static const struct extent_io_ops btrfs_extent_io_ops = {
        .submit_bio_hook = btrfs_submit_bio_hook,
        .readpage_end_io_hook = btrfs_readpage_end_io_hook,
        .readpage_io_failed_hook = btrfs_readpage_io_failed_hook,
-
-       /* optional callbacks */
-       .fill_delalloc = run_delalloc_range,
-       .writepage_end_io_hook = btrfs_writepage_end_io_hook,
-       .writepage_start_hook = btrfs_writepage_start_hook,
-       .set_bit_hook = btrfs_set_bit_hook,
-       .clear_bit_hook = btrfs_clear_bit_hook,
-       .merge_extent_hook = btrfs_merge_extent_hook,
-       .split_extent_hook = btrfs_split_extent_hook,
-       .check_extent_io_range = btrfs_check_extent_io_range,
 };
 
 /*