btrfs: Split btrfs_del_delalloc_inode into 2 functions
[sfrench/cifs-2.6.git] / fs / btrfs / inode.c
index 6c08c03fc03cec5a8c719583532611d73783f0a2..8e604e7071f14cf166652369e6f167fab5b5f462 100644 (file)
@@ -1,19 +1,6 @@
+// SPDX-License-Identifier: GPL-2.0
 /*
  * Copyright (C) 2007 Oracle.  All rights reserved.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public
- * License v2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public
- * License along with this program; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 021110-1307, USA.
  */
 
 #include <linux/kernel.h>
@@ -44,6 +31,7 @@
 #include <linux/uio.h>
 #include <linux/magic.h>
 #include <linux/iversion.h>
+#include <asm/unaligned.h>
 #include "ctree.h"
 #include "disk-io.h"
 #include "transaction.h"
@@ -1754,12 +1742,12 @@ static void btrfs_add_delalloc_inodes(struct btrfs_root *root,
        spin_unlock(&root->delalloc_lock);
 }
 
-static void btrfs_del_delalloc_inode(struct btrfs_root *root,
-                                    struct btrfs_inode *inode)
+
+void __btrfs_del_delalloc_inode(struct btrfs_root *root,
+                               struct btrfs_inode *inode)
 {
        struct btrfs_fs_info *fs_info = btrfs_sb(inode->vfs_inode.i_sb);
 
-       spin_lock(&root->delalloc_lock);
        if (!list_empty(&inode->delalloc_inodes)) {
                list_del_init(&inode->delalloc_inodes);
                clear_bit(BTRFS_INODE_IN_DELALLOC_LIST,
@@ -1772,6 +1760,13 @@ static void btrfs_del_delalloc_inode(struct btrfs_root *root,
                        spin_unlock(&fs_info->delalloc_root_lock);
                }
        }
+}
+
+static void btrfs_del_delalloc_inode(struct btrfs_root *root,
+                                    struct btrfs_inode *inode)
+{
+       spin_lock(&root->delalloc_lock);
+       __btrfs_del_delalloc_inode(root, inode);
        spin_unlock(&root->delalloc_lock);
 }
 
@@ -1867,7 +1862,7 @@ static void btrfs_clear_bit_hook(void *private_data,
                 */
                if (*bits & EXTENT_CLEAR_META_RESV &&
                    root != fs_info->tree_root)
-                       btrfs_delalloc_release_metadata(inode, len);
+                       btrfs_delalloc_release_metadata(inode, len, false);
 
                /* For sanity tests. */
                if (btrfs_is_testing(fs_info))
@@ -2152,7 +2147,7 @@ again:
 
        ClearPageChecked(page);
        set_page_dirty(page);
-       btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+       btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, false);
 out:
        unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end,
                             &cached_state);
@@ -2772,12 +2767,10 @@ static void relink_file_extents(struct new_sa_defrag_extent *new)
        struct sa_defrag_extent_backref *backref;
        struct sa_defrag_extent_backref *prev = NULL;
        struct inode *inode;
-       struct btrfs_root *root;
        struct rb_node *node;
        int ret;
 
        inode = new->inode;
-       root = BTRFS_I(inode)->root;
 
        path = btrfs_alloc_path();
        if (!path)
@@ -3368,7 +3361,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
        struct btrfs_root *root = inode->root;
        struct btrfs_block_rsv *block_rsv = NULL;
        int reserve = 0;
-       int insert = 0;
+       bool insert = false;
        int ret;
 
        if (!root->orphan_block_rsv) {
@@ -3379,20 +3372,8 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
        }
 
        if (!test_and_set_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
-                             &inode->runtime_flags)) {
-#if 0
-               /*
-                * For proper ENOSPC handling, we should do orphan
-                * cleanup when mounting. But this introduces backward
-                * compatibility issue.
-                */
-               if (!xchg(&root->orphan_item_inserted, 1))
-                       insert = 2;
-               else
-                       insert = 1;
-#endif
-               insert = 1;
-       }
+                             &inode->runtime_flags))
+               insert = true;
 
        if (!test_and_set_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
                              &inode->runtime_flags))
@@ -3432,7 +3413,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
        }
 
        /* insert an orphan item to track this unlinked/truncated file */
-       if (insert >= 1) {
+       if (insert) {
                ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode));
                if (ret) {
                        if (reserve) {
@@ -3456,15 +3437,6 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans,
                ret = 0;
        }
 
-       /* insert an orphan item to track subvolume contains orphan files */
-       if (insert >= 2) {
-               ret = btrfs_insert_orphan_item(trans, fs_info->tree_root,
-                                              root->root_key.objectid);
-               if (ret && ret != -EEXIST) {
-                       btrfs_abort_transaction(trans, ret);
-                       return ret;
-               }
-       }
        return 0;
 }
 
