ret = btrfs_orphan_reserve_metadata(trans, inode);
                ASSERT(!ret);
                if (ret) {
+                       /*
+                        * dec doesn't need spin_lock as ->orphan_block_rsv
+                        * would be released only if ->orphan_inodes is
+                        * zero.
+                        */
                        atomic_dec(&root->orphan_inodes);
                        clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
                                  &inode->runtime_flags);
        if (insert >= 1) {
                ret = btrfs_insert_orphan_item(trans, root, btrfs_ino(inode));
                if (ret) {
-                       atomic_dec(&root->orphan_inodes);
                        if (reserve) {
                                clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
                                          &inode->runtime_flags);
                                btrfs_orphan_release_metadata(inode);
                        }
+                       /*
+                        * btrfs_orphan_commit_root may race with us and set
+                        * ->orphan_block_rsv to zero, in order to avoid that,
+                        * decrease ->orphan_inodes after everything is done.
+                        */
+                       atomic_dec(&root->orphan_inodes);
                        if (ret != -EEXIST) {
                                clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
                                          &inode->runtime_flags);
 {
        struct btrfs_root *root = inode->root;
        int delete_item = 0;
-       int release_rsv = 0;
        int ret = 0;
 
-       spin_lock(&root->orphan_lock);
        if (test_and_clear_bit(BTRFS_INODE_HAS_ORPHAN_ITEM,
                               &inode->runtime_flags))
                delete_item = 1;
 
+       if (delete_item && trans)
+               ret = btrfs_del_orphan_item(trans, root, btrfs_ino(inode));
+
        if (test_and_clear_bit(BTRFS_INODE_ORPHAN_META_RESERVED,
                               &inode->runtime_flags))
-               release_rsv = 1;
-       spin_unlock(&root->orphan_lock);
+               btrfs_orphan_release_metadata(inode);
 
-       if (delete_item) {
+       /*
+        * btrfs_orphan_commit_root may race with us and set ->orphan_block_rsv
+        * to zero, in order to avoid that, decrease ->orphan_inodes after
+        * everything is done.
+        */
+       if (delete_item)
                atomic_dec(&root->orphan_inodes);
-               if (trans)
-                       ret = btrfs_del_orphan_item(trans, root,
-                                                   btrfs_ino(inode));
-       }
-
-       if (release_rsv)
-               btrfs_orphan_release_metadata(inode);
 
        return ret;
 }