Whamcloud - gitweb
Branch HEAD
authordzogin <dzogin>
Thu, 5 Nov 2009 22:10:32 +0000 (22:10 +0000)
committerdzogin <dzogin>
Thu, 5 Nov 2009 22:10:32 +0000 (22:10 +0000)
b=21031
i=andrew.perpechko
i=girish.shilamkar
----------------------------------------------------------------------
 Modified Files:
  ldiskfs/ChangeLog
  ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series
  ldiskfs/kernel_patches/series/ldiskfs-2.6-sles10.series
 Added Files:
  ldiskfs/kernel_patches/patches/ext3-corrupted-orphans-2.6.patch
----------------------------------------------------------------------
Description: ext3-corrupted-orphans-2.6.patch added.
Details    : Backport of ext3 patch to handle corrupted orphans.
-------------------------------------------------------------------------------

ldiskfs/ChangeLog
ldiskfs/kernel_patches/patches/ext3-corrupted-orphans-2.6.patch [new file with mode: 0644]
ldiskfs/kernel_patches/series/ldiskfs-2.6-rhel5.series
ldiskfs/kernel_patches/series/ldiskfs-2.6-sles10.series

index 5f13dca..d67c55c 100644 (file)
@@ -1,9 +1,20 @@
 tbd  Sun Microsystems, Inc.
-        * version 3.1.0
+        * version 3.1.1
        
 
 -------------------------------------------------------------------------------
        
+2009-11-05  Sun Microsystems, Inc.
+       * version 3.1.0
+
+Severity   : normal
+Frequency  : in recovery
+Bugzilla   : 21031
+Description: ext3-corrupted-orphans-2.6.patch added.
+Details    : Backport of ext3 patch to handle corrupted orphans.
+
+-------------------------------------------------------------------------------
+       
 2009-07-31  Sun Microsystems, Inc.
        * version 3.0.9
 
