Upgrade to 4.4.50-rt62
[kvmfornfv.git] / kernel / fs / ext4 / ialloc.c
index 53f2b98..5388207 100644 (file)
@@ -1143,25 +1143,20 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
        unsigned long max_ino = le32_to_cpu(EXT4_SB(sb)->s_es->s_inodes_count);
        ext4_group_t block_group;
        int bit;
-       struct buffer_head *bitmap_bh;
+       struct buffer_head *bitmap_bh = NULL;
        struct inode *inode = NULL;
-       long err = -EIO;
+       int err = -EFSCORRUPTED;
 
-       /* Error cases - e2fsck has already cleaned up for us */
-       if (ino > max_ino) {
-               ext4_warning(sb, "bad orphan ino %lu!  e2fsck was run?", ino);
-               err = -EFSCORRUPTED;
-               goto error;
-       }
+       if (ino < EXT4_FIRST_INO(sb) || ino > max_ino)
+               goto bad_orphan;
 
        block_group = (ino - 1) / EXT4_INODES_PER_GROUP(sb);
        bit = (ino - 1) % EXT4_INODES_PER_GROUP(sb);
        bitmap_bh = ext4_read_inode_bitmap(sb, block_group);
        if (IS_ERR(bitmap_bh)) {
-               err = PTR_ERR(bitmap_bh);
-               ext4_warning(sb, "inode bitmap error %ld for orphan %lu",
-                            ino, err);
-               goto error;
+               ext4_error(sb, "inode bitmap error %ld for orphan %lu",
+                          ino, PTR_ERR(bitmap_bh));
+               return (struct inode *) bitmap_bh;
        }
 
        /* Having the inode bit set should be a 100% indicator that this
@@ -1172,15 +1167,21 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
                goto bad_orphan;
 
        inode = ext4_iget(sb, ino);
-       if (IS_ERR(inode))
-               goto iget_failed;
+       if (IS_ERR(inode)) {
+               err = PTR_ERR(inode);
+               ext4_error(sb, "couldn't read orphan inode %lu (err %d)",
+                          ino, err);
+               return inode;
+       }
 
        /*
-        * If the orphans has i_nlinks > 0 then it should be able to be
-        * truncated, otherwise it won't be removed from the orphan list
-        * during processing and an infinite loop will result.
+        * If the orphans has i_nlinks > 0 then it should be able to
+        * be truncated, otherwise it won't be removed from the orphan
+        * list during processing and an infinite loop will result.
+        * Similarly, it must not be a bad inode.
         */
-       if (inode->i_nlink && !ext4_can_truncate(inode))
+       if ((inode->i_nlink && !ext4_can_truncate(inode)) ||
+           is_bad_inode(inode))
                goto bad_orphan;
 
        if (NEXT_ORPHAN(inode) > max_ino)
@@ -1188,29 +1189,25 @@ struct inode *ext4_orphan_get(struct super_block *sb, unsigned long ino)
        brelse(bitmap_bh);
        return inode;
 
-iget_failed:
-       err = PTR_ERR(inode);
-       inode = NULL;
 bad_orphan:
-       ext4_warning(sb, "bad orphan inode %lu!  e2fsck was run?", ino);
-       printk(KERN_WARNING "ext4_test_bit(bit=%d, block=%llu) = %d\n",
-              bit, (unsigned long long)bitmap_bh->b_blocknr,
-              ext4_test_bit(bit, bitmap_bh->b_data));
-       printk(KERN_WARNING "inode=%p\n", inode);
+       ext4_error(sb, "bad orphan inode %lu", ino);
+       if (bitmap_bh)
+               printk(KERN_ERR "ext4_test_bit(bit=%d, block=%llu) = %d\n",
+                      bit, (unsigned long long)bitmap_bh->b_blocknr,
+                      ext4_test_bit(bit, bitmap_bh->b_data));
        if (inode) {
-               printk(KERN_WARNING "is_bad_inode(inode)=%d\n",
+               printk(KERN_ERR "is_bad_inode(inode)=%d\n",
                       is_bad_inode(inode));
-               printk(KERN_WARNING "NEXT_ORPHAN(inode)=%u\n",
+               printk(KERN_ERR "NEXT_ORPHAN(inode)=%u\n",
                       NEXT_ORPHAN(inode));
-               printk(KERN_WARNING "max_ino=%lu\n", max_ino);
-               printk(KERN_WARNING "i_nlink=%u\n", inode->i_nlink);
+               printk(KERN_ERR "max_ino=%lu\n", max_ino);
+               printk(KERN_ERR "i_nlink=%u\n", inode->i_nlink);
                /* Avoid freeing blocks if we got a bad deleted inode */
                if (inode->i_nlink == 0)
                        inode->i_blocks = 0;
                iput(inode);
        }
        brelse(bitmap_bh);
-error:
        return ERR_PTR(err);
 }