From 7e678c18f2d1b5f81eda02c17da42bb9981257fd Mon Sep 17 00:00:00 2001 From: adilger Date: Tue, 9 Aug 2005 20:24:25 +0000 Subject: [PATCH] Branch b1_4 Description: Mounting an ldiskfs file system with mballoc may crash OST node. Details : ldiskfs mballoc code may reference an uninitialized buddy struct at startup during orphan unlinking. Instead, skip buddy update before setup, as it will be regenerated after recovery is complete. b=7264 r=alex --- .../patches/ext3-mballoc2-2.6-suse.patch | 12 ++++++------ .../patches/ext3-mballoc2-2.6.9-rhel4.patch | 20 ++++++++++---------- lustre/ChangeLog | 12 ++++++++++++ .../patches/ext3-mballoc2-2.6-suse.patch | 12 ++++++------ .../patches/ext3-mballoc2-2.6.9-rhel4.patch | 20 ++++++++++---------- 5 files changed, 44 insertions(+), 32 deletions(-) diff --git a/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch b/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch index 107de00..ae22210 100644 --- a/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch +++ b/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch @@ -1850,23 +1850,23 @@ Index: linux-stage/fs/ext3/mballoc.c +} + + -+extern void ext3_free_blocks_old(handle_t *, struct inode *, -+ unsigned long, unsigned long); -+void ext3_free_blocks(handle_t *handle, struct inode * inode, ++extern void ext3_free_blocks_old(handle_t *handle, struct inode *inode, ++ unsigned long block, unsigned long count); ++void ext3_free_blocks(handle_t *handle, struct inode *inode, + unsigned long block, unsigned long count, int metadata) +{ + int freed; + -+ if (!test_opt(inode->i_sb, MBALLOC)) ++ if (!test_opt(inode->i_sb, MBALLOC) || ++ EXT3_SB(inode->i_sb)->s_buddy_blocks == NULL) + ext3_free_blocks_old(handle, inode, block, count); + else { -+ ext3_mb_free_blocks(handle, inode, block, count, metadata, &freed); ++ ext3_mb_free_blocks(handle, inode, block,count,metadata,&freed); + if (freed) + DQUOT_FREE_BLOCK(inode, freed); + } + return; +} -+ Index: linux-stage/fs/ext3/super.c =================================================================== --- linux-stage.orig/fs/ext3/super.c 2005-07-28 16:09:49.624822080 -0400 diff --git a/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch b/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch index 24b2595..c8b3e48 100644 --- a/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch +++ b/ldiskfs/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch @@ -4,7 +4,7 @@ Index: linux-stage/fs/ext3/mballoc.c +++ linux-stage/fs/ext3/mballoc.c 2005-02-25 17:28:41.859307576 +0200 @@ -0,0 +1,1861 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -110,7 +110,7 @@ Index: linux-stage/fs/ext3/mballoc.c + struct super_block *ac_sb; + + /* search goals */ -+struct ext3_free_extent ac_g_ex; ++ struct ext3_free_extent ac_g_ex; + + /* the best found extent */ + struct ext3_free_extent ac_b_ex; @@ -471,7 +471,7 @@ Index: linux-stage/fs/ext3/mballoc.c +} + +static int mb_find_extent(struct ext3_buddy *e3b, int order, int block, -+ int needed, struct ext3_free_extent *ex) ++ int needed, struct ext3_free_extent *ex) +{ + int next, max, ord; + void *buddy; @@ -1849,17 +1849,17 @@ Index: linux-stage/fs/ext3/mballoc.c + return ret; +} + -+void ext3_free_blocks(handle_t *handle, struct inode * inode, -+ unsigned long block, unsigned long count, int metadata) ++void ext3_free_blocks(handle_t *handle, struct inode *inode, ++ unsigned long block, unsigned long count, int metadata) +{ -+ struct super_block *sb; + int freed; + -+ sb = inode->i_sb; -+ if (!test_opt(sb, MBALLOC)) -+ ext3_free_blocks_sb(handle, sb, block, count, &freed); ++ if (!test_opt(inode->i_sb, MBALLOC) || ++ EXT3_SB(inode->i_sb)->s_buddy_blocks == NULL) ++ ext3_free_blocks_sb(handle, inode->i_sb, block, count, &freed); + else -+ ext3_mb_free_blocks(handle, inode, block, count, metadata, &freed); ++ ext3_mb_free_blocks(handle, inode, block,count,metadata,&freed); ++ + if (freed) + DQUOT_FREE_BLOCK(inode, freed); + return; diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 3d5d67a..921eed8 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -1,4 +1,16 @@ tbd Cluster File Systems, Inc. + * version 1.4.5 + * bug fixes + +Severity : major +Frequency : rare +Bugzilla : 7264 +Description: Mounting an ldiskfs file system with mballoc may crash OST node. +Details : ldiskfs mballoc code may reference an uninitialized buddy struct + at startup during orphan unlinking. Instead, skip buddy update + before setup, as it will be regenerated after recovery is complete. + +tbd Cluster File Systems, Inc. * version 1.4.4 * bug fixes diff --git a/lustre/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch b/lustre/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch index 107de00..ae22210 100644 --- a/lustre/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch +++ b/lustre/kernel_patches/patches/ext3-mballoc2-2.6-suse.patch @@ -1850,23 +1850,23 @@ Index: linux-stage/fs/ext3/mballoc.c +} + + -+extern void ext3_free_blocks_old(handle_t *, struct inode *, -+ unsigned long, unsigned long); -+void ext3_free_blocks(handle_t *handle, struct inode * inode, ++extern void ext3_free_blocks_old(handle_t *handle, struct inode *inode, ++ unsigned long block, unsigned long count); ++void ext3_free_blocks(handle_t *handle, struct inode *inode, + unsigned long block, unsigned long count, int metadata) +{ + int freed; + -+ if (!test_opt(inode->i_sb, MBALLOC)) ++ if (!test_opt(inode->i_sb, MBALLOC) || ++ EXT3_SB(inode->i_sb)->s_buddy_blocks == NULL) + ext3_free_blocks_old(handle, inode, block, count); + else { -+ ext3_mb_free_blocks(handle, inode, block, count, metadata, &freed); ++ ext3_mb_free_blocks(handle, inode, block,count,metadata,&freed); + if (freed) + DQUOT_FREE_BLOCK(inode, freed); + } + return; +} -+ Index: linux-stage/fs/ext3/super.c =================================================================== --- linux-stage.orig/fs/ext3/super.c 2005-07-28 16:09:49.624822080 -0400 diff --git a/lustre/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch b/lustre/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch index 24b2595..c8b3e48 100644 --- a/lustre/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch +++ b/lustre/kernel_patches/patches/ext3-mballoc2-2.6.9-rhel4.patch @@ -4,7 +4,7 @@ Index: linux-stage/fs/ext3/mballoc.c +++ linux-stage/fs/ext3/mballoc.c 2005-02-25 17:28:41.859307576 +0200 @@ -0,0 +1,1861 @@ +/* -+ * Copyright (c) 2003, Cluster File Systems, Inc, info@clusterfs.com ++ * Copyright(c) 2003, 2004, 2005, Cluster File Systems, Inc, info@clusterfs.com + * Written by Alex Tomas + * + * This program is free software; you can redistribute it and/or modify @@ -110,7 +110,7 @@ Index: linux-stage/fs/ext3/mballoc.c + struct super_block *ac_sb; + + /* search goals */ -+struct ext3_free_extent ac_g_ex; ++ struct ext3_free_extent ac_g_ex; + + /* the best found extent */ + struct ext3_free_extent ac_b_ex; @@ -471,7 +471,7 @@ Index: linux-stage/fs/ext3/mballoc.c +} + +static int mb_find_extent(struct ext3_buddy *e3b, int order, int block, -+ int needed, struct ext3_free_extent *ex) ++ int needed, struct ext3_free_extent *ex) +{ + int next, max, ord; + void *buddy; @@ -1849,17 +1849,17 @@ Index: linux-stage/fs/ext3/mballoc.c + return ret; +} + -+void ext3_free_blocks(handle_t *handle, struct inode * inode, -+ unsigned long block, unsigned long count, int metadata) ++void ext3_free_blocks(handle_t *handle, struct inode *inode, ++ unsigned long block, unsigned long count, int metadata) +{ -+ struct super_block *sb; + int freed; + -+ sb = inode->i_sb; -+ if (!test_opt(sb, MBALLOC)) -+ ext3_free_blocks_sb(handle, sb, block, count, &freed); ++ if (!test_opt(inode->i_sb, MBALLOC) || ++ EXT3_SB(inode->i_sb)->s_buddy_blocks == NULL) ++ ext3_free_blocks_sb(handle, inode->i_sb, block, count, &freed); + else -+ ext3_mb_free_blocks(handle, inode, block, count, metadata, &freed); ++ ext3_mb_free_blocks(handle, inode, block,count,metadata,&freed); ++ + if (freed) + DQUOT_FREE_BLOCK(inode, freed); + return; -- 1.8.3.1