diff --git a/ldiskfs/kernel_patches/patches/ext3-corrupted-orphans-2.6.patch b/ldiskfs/kernel_patches/patches/ext3-corrupted-orphans-2.6.patch
new file mode 100644 (file)
index 0000000..607cf1e
--- /dev/null
@@ -0,0 +1,145 @@
+--- linux-2.6.18-128.7.1.orig/include/linux/ext3_fs.h  2006-09-19 23:42:06.000000000 -0400
++++ linux-2.6.18-128.7.1/include/linux/ext3_fs.h       2009-10-12 19:37:54.000000000 -0400
+@@ -809,6 +809,7 @@ extern void ext3_discard_reservation (st
+ extern void ext3_dirty_inode(struct inode *);
+ extern int ext3_change_inode_journal_flag(struct inode *, int);
+ extern int ext3_get_inode_loc(struct inode *, struct ext3_iloc *);
++extern int ext3_can_truncate(struct inode *inode);
+ extern void ext3_truncate (struct inode *);
+ extern void ext3_set_inode_flags(struct inode *);
+ extern void ext3_set_aops(struct inode *inode);
+--- linux-2.6.18-128.7.1.orig/fs/ext3/inode.c  2009-09-15 10:38:31.000000000 -0400
++++ linux-2.6.18-128.7.1/fs/ext3/inode.c       2009-10-12 18:49:01.000000000 -0400
+@@ -2194,6 +2194,19 @@ static void ext3_free_branches(handle_t 
+       }
+ }
++int ext3_can_truncate(struct inode *inode)
++{
++      if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
++              return 0;
++      if (S_ISREG(inode->i_mode))
++              return 1;
++      if (S_ISDIR(inode->i_mode))
++              return 1;
++      if (S_ISLNK(inode->i_mode))
++              return !ext3_inode_is_fast_symlink(inode);
++      return 0;
++}
++
+ /*
+  * ext3_truncate()
+  *
+@@ -2238,12 +2251,7 @@ void ext3_truncate(struct inode *inode)
+       unsigned blocksize = inode->i_sb->s_blocksize;
+       struct page *page;
+-      if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) ||
+-          S_ISLNK(inode->i_mode)))
+-              return;
+-      if (ext3_inode_is_fast_symlink(inode))
+-              return;
+-      if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
++      if (!ext3_can_truncate(inode))
+               return;
+       /*
+--- linux-2.6.18-128.7.1.orig/fs/ext3/ialloc.c 2009-09-15 10:24:17.000000000 -0400
++++ linux-2.6.18-128.7.1/fs/ext3/ialloc.c      2009-10-14 15:36:27.000000000 -0400
+@@ -645,54 +645,71 @@ struct inode *ext3_orphan_get(struct sup
+       unsigned long max_ino = le32_to_cpu(EXT3_SB(sb)->s_es->s_inodes_count);
+       unsigned long block_group;
+       int bit;
+-      struct buffer_head *bitmap_bh = NULL;
++      struct buffer_head *bitmap_bh;
+       struct inode *inode = NULL;
+       /* Error cases - e2fsck has already cleaned up for us */
+       if (ino > max_ino) {
+-              ext3_warning(sb, __FUNCTION__,
++              ext3_warning(sb, __func__,
+                            "bad orphan ino %lu!  e2fsck was run?", ino);
+-              goto out;
++              goto error;
+       }
+       block_group = (ino - 1) / EXT3_INODES_PER_GROUP(sb);
+       bit = (ino - 1) % EXT3_INODES_PER_GROUP(sb);
+       bitmap_bh = read_inode_bitmap(sb, block_group);
+       if (!bitmap_bh) {
+-              ext3_warning(sb, __FUNCTION__,
++              ext3_warning(sb, __func__,
+                            "inode bitmap error for orphan %lu", ino);
+-              goto out;
++              goto error;
+       }
+       /* Having the inode bit set should be a 100% indicator that this
+        * is a valid orphan (no e2fsck run on fs).  Orphans also include
+        * inodes that were being truncated, so we can't check i_nlink==0.
+        */
+-      if (!ext3_test_bit(bit, bitmap_bh->b_data) ||
+-                      !(inode = iget(sb, ino)) || is_bad_inode(inode) ||
+-                      NEXT_ORPHAN(inode) > max_ino) {
+-              ext3_warning(sb, __FUNCTION__,
+-                           "bad orphan inode %lu!  e2fsck was run?", ino);
+-              printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
+-                     bit, (unsigned long long)bitmap_bh->b_blocknr,
+-                     ext3_test_bit(bit, bitmap_bh->b_data));
+-              printk(KERN_NOTICE "inode=%p\n", inode);
+-              if (inode) {
+-                      printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
+-                             is_bad_inode(inode));
+-                      printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n",
+-                             NEXT_ORPHAN(inode));
+-                      printk(KERN_NOTICE "max_ino=%lu\n", max_ino);
+-              }
++      if (!ext3_test_bit(bit, bitmap_bh->b_data))
++              goto bad_orphan;
++
++      inode = iget(sb, ino);
++      if ((inode == NULL) || is_bad_inode(inode))
++              goto bad_orphan;
++
++      /*
++       * If the orphan 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 (inode->i_nlink && !ext3_can_truncate(inode))
++              goto bad_orphan;
++
++      if (NEXT_ORPHAN(inode) > max_ino)
++              goto bad_orphan;
++      brelse(bitmap_bh);
++      return inode;
++
++bad_orphan:
++      ext3_warning(sb, __func__,
++                   "bad orphan inode %lu!  e2fsck was run?", ino);
++      printk(KERN_NOTICE "ext3_test_bit(bit=%d, block=%llu) = %d\n",
++             bit, (unsigned long long)bitmap_bh->b_blocknr,
++             ext3_test_bit(bit, bitmap_bh->b_data));
++      printk(KERN_NOTICE "inode=%p\n", inode);
++      if (inode) {
++              printk(KERN_NOTICE "is_bad_inode(inode)=%d\n",
++                     is_bad_inode(inode));
++              printk(KERN_NOTICE "NEXT_ORPHAN(inode)=%u\n",
++                     NEXT_ORPHAN(inode));
++              printk(KERN_NOTICE "max_ino=%lu\n", max_ino);
++              printk(KERN_NOTICE "i_nlink=%u\n", inode->i_nlink);
+               /* Avoid freeing blocks if we got a bad deleted inode */
+-              if (inode && inode->i_nlink == 0)
++              if (inode->i_nlink == 0)
+                       inode->i_blocks = 0;
+               iput(inode);
+-              inode = NULL;
+       }
+-out:
+       brelse(bitmap_bh);
+-      return inode;
++error:
++      return NULL;
+ }
+ unsigned long ext3_count_free_inodes (struct super_block * sb)
index 8f87b9f..7f61ad5 100644 (file)
@@ -33,5 +33,6 @@ ext3-osd-iam-exports.patch
 ext3-dynlocks-common.patch
 ext3-dynlocks-2.6-rhel5.patch
 ext3-hash-indexed-dir-dotdot-update.patch
+ext3-corrupted-orphans-2.6.patch
 ext3-kill-dx_root.patch
 ext3_data_in_dirent.patch
index 885df46..d9fc687 100644 (file)
@@ -38,3 +38,4 @@ ext3-osd-iam-exports.patch
 ext3-dynlocks-common.patch
 ext3-dynlocks-2.6-rhel5.patch
 ext3-hash-indexed-dir-dotdot-update.patch
+ext3-corrupted-orphans-2.6.patch