Btrfs: fix tracking of orphan inode count
authorFilipe David Borba Manana <fdmanana@gmail.com>
Sun, 22 Sep 2013 20:54:55 +0000 (21:54 +0100)
committerChris Mason <chris.mason@fusionio.com>
Tue, 12 Nov 2013 02:53:01 +0000 (21:53 -0500)
In inode.c:btrfs_orphan_add() if we failed to insert the orphan
item, we would return without decrementing the orphan count that
we just incremented before attempting the insertion, leaving the
orphan inode count wrong.

In inode.c:btrfs_orphan_del(), we were decrementing the inode
orphan count if the bit BTRFS_INODE_ORPHAN_META_RESERVED was set,
which is logically wrong because it should be decremented if the
bit BTRFS_INODE_HAS_ORPHAN_ITEM was set - after all we increment
the count when we set the bit BTRFS_INODE_HAS_ORPHAN_ITEM elsewhere.

Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com>
Signed-off-by: Josef Bacik <jbacik@fusionio.com>
Signed-off-by: Chris Mason <chris.mason@fusionio.com>
fs/btrfs/inode.c

index 57b27012d43a24f4ba60cbe682c4b33fa63723c9..939dd1ff34a7b93dbc08bf00f951786f6bd61a2a 100644 (file)
@@ -2969,6 +2969,7 @@ int btrfs_orphan_add(struct btrfs_trans_handle *trans, struct inode *inode)
        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,
                                          &BTRFS_I(inode)->runtime_flags);
@@ -3018,14 +3019,16 @@ static int btrfs_orphan_del(struct btrfs_trans_handle *trans,
                release_rsv = 1;
        spin_unlock(&root->orphan_lock);
 
-       if (trans && delete_item)
-               ret = btrfs_del_orphan_item(trans, root, btrfs_ino(inode));
-
-       if (release_rsv) {
-               btrfs_orphan_release_metadata(inode);
+       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;
 }