@@ -4732,7 +4704,6 @@ delete:
                                if (updates) {
                                        trans->delayed_ref_updates = 0;
                                        ret = btrfs_run_delayed_refs(trans,
-                                                                  fs_info,
                                                                   updates * 2);
                                        if (ret && !err)
                                                err = ret;
@@ -4772,8 +4743,7 @@ error:
                unsigned long updates = trans->delayed_ref_updates;
                if (updates) {
                        trans->delayed_ref_updates = 0;
-                       ret = btrfs_run_delayed_refs(trans, fs_info,
-                                                    updates * 2);
+                       ret = btrfs_run_delayed_refs(trans, updates * 2);
                        if (ret && !err)
                                err = ret;
                }
@@ -4827,8 +4797,8 @@ again:
        page = find_or_create_page(mapping, index, mask);
        if (!page) {
                btrfs_delalloc_release_space(inode, data_reserved,
-                                            block_start, blocksize);
-               btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize);
+                                            block_start, blocksize, true);
+               btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize, true);
                ret = -ENOMEM;
                goto out;
        }
@@ -4895,8 +4865,8 @@ again:
 out_unlock:
        if (ret)
                btrfs_delalloc_release_space(inode, data_reserved, block_start,
-                                            blocksize);
-       btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize);
+                                            blocksize, true);
+       btrfs_delalloc_release_extents(BTRFS_I(inode), blocksize, (ret != 0));
        unlock_page(page);
        put_page(page);
 out:
@@ -5943,11 +5913,13 @@ static int btrfs_filldir(void *addr, int entries, struct dir_context *ctx)
                struct dir_entry *entry = addr;
                char *name = (char *)(entry + 1);
 
-               ctx->pos = entry->offset;
-               if (!dir_emit(ctx, name, entry->name_len, entry->ino,
-                             entry->type))
+               ctx->pos = get_unaligned(&entry->offset);
+               if (!dir_emit(ctx, name, get_unaligned(&entry->name_len),
+                                        get_unaligned(&entry->ino),
+                                        get_unaligned(&entry->type)))
                        return 1;
-               addr += sizeof(struct dir_entry) + entry->name_len;
+               addr += sizeof(struct dir_entry) +
+                       get_unaligned(&entry->name_len);
                ctx->pos++;
        }
        return 0;
@@ -6037,14 +6009,15 @@ again:
                }
 
                entry = addr;
-               entry->name_len = name_len;
+               put_unaligned(name_len, &entry->name_len);
                name_ptr = (char *)(entry + 1);
                read_extent_buffer(leaf, name_ptr, (unsigned long)(di + 1),
                                   name_len);
-               entry->type = btrfs_filetype_table[btrfs_dir_type(leaf, di)];
+               put_unaligned(btrfs_filetype_table[btrfs_dir_type(leaf, di)],
+                               &entry->type);
                btrfs_dir_item_key_to_cpu(leaf, di, &location);
-               entry->ino = location.objectid;
-               entry->offset = found_key.offset;
+               put_unaligned(location.objectid, &entry->ino);
+               put_unaligned(found_key.offset, &entry->offset);
                entries++;
                addr += sizeof(struct dir_entry) + name_len;
                total_len += sizeof(struct dir_entry) + name_len;
@@ -8661,7 +8634,7 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
                if (ret < 0 && ret != -EIOCBQUEUED) {
                        if (dio_data.reserve)
                                btrfs_delalloc_release_space(inode, data_reserved,
-                                       offset, dio_data.reserve);
+                                       offset, dio_data.reserve, true);
                        /*
                         * On error we might have left some ordered extents
                         * without submitting corresponding bios for them, so
@@ -8677,8 +8650,8 @@ static ssize_t btrfs_direct_IO(struct kiocb *iocb, struct iov_iter *iter)
                                        false);
                } else if (ret >= 0 && (size_t)ret < count)
                        btrfs_delalloc_release_space(inode, data_reserved,
-                                       offset, count - (size_t)ret);
-               btrfs_delalloc_release_extents(BTRFS_I(inode), count);
+                                       offset, count - (size_t)ret, true);
+               btrfs_delalloc_release_extents(BTRFS_I(inode), count, false);
        }
 out:
        if (wakeup)
@@ -8993,7 +8966,8 @@ again:
                if (reserved_space < PAGE_SIZE) {
                        end = page_start + reserved_space - 1;
                        btrfs_delalloc_release_space(inode, data_reserved,
-                                       page_start, PAGE_SIZE - reserved_space);
+                                       page_start, PAGE_SIZE - reserved_space,
+                                       true);
                }
        }
 
@@ -9043,16 +9017,16 @@ again:
 
 out_unlock:
        if (!ret) {
-               btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+               btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, true);
                sb_end_pagefault(inode->i_sb);
                extent_changeset_free(data_reserved);
                return VM_FAULT_LOCKED;
        }
        unlock_page(page);
 out:
-       btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE);
+       btrfs_delalloc_release_extents(BTRFS_I(inode), PAGE_SIZE, (ret != 0));
        btrfs_delalloc_release_space(inode, data_reserved, page_start,
-                                    reserved_space);
+                                    reserved_space, (ret != 0));
 out_noreserve:
        sb_end_pagefault(inode->i_sb);
        extent_changeset_free(data_reserved);