From 19d0394c22ea5927ec085fa9161f79f2537d58ef Mon Sep 17 00:00:00 2001 From: adilger Date: Mon, 9 Feb 2004 22:29:42 +0000 Subject: [PATCH] Fix for failed assertion in iopen_connect_dentry (2.4 kernels only, from b1_0). b=1792, b=2517 --- lustre/ChangeLog | 26 ++-- .../patches/ext3-noread-2.4.20.patch | 154 ++++++++++----------- .../patches/ext3-noread-2.4.21-chaos.patch | 138 +++++++++--------- .../patches/ext3-noread-2.4.21-suse2.patch | 138 +++++++++--------- lustre/kernel_patches/patches/iopen-2.4.18-2.patch | 90 ++++++------ lustre/kernel_patches/patches/iopen-2.4.18.patch | 86 +++++++----- .../kernel_patches/patches/iopen-2.4.19-suse.patch | 88 +++++++----- lustre/kernel_patches/patches/iopen-2.4.20.patch | 146 +++++++++++-------- .../patches/iopen-2.4.21-chaos.patch | 88 +++++++----- .../patches/vfs_intent-2.4.18-18-chaos65.patch | 16 +-- .../patches/vfs_intent-2.4.19-pre1.patch | 14 +- .../patches/vfs_intent-2.4.19-suse.patch | 14 +- .../patches/vfs_intent-2.4.20-hp.patch | 14 +- .../patches/vfs_intent-2.4.20-vanilla.patch | 4 +- .../patches/vfs_intent-2.4.21-chaos.patch | 4 +- .../patches/vfs_intent-2.4.21-suse2.patch | 4 +- .../patches/vfs_intent-2.4.22-rh.patch | 4 +- .../patches/vfs_intent_2.6.0-test1.patch | 12 +- .../patches/vfs_intent_2.6.0-test6.patch | 12 +- .../kernel_patches/patches/vfs_intent_2.6.0.patch | 12 +- 20 files changed, 572 insertions(+), 492 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 021e734..8999bec 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -1,16 +1,22 @@ tbd Cluster File Systems, Inc. * version 1.2.0 * bug fixes - - reduce journal credits needed for BRW writes (2370) - - orphan handling to avoid losing space on client/server crashes - - ptlrpcd can be blocked, stopping ALL progress (2477) - - recovery for initial connections (2355) - - orphan recovery problems in b_eq (1934) - - block all file creations until orphan recovery completes (1901) - - client remove rq_connection from request struct (2423) - - conf-sanity test_5, proper cleanup in umount log not availale (2640) - - recovery timer race (2670) - - mdc_close recovey bug (2532) + - reduce journal credits needed for BRW writes (2370) + - orphan handling to avoid losing space on client/server crashes + - ptlrpcd can be blocked, stopping ALL progress (2477) + - recovery for initial connections (2355) + - orphan recovery problems in b_eq (1934) + - block all file creations until orphan recovery completes (1901) + - client remove rq_connection from request struct (2423) + - conf-sanity test_5, proper cleanup in umount log not availale (2640) + - recovery timer race (2670) + - mdc_close recovey bug (2532) + +2004-02-06 Cluster File Systems, Inc. + * version 1.0.4 + * kernel patches + - fix for failed assertion in iopen_connect_dentry (1792,2517) + 2004-01-27 Cluster File Systems, Inc. * version 1.0.3 diff --git a/lustre/kernel_patches/patches/ext3-noread-2.4.20.patch b/lustre/kernel_patches/patches/ext3-noread-2.4.20.patch index b14b869..f8270b2 100644 --- a/lustre/kernel_patches/patches/ext3-noread-2.4.20.patch +++ b/lustre/kernel_patches/patches/ext3-noread-2.4.20.patch @@ -57,18 +57,18 @@ inode->u.ext3_i.i_state = EXT3_STATE_NEW; - err = ext3_mark_inode_dirty(handle, inode); - if (err) goto fail; -+ err = ext3_get_inode_loc_new(inode, &iloc, 1); -+ if (err) goto fail; -+ BUFFER_TRACE(iloc->bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, iloc.bh); -+ if (err) { -+ brelse(iloc.bh); -+ iloc.bh = NULL; -+ goto fail; -+ } -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; -+ ++ err = ext3_get_inode_loc_new(inode, &iloc, 1); ++ if (err) goto fail; ++ BUFFER_TRACE(iloc->bh, "get_write_access"); ++ err = ext3_journal_get_write_access(handle, iloc.bh); ++ if (err) { ++ brelse(iloc.bh); ++ iloc.bh = NULL; ++ goto fail; ++ } ++ err = ext3_mark_iloc_dirty(handle, inode, &iloc); ++ if (err) goto fail; ++ + unlock_super (sb); @@ -86,19 +86,19 @@ - -int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc) +#define NUM_INODE_PREREAD 16 -+ ++ +/* -+ * ext3_get_inode_loc returns with an extra refcount against the inode's -+ * underlying buffer_head on success. If this is for a new inode allocation -+ * (new is non-zero) then we may be able to optimize away the read if there -+ * are no other in-use inodes in this inode table block. If we need to do -+ * a read, then read in a whole chunk of blocks to avoid blocking again soon -+ * if we are doing lots of creates/updates. -+ */ ++ * ext3_get_inode_loc returns with an extra refcount against the inode's ++ * underlying buffer_head on success. If this is for a new inode allocation ++ * (new is non-zero) then we may be able to optimize away the read if there ++ * are no other in-use inodes in this inode table block. If we need to do ++ * a read, then read in a whole chunk of blocks to avoid blocking again soon ++ * if we are doing lots of creates/updates. ++ */ +int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new) { - struct buffer_head *bh = 0; -+ struct buffer_head *bh[NUM_INODE_PREREAD]; ++ struct buffer_head *bh[NUM_INODE_PREREAD]; unsigned long block; unsigned long block_group; unsigned long group_desc; @@ -115,7 +115,7 @@ } - gdp = (struct ext3_group_desc *) bh->b_data; -+ gdp = (struct ext3_group_desc *)(inode->i_sb->u.ext3_sb.s_group_desc[group_desc]->b_data); ++ gdp = (struct ext3_group_desc *)(inode->i_sb->u.ext3_sb.s_group_desc[group_desc]->b_data); /* * Figure out the offset within the block group inode table */ @@ -132,62 +132,62 @@ - goto bad_inode; - } - offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1); -+ (offset * EXT3_INODE_SIZE(inode->i_sb) >> EXT3_BLOCK_SIZE_BITS(inode->i_sb)); ++ (offset * EXT3_INODE_SIZE(inode->i_sb) >> EXT3_BLOCK_SIZE_BITS(inode->i_sb)); - iloc->bh = bh; - iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset); -+ bh[0] = sb_getblk(inode->i_sb, block); -+ if (buffer_uptodate(bh[0])) -+ goto done; -+ -+ /* If we don't really need to read this block, and it isn't already -+ * in memory, then we just zero it out. Otherwise, we keep the -+ * current block contents (deleted inode data) for posterity. -+ */ -+ if (new && !ext3_itable_block_used(inode->i_sb, block_group, offset)) { -+ lock_buffer(bh[0]); -+ memset(bh[0]->b_data, 0, bh[0]->b_size); -+ mark_buffer_uptodate(bh[0], 1); -+ unlock_buffer(bh[0]); -+ } else { -+ unsigned long block_end, itable_end; -+ int count = 1; -+ -+ itable_end = le32_to_cpu(gdp[desc].bg_inode_table) + -+ inode->i_sb->u.ext3_sb.s_itb_per_group; -+ block_end = block + NUM_INODE_PREREAD; -+ if (block_end > itable_end) -+ block_end = itable_end; -+ -+ for (++block; block < block_end; block++) { -+ bh[count] = sb_getblk(inode->i_sb, block); -+ if (count && (buffer_uptodate(bh[count]) || -+ buffer_locked(bh[count]))) { -+ __brelse(bh[count]); -+ } else -+ count++; -+ } -+ -+ ll_rw_block(READ, count, bh); -+ -+ /* Release all but the block we actually need (bh[0]) */ -+ while (--count > 0) -+ __brelse(bh[count]); -+ -+ wait_on_buffer(bh[0]); -+ if (!buffer_uptodate(bh[0])) { -+ ext3_error(inode->i_sb, __FUNCTION__, -+ "unable to read inode block - " -+ "inode=%lu, block=%lu", inode->i_ino, -+ bh[0]->b_blocknr); -+ goto bad_inode; -+ } -+ } -+ done: -+ offset = (offset * EXT3_INODE_SIZE(inode->i_sb)) & (EXT3_BLOCK_SIZE(inode->i_sb) - 1); -+ -+ iloc->bh = bh[0]; -+ iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset); ++ bh[0] = sb_getblk(inode->i_sb, block); ++ if (buffer_uptodate(bh[0])) ++ goto done; ++ ++ /* If we don't really need to read this block, and it isn't already ++ * in memory, then we just zero it out. Otherwise, we keep the ++ * current block contents (deleted inode data) for posterity. ++ */ ++ if (new && !ext3_itable_block_used(inode->i_sb, block_group, offset)) { ++ lock_buffer(bh[0]); ++ memset(bh[0]->b_data, 0, bh[0]->b_size); ++ mark_buffer_uptodate(bh[0], 1); ++ unlock_buffer(bh[0]); ++ } else { ++ unsigned long block_end, itable_end; ++ int count = 1; ++ ++ itable_end = le32_to_cpu(gdp[desc].bg_inode_table) + ++ inode->i_sb->u.ext3_sb.s_itb_per_group; ++ block_end = block + NUM_INODE_PREREAD; ++ if (block_end > itable_end) ++ block_end = itable_end; ++ ++ for (++block; block < block_end; block++) { ++ bh[count] = sb_getblk(inode->i_sb, block); ++ if (count && (buffer_uptodate(bh[count]) || ++ buffer_locked(bh[count]))) { ++ __brelse(bh[count]); ++ } else ++ count++; ++ } ++ ++ ll_rw_block(READ, count, bh); ++ ++ /* Release all but the block we actually need (bh[0]) */ ++ while (--count > 0) ++ __brelse(bh[count]); ++ ++ wait_on_buffer(bh[0]); ++ if (!buffer_uptodate(bh[0])) { ++ ext3_error(inode->i_sb, __FUNCTION__, ++ "unable to read inode block - " ++ "inode=%lu, block=%lu", inode->i_ino, ++ bh[0]->b_blocknr); ++ goto bad_inode; ++ } ++ } ++done: ++ offset = (offset * EXT3_INODE_SIZE(inode->i_sb)) & (EXT3_BLOCK_SIZE(inode->i_sb) - 1); ++ ++ iloc->bh = bh[0]; ++ iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset); iloc->block_group = block_group; return 0; @@ -197,9 +197,9 @@ +int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc) +{ -+ return ext3_get_inode_loc_new(inode, iloc, 0); ++ return ext3_get_inode_loc_new(inode, iloc, 0); +} -+ ++ void ext3_read_inode(struct inode * inode) { struct ext3_iloc iloc; diff --git a/lustre/kernel_patches/patches/ext3-noread-2.4.21-chaos.patch b/lustre/kernel_patches/patches/ext3-noread-2.4.21-chaos.patch index 55d1537..1903baa 100644 --- a/lustre/kernel_patches/patches/ext3-noread-2.4.21-chaos.patch +++ b/lustre/kernel_patches/patches/ext3-noread-2.4.21-chaos.patch @@ -59,17 +59,17 @@ Index: linux-2.4.21-chaos/fs/ext3/ialloc.c ei->i_state = EXT3_STATE_NEW; - err = ext3_mark_inode_dirty(handle, inode); - if (err) goto fail; -+ err = ext3_get_inode_loc_new(inode, &iloc, 1); -+ if (err) goto fail; -+ BUFFER_TRACE(iloc->bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, iloc.bh); -+ if (err) { -+ brelse(iloc.bh); -+ iloc.bh = NULL; -+ goto fail; -+ } -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; ++ err = ext3_get_inode_loc_new(inode, &iloc, 1); ++ if (err) goto fail; ++ BUFFER_TRACE(iloc->bh, "get_write_access"); ++ err = ext3_journal_get_write_access(handle, iloc.bh); ++ if (err) { ++ brelse(iloc.bh); ++ iloc.bh = NULL; ++ goto fail; ++ } ++ err = ext3_mark_iloc_dirty(handle, inode, &iloc); ++ if (err) goto fail; + + @@ -90,21 +90,21 @@ Index: linux-2.4.21-chaos/fs/ext3/inode.c - -int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc) +#define NUM_INODE_PREREAD 16 -+ ++ +/* -+ * ext3_get_inode_loc returns with an extra refcount against the inode's -+ * underlying buffer_head on success. If this is for a new inode allocation -+ * (new is non-zero) then we may be able to optimize away the read if there -+ * are no other in-use inodes in this inode table block. If we need to do -+ * a read, then read in a whole chunk of blocks to avoid blocking again soon -+ * if we are doing lots of creates/updates. -+ */ ++ * ext3_get_inode_loc returns with an extra refcount against the inode's ++ * underlying buffer_head on success. If this is for a new inode allocation ++ * (new is non-zero) then we may be able to optimize away the read if there ++ * are no other in-use inodes in this inode table block. If we need to do ++ * a read, then read in a whole chunk of blocks to avoid blocking again soon ++ * if we are doing lots of creates/updates. ++ */ +int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new) { struct super_block *sb = inode->i_sb; struct ext3_sb_info *sbi = EXT3_SB(sb); - struct buffer_head *bh = 0; -+ struct buffer_head *bh[NUM_INODE_PREREAD]; ++ struct buffer_head *bh[NUM_INODE_PREREAD]; unsigned long block; unsigned long block_group; unsigned long group_desc; @@ -120,7 +120,7 @@ Index: linux-2.4.21-chaos/fs/ext3/inode.c } - gdp = (struct ext3_group_desc *) bh->b_data; -+ gdp = (struct ext3_group_desc *)(sbi->s_group_desc[group_desc]->b_data); ++ gdp = (struct ext3_group_desc *)(sbi->s_group_desc[group_desc]->b_data); /* * Figure out the offset within the block group inode table */ @@ -137,62 +137,62 @@ Index: linux-2.4.21-chaos/fs/ext3/inode.c - goto bad_inode; - } - offset &= (EXT3_BLOCK_SIZE(sb) - 1); -+ (offset * EXT3_INODE_SIZE(sb) >> EXT3_BLOCK_SIZE_BITS(sb)); ++ (offset * EXT3_INODE_SIZE(sb) >> EXT3_BLOCK_SIZE_BITS(sb)); - iloc->bh = bh; - iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset); -+ bh[0] = sb_getblk(inode->i_sb, block); -+ if (buffer_uptodate(bh[0])) -+ goto done; ++ bh[0] = sb_getblk(inode->i_sb, block); ++ if (buffer_uptodate(bh[0])) ++ goto done; + -+ /* If we don't really need to read this block, and it isn't already -+ * in memory, then we just zero it out. Otherwise, we keep the -+ * current block contents (deleted inode data) for posterity. -+ */ -+ if (new && !ext3_itable_block_used(inode->i_sb, block_group, offset)) { -+ lock_buffer(bh[0]); -+ memset(bh[0]->b_data, 0, bh[0]->b_size); -+ mark_buffer_uptodate(bh[0], 1); -+ unlock_buffer(bh[0]); -+ } else { -+ unsigned long block_end, itable_end; -+ int count = 1; ++ /* If we don't really need to read this block, and it isn't already ++ * in memory, then we just zero it out. Otherwise, we keep the ++ * current block contents (deleted inode data) for posterity. ++ */ ++ if (new && !ext3_itable_block_used(inode->i_sb, block_group, offset)) { ++ lock_buffer(bh[0]); ++ memset(bh[0]->b_data, 0, bh[0]->b_size); ++ mark_buffer_uptodate(bh[0], 1); ++ unlock_buffer(bh[0]); ++ } else { ++ unsigned long block_end, itable_end; ++ int count = 1; + -+ itable_end = le32_to_cpu(gdp[desc].bg_inode_table) + -+ inode->i_sb->u.ext3_sb.s_itb_per_group; -+ block_end = block + NUM_INODE_PREREAD; -+ if (block_end > itable_end) -+ block_end = itable_end; ++ itable_end = le32_to_cpu(gdp[desc].bg_inode_table) + ++ inode->i_sb->u.ext3_sb.s_itb_per_group; ++ block_end = block + NUM_INODE_PREREAD; ++ if (block_end > itable_end) ++ block_end = itable_end; + -+ for (++block; block < block_end; block++) { -+ bh[count] = sb_getblk(inode->i_sb, block); -+ if (count && (buffer_uptodate(bh[count]) || -+ buffer_locked(bh[count]))) { -+ __brelse(bh[count]); -+ } else -+ count++; -+ } ++ for (++block; block < block_end; block++) { ++ bh[count] = sb_getblk(inode->i_sb, block); ++ if (count && (buffer_uptodate(bh[count]) || ++ buffer_locked(bh[count]))) { ++ __brelse(bh[count]); ++ } else ++ count++; ++ } + -+ ll_rw_block(READ, count, bh); ++ ll_rw_block(READ, count, bh); + -+ /* Release all but the block we actually need (bh[0]) */ -+ while (--count > 0) -+ __brelse(bh[count]); ++ /* Release all but the block we actually need (bh[0]) */ ++ while (--count > 0) ++ __brelse(bh[count]); + -+ wait_on_buffer(bh[0]); -+ if (!buffer_uptodate(bh[0])) { -+ ext3_error(inode->i_sb, __FUNCTION__, -+ "unable to read inode block - " -+ "inode=%lu, block=%lu", inode->i_ino, -+ bh[0]->b_blocknr); -+ goto bad_inode; -+ } -+ } -+ done: -+ offset = (offset * EXT3_INODE_SIZE(inode->i_sb)) & (EXT3_BLOCK_SIZE(inode->i_sb) - 1); -+ -+ iloc->bh = bh[0]; -+ iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset); ++ wait_on_buffer(bh[0]); ++ if (!buffer_uptodate(bh[0])) { ++ ext3_error(inode->i_sb, __FUNCTION__, ++ "unable to read inode block - " ++ "inode=%lu, block=%lu", inode->i_ino, ++ bh[0]->b_blocknr); ++ goto bad_inode; ++ } ++ } ++ done: ++ offset = (offset * EXT3_INODE_SIZE(inode->i_sb)) & (EXT3_BLOCK_SIZE(inode->i_sb) - 1); ++ ++ iloc->bh = bh[0]; ++ iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset); iloc->block_group = block_group; return 0; @@ -202,7 +202,7 @@ Index: linux-2.4.21-chaos/fs/ext3/inode.c +int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc) +{ -+ return ext3_get_inode_loc_new(inode, iloc, 0); ++ return ext3_get_inode_loc_new(inode, iloc, 0); +} + void ext3_read_inode(struct inode * inode) diff --git a/lustre/kernel_patches/patches/ext3-noread-2.4.21-suse2.patch b/lustre/kernel_patches/patches/ext3-noread-2.4.21-suse2.patch index b4b5048..66274d8 100644 --- a/lustre/kernel_patches/patches/ext3-noread-2.4.21-suse2.patch +++ b/lustre/kernel_patches/patches/ext3-noread-2.4.21-suse2.patch @@ -57,17 +57,17 @@ inode->u.ext3_i.i_state = EXT3_STATE_NEW; - err = ext3_mark_inode_dirty(handle, inode); - if (err) goto fail; -+ err = ext3_get_inode_loc_new(inode, &iloc, 1); -+ if (err) goto fail; -+ BUFFER_TRACE(iloc->bh, "get_write_access"); -+ err = ext3_journal_get_write_access(handle, iloc.bh); -+ if (err) { -+ brelse(iloc.bh); -+ iloc.bh = NULL; -+ goto fail; -+ } -+ err = ext3_mark_iloc_dirty(handle, inode, &iloc); -+ if (err) goto fail; ++ err = ext3_get_inode_loc_new(inode, &iloc, 1); ++ if (err) goto fail; ++ BUFFER_TRACE(iloc->bh, "get_write_access"); ++ err = ext3_journal_get_write_access(handle, iloc.bh); ++ if (err) { ++ brelse(iloc.bh); ++ iloc.bh = NULL; ++ goto fail; ++ } ++ err = ext3_mark_iloc_dirty(handle, inode, &iloc); ++ if (err) goto fail; + + @@ -86,19 +86,19 @@ - -int ext3_get_inode_loc (struct inode *inode, struct ext3_iloc *iloc) +#define NUM_INODE_PREREAD 16 -+ ++ +/* -+ * ext3_get_inode_loc returns with an extra refcount against the inode's -+ * underlying buffer_head on success. If this is for a new inode allocation -+ * (new is non-zero) then we may be able to optimize away the read if there -+ * are no other in-use inodes in this inode table block. If we need to do -+ * a read, then read in a whole chunk of blocks to avoid blocking again soon -+ * if we are doing lots of creates/updates. -+ */ ++ * ext3_get_inode_loc returns with an extra refcount against the inode's ++ * underlying buffer_head on success. If this is for a new inode allocation ++ * (new is non-zero) then we may be able to optimize away the read if there ++ * are no other in-use inodes in this inode table block. If we need to do ++ * a read, then read in a whole chunk of blocks to avoid blocking again soon ++ * if we are doing lots of creates/updates. ++ */ +int ext3_get_inode_loc_new(struct inode *inode, struct ext3_iloc *iloc, int new) { - struct buffer_head *bh = 0; -+ struct buffer_head *bh[NUM_INODE_PREREAD]; ++ struct buffer_head *bh[NUM_INODE_PREREAD]; unsigned long block; unsigned long block_group; unsigned long group_desc; @@ -115,7 +115,7 @@ } - gdp = (struct ext3_group_desc *) bh->b_data; -+ gdp = (struct ext3_group_desc *)(inode->i_sb->u.ext3_sb.s_group_desc[group_desc]->b_data); ++ gdp = (struct ext3_group_desc *)(inode->i_sb->u.ext3_sb.s_group_desc[group_desc]->b_data); /* * Figure out the offset within the block group inode table */ @@ -132,62 +132,62 @@ - goto bad_inode; - } - offset &= (EXT3_BLOCK_SIZE(inode->i_sb) - 1); -+ (offset * EXT3_INODE_SIZE(inode->i_sb) >> EXT3_BLOCK_SIZE_BITS(inode->i_sb)); ++ (offset * EXT3_INODE_SIZE(inode->i_sb) >> EXT3_BLOCK_SIZE_BITS(inode->i_sb)); - iloc->bh = bh; - iloc->raw_inode = (struct ext3_inode *) (bh->b_data + offset); -+ bh[0] = sb_getblk(inode->i_sb, block); -+ if (buffer_uptodate(bh[0])) -+ goto done; ++ bh[0] = sb_getblk(inode->i_sb, block); ++ if (buffer_uptodate(bh[0])) ++ goto done; + -+ /* If we don't really need to read this block, and it isn't already -+ * in memory, then we just zero it out. Otherwise, we keep the -+ * current block contents (deleted inode data) for posterity. -+ */ -+ if (new && !ext3_itable_block_used(inode->i_sb, block_group, offset)) { -+ lock_buffer(bh[0]); -+ memset(bh[0]->b_data, 0, bh[0]->b_size); -+ mark_buffer_uptodate(bh[0], 1); -+ unlock_buffer(bh[0]); -+ } else { -+ unsigned long block_end, itable_end; -+ int count = 1; ++ /* If we don't really need to read this block, and it isn't already ++ * in memory, then we just zero it out. Otherwise, we keep the ++ * current block contents (deleted inode data) for posterity. ++ */ ++ if (new && !ext3_itable_block_used(inode->i_sb, block_group, offset)) { ++ lock_buffer(bh[0]); ++ memset(bh[0]->b_data, 0, bh[0]->b_size); ++ mark_buffer_uptodate(bh[0], 1); ++ unlock_buffer(bh[0]); ++ } else { ++ unsigned long block_end, itable_end; ++ int count = 1; + -+ itable_end = le32_to_cpu(gdp[desc].bg_inode_table) + -+ inode->i_sb->u.ext3_sb.s_itb_per_group; -+ block_end = block + NUM_INODE_PREREAD; -+ if (block_end > itable_end) -+ block_end = itable_end; ++ itable_end = le32_to_cpu(gdp[desc].bg_inode_table) + ++ inode->i_sb->u.ext3_sb.s_itb_per_group; ++ block_end = block + NUM_INODE_PREREAD; ++ if (block_end > itable_end) ++ block_end = itable_end; + -+ for (++block; block < block_end; block++) { -+ bh[count] = sb_getblk(inode->i_sb, block); -+ if (count && (buffer_uptodate(bh[count]) || -+ buffer_locked(bh[count]))) { -+ __brelse(bh[count]); -+ } else -+ count++; -+ } ++ for (++block; block < block_end; block++) { ++ bh[count] = sb_getblk(inode->i_sb, block); ++ if (count && (buffer_uptodate(bh[count]) || ++ buffer_locked(bh[count]))) { ++ __brelse(bh[count]); ++ } else ++ count++; ++ } + -+ ll_rw_block(READ, count, bh); ++ ll_rw_block(READ, count, bh); + -+ /* Release all but the block we actually need (bh[0]) */ -+ while (--count > 0) -+ __brelse(bh[count]); ++ /* Release all but the block we actually need (bh[0]) */ ++ while (--count > 0) ++ __brelse(bh[count]); + -+ wait_on_buffer(bh[0]); -+ if (!buffer_uptodate(bh[0])) { -+ ext3_error(inode->i_sb, __FUNCTION__, -+ "unable to read inode block - " -+ "inode=%lu, block=%lu", inode->i_ino, -+ bh[0]->b_blocknr); -+ goto bad_inode; -+ } -+ } -+ done: -+ offset = (offset * EXT3_INODE_SIZE(inode->i_sb)) & (EXT3_BLOCK_SIZE(inode->i_sb) - 1); -+ -+ iloc->bh = bh[0]; -+ iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset); ++ wait_on_buffer(bh[0]); ++ if (!buffer_uptodate(bh[0])) { ++ ext3_error(inode->i_sb, __FUNCTION__, ++ "unable to read inode block - " ++ "inode=%lu, block=%lu", inode->i_ino, ++ bh[0]->b_blocknr); ++ goto bad_inode; ++ } ++ } ++ done: ++ offset = (offset * EXT3_INODE_SIZE(inode->i_sb)) & (EXT3_BLOCK_SIZE(inode->i_sb) - 1); ++ ++ iloc->bh = bh[0]; ++ iloc->raw_inode = (struct ext3_inode *)(bh[0]->b_data + offset); iloc->block_group = block_group; return 0; @@ -197,7 +197,7 @@ +int ext3_get_inode_loc(struct inode *inode, struct ext3_iloc *iloc) +{ -+ return ext3_get_inode_loc_new(inode, iloc, 0); ++ return ext3_get_inode_loc_new(inode, iloc, 0); +} + void ext3_read_inode(struct inode * inode) diff --git a/lustre/kernel_patches/patches/iopen-2.4.18-2.patch b/lustre/kernel_patches/patches/iopen-2.4.18-2.patch index c971a83..8215730 100644 --- a/lustre/kernel_patches/patches/iopen-2.4.18-2.patch +++ b/lustre/kernel_patches/patches/iopen-2.4.18-2.patch @@ -14,7 +14,7 @@ sb=n Use alternate superblock at this location. -+iopen Makes an invisible pseudo-directory called ++iopen Makes an invisible pseudo-directory called + __iopen__ available in the root directory + of the filesystem. Allows open-by-inode- + number. i.e., inode 3145 can be accessed @@ -60,20 +60,20 @@ + if (ext3_iopen_get_inode(inode)) + return; -+ ++ if(ext3_get_inode_loc(inode, &iloc)) goto bad_inode; bh = iloc.bh; --- /dev/null 2003-01-30 03:24:37.000000000 -0700 +++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.c 2003-07-09 17:13:02.000000000 -0600 -@@ -0,0 +1,259 @@ +@@ -0,0 +1,258 @@ +/* + * linux/fs/ext3/iopen.c + * + * Special support for open by inode number + * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. + * @@ -122,7 +122,7 @@ + struct list_head *lp; + struct dentry *alternate; + char buf[IOPEN_NAME_LEN]; -+ ++ + if (dentry->d_name.len >= IOPEN_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + @@ -151,6 +151,9 @@ + return ERR_PTR(-ENOENT); + } + ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ + /* preferrably return a connected dentry */ + spin_lock(&dcache_lock); + list_for_each(lp, &inode->i_dentry) { @@ -159,7 +162,7 @@ + } + + if (!list_empty(&inode->i_dentry)) { -+ alternate = list_entry(inode->i_dentry.next, ++ alternate = list_entry(inode->i_dentry.next, + struct dentry, d_alias); + dget_locked(alternate); + alternate->d_vfs_flags |= DCACHE_REFERENCED; @@ -168,9 +171,14 @@ + return alternate; + } + dentry->d_flags |= DCACHE_NFSD_DISCONNECTED; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ + spin_unlock(&dcache_lock); + -+ d_add(dentry, inode); + return NULL; +} + @@ -182,7 +190,7 @@ +{ + const unsigned char *old_name, *new_name; + -+ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); ++ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); + old_name = target->d_name.name; + new_name = dentry->d_name.name; + if (old_name == target->d_iname) @@ -195,6 +203,7 @@ + +/* This function is spliced into ext3_lookup and does the move of a + * disconnected dentry (if it exists) to a connected dentry. ++ * Caller must hold dcache_lock. + */ +struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode) +{ @@ -202,13 +211,6 @@ + struct list_head *lp; + + /* preferrably return a connected dentry */ -+ spin_lock(&dcache_lock); -+ /* verify this dentry is really new */ -+ assert(!de->d_inode); -+ assert(list_empty(&de->d_subdirs)); -+ assert(list_empty(&de->d_alias)); -+ -+ + list_for_each(lp, &inode->i_dentry) { + tmp = list_entry(lp, struct dentry, d_alias); + if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) { @@ -220,15 +222,12 @@ + } + } + -+ if (!goal) { -+ spin_unlock(&dcache_lock); -+ return NULL; -+ } ++ if (!goal) ++ return NULL; + + /* Move the goal to the de hash queue - like d_move() */ + goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED; -+ list_del(&goal->d_hash); -+ list_add(&goal->d_hash, &de->d_hash); ++ list_del_init(&goal->d_hash); + + list_del(&goal->d_child); + list_del(&de->d_child); @@ -242,7 +241,7 @@ + /* And add them back to the (new) parent lists */ + list_add(&goal->d_child, &goal->d_parent->d_subdirs); + list_add(&de->d_child, &de->d_parent->d_subdirs); -+ spin_unlock(&dcache_lock); ++ __d_rehash(goal, 0); + + return goal; +} @@ -286,7 +285,7 @@ + + inode = iget(dir->i_sb, EXT3_BAD_INO); + -+ if (!inode) ++ if (!inode) + return 0; + d_add(dentry, inode); + return 1; @@ -315,7 +314,7 @@ + inode->u.ext3_i.i_dtime = 0; + inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size + * (for stat), not the fs block -+ * size */ ++ * size */ + inode->i_blocks = 0; + inode->i_version = 1; + inode->i_generation = 0; @@ -328,20 +327,22 @@ +} --- /dev/null 2003-01-30 03:24:37.000000000 -0700 +++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.h 2003-07-09 17:13:02.000000000 -0600 -@@ -0,0 +1,13 @@ +@@ -0,0 +1,15 @@ +/* + * iopen.h + * + * Special support for opening files by inode number. -+ * ++ * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. + */ + +extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); +extern int ext3_iopen_get_inode(struct inode *inode); ++extern struct dentry *iopen_connect_dentry(struct dentry *de, ++ struct inode *inode); --- linux-2.4.18-p4smp/fs/ext3/namei.c~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 +++ linux-2.4.18-p4smp-braam/fs/ext3/namei.c 2003-07-09 17:13:02.000000000 -0600 @@ -34,6 +34,7 @@ @@ -352,14 +353,7 @@ /* * define how far ahead to read directories while searching them. -@@ -703,16 +704,21 @@ cleanup_and_exit: - return NULL; - } - #endif -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode); - - static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry) - { +@@ -709,10 +710,14 @@ cleanup_and_exit: struct inode * inode; struct ext3_dir_entry_2 * de; struct buffer_head * bh; @@ -374,29 +368,47 @@ bh = ext3_find_entry(dentry, &de); inode = NULL; if (bh) { -@@ -723,6 +729,12 @@ static struct dentry *ext3_lookup(struct +@@ -723,7 +729,28 @@ static struct dentry *ext3_lookup(struct if (!inode) return ERR_PTR(-EACCES); } +- d_add(dentry, inode); ++ ++ /* verify this dentry is really new */ ++ assert(!dentry->d_inode); ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ assert(list_empty(&dentry->d_subdirs)); + ++ spin_lock(&dcache_lock); + if (inode && (alternate = iopen_connect_dentry(dentry, inode))) { ++ spin_unlock(&dcache_lock); + iput(inode); + return alternate; + } + - d_add(dentry, inode); ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ if (inode) /* d_instantiate */ ++ list_add(&dentry->d_alias, &inode->i_dentry); ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ ++ spin_unlock(&dcache_lock); ++ return NULL; } + --- linux-2.4.18-p4smp/fs/ext3/super.c~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 +++ linux-2.4.18-p4smp-braam/fs/ext3/super.c 2003-07-09 17:13:02.000000000 -0600 -@@ -831,6 +831,17 @@ static int parse_options (char * options +@@ -831,6 +831,18 @@ static int parse_options (char * options || !strcmp (this_char, "quota") || !strcmp (this_char, "usrquota")) /* Don't do anything ;-) */ ; + else if (!strcmp (this_char, "iopen")) { + set_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); -+ } else if (!strcmp (this_char, "noiopen")) { ++ } ++ else if (!strcmp (this_char, "noiopen")) { + clear_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + } diff --git a/lustre/kernel_patches/patches/iopen-2.4.18.patch b/lustre/kernel_patches/patches/iopen-2.4.18.patch index 7fc40f7..202ebc6 100644 --- a/lustre/kernel_patches/patches/iopen-2.4.18.patch +++ b/lustre/kernel_patches/patches/iopen-2.4.18.patch @@ -14,7 +14,7 @@ sb=n Use alternate superblock at this location. -+iopen Makes an invisible pseudo-directory called ++iopen Makes an invisible pseudo-directory called + __iopen__ available in the root directory + of the filesystem. Allows open-by-inode- + number. i.e., inode 3145 can be accessed @@ -60,20 +60,20 @@ + if (ext3_iopen_get_inode(inode)) + return; -+ ++ if(ext3_get_inode_loc(inode, &iloc)) goto bad_inode; bh = iloc.bh; --- /dev/null 2003-01-30 03:24:37.000000000 -0700 +++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.c 2003-07-09 17:13:02.000000000 -0600 -@@ -0,0 +1,259 @@ +@@ -0,0 +1,258 @@ +/* + * linux/fs/ext3/iopen.c + * + * Special support for open by inode number + * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. + * @@ -122,7 +122,7 @@ + struct list_head *lp; + struct dentry *alternate; + char buf[IOPEN_NAME_LEN]; -+ ++ + if (dentry->d_name.len >= IOPEN_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + @@ -151,6 +151,9 @@ + return ERR_PTR(-ENOENT); + } + ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ + /* preferrably return a connected dentry */ + spin_lock(&dcache_lock); + list_for_each(lp, &inode->i_dentry) { @@ -159,7 +162,7 @@ + } + + if (!list_empty(&inode->i_dentry)) { -+ alternate = list_entry(inode->i_dentry.next, ++ alternate = list_entry(inode->i_dentry.next, + struct dentry, d_alias); + dget_locked(alternate); + alternate->d_vfs_flags |= DCACHE_REFERENCED; @@ -168,9 +171,14 @@ + return alternate; + } + dentry->d_flags |= DCACHE_NFSD_DISCONNECTED; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ + spin_unlock(&dcache_lock); + -+ d_add(dentry, inode); + return NULL; +} + @@ -182,7 +190,7 @@ +{ + const unsigned char *old_name, *new_name; + -+ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); ++ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); + old_name = target->d_name.name; + new_name = dentry->d_name.name; + if (old_name == target->d_iname) @@ -195,6 +203,7 @@ + +/* This function is spliced into ext3_lookup and does the move of a + * disconnected dentry (if it exists) to a connected dentry. ++ * Caller must hold dcache_lock. + */ +struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode) +{ @@ -202,13 +211,6 @@ + struct list_head *lp; + + /* preferrably return a connected dentry */ -+ spin_lock(&dcache_lock); -+ /* verify this dentry is really new */ -+ assert(!de->d_inode); -+ assert(list_empty(&de->d_subdirs)); -+ assert(list_empty(&de->d_alias)); -+ -+ + list_for_each(lp, &inode->i_dentry) { + tmp = list_entry(lp, struct dentry, d_alias); + if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) { @@ -220,10 +222,8 @@ + } + } + -+ if (!goal) { -+ spin_unlock(&dcache_lock); -+ return NULL; -+ } ++ if (!goal) ++ return NULL; + + /* Move the goal to the de hash queue - like d_move() */ + goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED; @@ -242,7 +242,6 @@ + list_add(&goal->d_child, &goal->d_parent->d_subdirs); + list_add(&de->d_child, &de->d_parent->d_subdirs); + __d_rehash(goal, 0); -+ spin_unlock(&dcache_lock); + + return goal; +} @@ -286,7 +285,7 @@ + + inode = iget(dir->i_sb, EXT3_BAD_INO); + -+ if (!inode) ++ if (!inode) + return 0; + d_add(dentry, inode); + return 1; @@ -315,7 +314,7 @@ + inode->u.ext3_i.i_dtime = 0; + inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size + * (for stat), not the fs block -+ * size */ ++ * size */ + inode->i_blocks = 0; + inode->i_version = 1; + inode->i_generation = 0; @@ -328,20 +327,22 @@ +} --- /dev/null 2003-01-30 03:24:37.000000000 -0700 +++ linux-2.4.18-p4smp-braam/fs/ext3/iopen.h 2003-07-09 17:13:02.000000000 -0600 -@@ -0,0 +1,13 @@ +@@ -0,0 +1,15 @@ +/* + * iopen.h + * + * Special support for opening files by inode number. -+ * ++ * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. + */ + +extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); +extern int ext3_iopen_get_inode(struct inode *inode); ++extern struct dentry *iopen_connect_dentry(struct dentry *de, ++ struct inode *inode); --- linux-2.4.18-p4smp/fs/ext3/namei.c~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 +++ linux-2.4.18-p4smp-braam/fs/ext3/namei.c 2003-07-09 17:13:02.000000000 -0600 @@ -34,6 +34,7 @@ @@ -352,14 +353,7 @@ /* * define how far ahead to read directories while searching them. -@@ -703,16 +704,21 @@ cleanup_and_exit: - brelse (bh_use[ra_ptr]); - return ret; - } -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode); - - static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry) - { +@@ -703,10 +704,14 @@ cleanup_and_exit: struct inode * inode; struct ext3_dir_entry_2 * de; struct buffer_head * bh; @@ -374,29 +368,47 @@ bh = ext3_find_entry(dentry, &de); inode = NULL; if (bh) { -@@ -723,6 +729,12 @@ static struct dentry *ext3_lookup(struct +@@ -723,7 +729,28 @@ static struct dentry *ext3_lookup(struct if (!inode) return ERR_PTR(-EACCES); } +- d_add(dentry, inode); ++ ++ /* verify this dentry is really new */ ++ assert(!dentry->d_inode); ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ assert(list_empty(&dentry->d_subdirs)); + ++ spin_lock(&dcache_lock); + if (inode && (alternate = iopen_connect_dentry(dentry, inode))) { ++ spin_unlock(&dcache_lock); + iput(inode); + return alternate; + } + - d_add(dentry, inode); ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ if (inode) /* d_instantiate */ ++ list_add(&dentry->d_alias, &inode->i_dentry); ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ ++ spin_unlock(&dcache_lock); ++ return NULL; } + --- linux-2.4.18-p4smp/fs/ext3/super.c~iopen-2.4.18 2003-07-09 13:32:38.000000000 -0600 +++ linux-2.4.18-p4smp-braam/fs/ext3/super.c 2003-07-09 17:13:02.000000000 -0600 -@@ -831,6 +831,17 @@ static int parse_options (char * options +@@ -831,6 +831,18 @@ static int parse_options (char * options || !strcmp (this_char, "quota") || !strcmp (this_char, "usrquota")) /* Don't do anything ;-) */ ; + else if (!strcmp (this_char, "iopen")) { + set_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); -+ } else if (!strcmp (this_char, "noiopen")) { ++ } ++ else if (!strcmp (this_char, "noiopen")) { + clear_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + } diff --git a/lustre/kernel_patches/patches/iopen-2.4.19-suse.patch b/lustre/kernel_patches/patches/iopen-2.4.19-suse.patch index ab267bb..ad213c9 100644 --- a/lustre/kernel_patches/patches/iopen-2.4.19-suse.patch +++ b/lustre/kernel_patches/patches/iopen-2.4.19-suse.patch @@ -16,7 +16,7 @@ Index: linux-2.4.19.SuSE/Documentation/filesystems/ext2.txt sb=n Use alternate superblock at this location. -+iopen Makes an invisible pseudo-directory called ++iopen Makes an invisible pseudo-directory called + __iopen__ available in the root directory + of the filesystem. Allows open-by-inode- + number. i.e., inode 3145 can be accessed @@ -66,7 +66,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/inode.c + if (ext3_iopen_get_inode(inode)) + return; -+ ++ if(ext3_get_inode_loc(inode, &iloc)) goto bad_inode; bh = iloc.bh; @@ -74,17 +74,17 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c =================================================================== --- linux-2.4.19.SuSE.orig/fs/ext3/iopen.c Sun Nov 16 01:27:31 2003 +++ linux-2.4.19.SuSE/fs/ext3/iopen.c Sun Nov 16 01:27:31 2003 -@@ -0,0 +1,259 @@ +@@ -0,0 +1,258 @@ +/* + * linux/fs/ext3/iopen.c + * + * Special support for open by inode number + * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. -+ * ++ * + * + * Invariants: + * - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias @@ -130,7 +130,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + struct list_head *lp; + struct dentry *alternate; + char buf[IOPEN_NAME_LEN]; -+ ++ + if (dentry->d_name.len >= IOPEN_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + @@ -159,6 +159,9 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + return ERR_PTR(-ENOENT); + } + ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ + /* preferrably return a connected dentry */ + spin_lock(&dcache_lock); + list_for_each(lp, &inode->i_dentry) { @@ -167,7 +170,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + } + + if (!list_empty(&inode->i_dentry)) { -+ alternate = list_entry(inode->i_dentry.next, ++ alternate = list_entry(inode->i_dentry.next, + struct dentry, d_alias); + dget_locked(alternate); + alternate->d_vfs_flags |= DCACHE_REFERENCED; @@ -176,9 +179,14 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + return alternate; + } + dentry->d_flags |= DCACHE_NFSD_DISCONNECTED; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ + spin_unlock(&dcache_lock); + -+ d_add(dentry, inode); + return NULL; +} + @@ -190,7 +198,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c +{ + const unsigned char *old_name, *new_name; + -+ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); ++ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); + old_name = target->d_name.name; + new_name = dentry->d_name.name; + if (old_name == target->d_iname) @@ -203,6 +211,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + +/* This function is spliced into ext3_lookup and does the move of a + * disconnected dentry (if it exists) to a connected dentry. ++ * Caller must hold dcache_lock. + */ +struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode) +{ @@ -210,13 +219,6 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + struct list_head *lp; + + /* preferrably return a connected dentry */ -+ spin_lock(&dcache_lock); -+ /* verify this dentry is really new */ -+ assert(!de->d_inode); -+ assert(list_empty(&de->d_subdirs)); -+ assert(list_empty(&de->d_alias)); -+ -+ + list_for_each(lp, &inode->i_dentry) { + tmp = list_entry(lp, struct dentry, d_alias); + if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) { @@ -228,10 +230,8 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + } + } + -+ if (!goal) { -+ spin_unlock(&dcache_lock); -+ return NULL; -+ } ++ if (!goal) ++ return NULL; + + /* Move the goal to the de hash queue - like d_move() */ + goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED; @@ -250,7 +250,6 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + list_add(&goal->d_child, &goal->d_parent->d_subdirs); + list_add(&de->d_child, &de->d_parent->d_subdirs); + __d_rehash(goal, 0); -+ spin_unlock(&dcache_lock); + + return goal; +} @@ -294,7 +293,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + + inode = iget(dir->i_sb, EXT3_BAD_INO); + -+ if (!inode) ++ if (!inode) + return 0; + d_add(dentry, inode); + return 1; @@ -323,7 +322,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.c + inode->u.ext3_i.i_dtime = 0; + inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size + * (for stat), not the fs block -+ * size */ ++ * size */ + inode->i_blocks = 0; + inode->i_version = 1; + inode->i_generation = 0; @@ -338,20 +337,22 @@ Index: linux-2.4.19.SuSE/fs/ext3/iopen.h =================================================================== --- linux-2.4.19.SuSE.orig/fs/ext3/iopen.h Sun Nov 16 01:27:31 2003 +++ linux-2.4.19.SuSE/fs/ext3/iopen.h Sun Nov 16 01:27:31 2003 -@@ -0,0 +1,13 @@ +@@ -0,0 +1,15 @@ +/* + * iopen.h + * + * Special support for opening files by inode number. -+ * ++ * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. + */ + +extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); +extern int ext3_iopen_get_inode(struct inode *inode); ++extern struct dentry *iopen_connect_dentry(struct dentry *de, ++ struct inode *inode); Index: linux-2.4.19.SuSE/fs/ext3/namei.c =================================================================== --- linux-2.4.19.SuSE.orig/fs/ext3/namei.c Sun Nov 16 01:23:20 2003 @@ -365,14 +366,7 @@ Index: linux-2.4.19.SuSE/fs/ext3/namei.c /* * define how far ahead to read directories while searching them. -@@ -922,16 +922,21 @@ - return NULL; - } - #endif -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode); - - static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry) - { +@@ -922,10 +922,14 @@ struct inode * inode; struct ext3_dir_entry_2 * de; struct buffer_head * bh; @@ -387,31 +381,49 @@ Index: linux-2.4.19.SuSE/fs/ext3/namei.c bh = ext3_find_entry(dentry, &de); inode = NULL; if (bh) { -@@ -943,6 +948,12 @@ +@@ -943,7 +948,28 @@ return ERR_PTR(-EACCES); } } +- d_add(dentry, inode); ++ ++ /* verify this dentry is really new */ ++ assert(!dentry->d_inode); ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ assert(list_empty(&dentry->d_subdirs)); + ++ spin_lock(&dcache_lock); + if (inode && (alternate = iopen_connect_dentry(dentry, inode))) { ++ spin_unlock(&dcache_lock); + iput(inode); + return alternate; + } + - d_add(dentry, inode); ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ if (inode) /* d_instantiate */ ++ list_add(&dentry->d_alias, &inode->i_dentry); ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ ++ spin_unlock(&dcache_lock); ++ return NULL; } + Index: linux-2.4.19.SuSE/fs/ext3/super.c =================================================================== --- linux-2.4.19.SuSE.orig/fs/ext3/super.c Sun Nov 16 01:19:22 2003 +++ linux-2.4.19.SuSE/fs/ext3/super.c Sun Nov 16 01:27:31 2003 -@@ -864,6 +864,17 @@ +@@ -864,6 +864,18 @@ || !strcmp (this_char, "quota") || !strcmp (this_char, "usrquota")) /* Don't do anything ;-) */ ; + else if (!strcmp (this_char, "iopen")) { + set_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); -+ } else if (!strcmp (this_char, "noiopen")) { ++ } ++ else if (!strcmp (this_char, "noiopen")) { + clear_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + } diff --git a/lustre/kernel_patches/patches/iopen-2.4.20.patch b/lustre/kernel_patches/patches/iopen-2.4.20.patch index dcf2fc0..8800e1f 100644 --- a/lustre/kernel_patches/patches/iopen-2.4.20.patch +++ b/lustre/kernel_patches/patches/iopen-2.4.20.patch @@ -8,13 +8,15 @@ include/linux/ext3_fs.h | 2 8 files changed, 318 insertions(+), 2 deletions(-) ---- linux/Documentation/filesystems/ext2.txt~iopen-2.4.20 Wed Jul 11 15:44:45 2001 -+++ linux-mmonroe/Documentation/filesystems/ext2.txt Thu Jul 10 12:28:54 2003 -@@ -35,6 +35,22 @@ resgid=n The group ID which may use th +Index: linux-2.4.22-uml/Documentation/filesystems/ext2.txt +=================================================================== +--- linux-2.4.22-uml.orig/Documentation/filesystems/ext2.txt 2001-07-11 16:44:45.000000000 -0600 ++++ linux-2.4.22-uml/Documentation/filesystems/ext2.txt 2004-01-30 14:18:10.000000000 -0700 +@@ -35,6 +35,22 @@ sb=n Use alternate superblock at this location. -+iopen Makes an invisible pseudo-directory called ++iopen Makes an invisible pseudo-directory called + __iopen__ available in the root directory + of the filesystem. Allows open-by-inode- + number. i.e., inode 3145 can be accessed @@ -33,9 +35,11 @@ grpquota,noquota,quota,usrquota Quota options are silently ignored by ext2. ---- linux/fs/ext3/Makefile~iopen-2.4.20 Thu Jul 10 12:28:44 2003 -+++ linux-mmonroe/fs/ext3/Makefile Thu Jul 10 12:28:54 2003 -@@ -11,7 +11,7 @@ O_TARGET := ext3.o +Index: linux-2.4.22-uml/fs/ext3/Makefile +=================================================================== +--- linux-2.4.22-uml.orig/fs/ext3/Makefile 2004-01-30 14:17:58.000000000 -0700 ++++ linux-2.4.22-uml/fs/ext3/Makefile 2004-01-30 14:18:10.000000000 -0700 +@@ -11,7 +11,7 @@ export-objs := ext3-exports.o @@ -44,8 +48,10 @@ ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o obj-m := $(O_TARGET) ---- linux/fs/ext3/inode.c~iopen-2.4.20 Thu Jul 10 12:28:46 2003 -+++ linux-mmonroe/fs/ext3/inode.c Thu Jul 10 12:28:54 2003 +Index: linux-2.4.22-uml/fs/ext3/inode.c +=================================================================== +--- linux-2.4.22-uml.orig/fs/ext3/inode.c 2004-01-30 14:17:59.000000000 -0700 ++++ linux-2.4.22-uml/fs/ext3/inode.c 2004-01-30 14:18:10.000000000 -0700 @@ -31,6 +31,7 @@ #include #include @@ -54,29 +60,31 @@ /* * SEARCH_FROM_ZERO forces each block allocation to search from the start -@@ -2253,6 +2254,9 @@ void ext3_read_inode(struct inode * inod +@@ -2153,6 +2154,9 @@ struct buffer_head *bh; int block; + if (ext3_iopen_get_inode(inode)) + return; -+ ++ if(ext3_get_inode_loc(inode, &iloc)) goto bad_inode; bh = iloc.bh; ---- /dev/null Tue Jan 28 04:00:01 2003 -+++ linux-mmonroe/fs/ext3/iopen.c Thu Jul 10 12:28:54 2003 -@@ -0,0 +1,259 @@ +Index: linux-2.4.22-uml/fs/ext3/iopen.c +=================================================================== +--- linux-2.4.22-uml.orig/fs/ext3/iopen.c 2004-01-30 14:18:10.000000000 -0700 ++++ linux-2.4.22-uml/fs/ext3/iopen.c 2004-01-30 14:18:10.000000000 -0700 +@@ -0,0 +1,258 @@ +/* + * linux/fs/ext3/iopen.c + * + * Special support for open by inode number + * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. -+ * ++ * + * + * Invariants: + * - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias @@ -122,7 +130,7 @@ + struct list_head *lp; + struct dentry *alternate; + char buf[IOPEN_NAME_LEN]; -+ ++ + if (dentry->d_name.len >= IOPEN_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + @@ -151,6 +159,9 @@ + return ERR_PTR(-ENOENT); + } + ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ + /* preferrably return a connected dentry */ + spin_lock(&dcache_lock); + list_for_each(lp, &inode->i_dentry) { @@ -159,7 +170,7 @@ + } + + if (!list_empty(&inode->i_dentry)) { -+ alternate = list_entry(inode->i_dentry.next, ++ alternate = list_entry(inode->i_dentry.next, + struct dentry, d_alias); + dget_locked(alternate); + alternate->d_vfs_flags |= DCACHE_REFERENCED; @@ -168,9 +179,14 @@ + return alternate; + } + dentry->d_flags |= DCACHE_NFSD_DISCONNECTED; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ + spin_unlock(&dcache_lock); + -+ d_add(dentry, inode); + return NULL; +} + @@ -182,7 +198,7 @@ +{ + const unsigned char *old_name, *new_name; + -+ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); ++ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); + old_name = target->d_name.name; + new_name = dentry->d_name.name; + if (old_name == target->d_iname) @@ -195,6 +211,7 @@ + +/* This function is spliced into ext3_lookup and does the move of a + * disconnected dentry (if it exists) to a connected dentry. ++ * Caller must hold dcache_lock. + */ +struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode) +{ @@ -202,13 +219,6 @@ + struct list_head *lp; + + /* preferrably return a connected dentry */ -+ spin_lock(&dcache_lock); -+ /* verify this dentry is really new */ -+ assert(!de->d_inode); -+ assert(list_empty(&de->d_subdirs)); -+ assert(list_empty(&de->d_alias)); -+ -+ + list_for_each(lp, &inode->i_dentry) { + tmp = list_entry(lp, struct dentry, d_alias); + if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) { @@ -220,10 +230,8 @@ + } + } + -+ if (!goal) { -+ spin_unlock(&dcache_lock); -+ return NULL; -+ } ++ if (!goal) ++ return NULL; + + /* Move the goal to the de hash queue - like d_move() */ + goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED; @@ -242,7 +250,6 @@ + list_add(&goal->d_child, &goal->d_parent->d_subdirs); + list_add(&de->d_child, &de->d_parent->d_subdirs); + __d_rehash(goal, 0); -+ spin_unlock(&dcache_lock); + + return goal; +} @@ -286,7 +293,7 @@ + + inode = iget(dir->i_sb, EXT3_BAD_INO); + -+ if (!inode) ++ if (!inode) + return 0; + d_add(dentry, inode); + return 1; @@ -315,7 +322,7 @@ + inode->u.ext3_i.i_dtime = 0; + inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size + * (for stat), not the fs block -+ * size */ ++ * size */ + inode->i_blocks = 0; + inode->i_version = 1; + inode->i_generation = 0; @@ -326,24 +333,30 @@ + + return 1; +} ---- /dev/null Tue Jan 28 04:00:01 2003 -+++ linux-mmonroe/fs/ext3/iopen.h Thu Jul 10 12:28:54 2003 -@@ -0,0 +1,13 @@ +Index: linux-2.4.22-uml/fs/ext3/iopen.h +=================================================================== +--- linux-2.4.22-uml.orig/fs/ext3/iopen.h 2004-01-30 14:18:10.000000000 -0700 ++++ linux-2.4.22-uml/fs/ext3/iopen.h 2004-01-30 14:18:10.000000000 -0700 +@@ -0,0 +1,15 @@ +/* + * iopen.h + * + * Special support for opening files by inode number. -+ * ++ * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. + */ + +extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); +extern int ext3_iopen_get_inode(struct inode *inode); ---- linux/fs/ext3/namei.c~iopen-2.4.20 Thu Jul 10 12:28:46 2003 -+++ linux-mmonroe/fs/ext3/namei.c Thu Jul 10 12:28:54 2003 ++extern struct dentry *iopen_connect_dentry(struct dentry *de, ++ struct inode *inode); +Index: linux-2.4.22-uml/fs/ext3/namei.c +=================================================================== +--- linux-2.4.22-uml.orig/fs/ext3/namei.c 2004-01-30 14:17:59.000000000 -0700 ++++ linux-2.4.22-uml/fs/ext3/namei.c 2004-01-30 14:19:44.000000000 -0700 @@ -35,7 +35,7 @@ #include #include @@ -353,14 +366,7 @@ /* * define how far ahead to read directories while searching them. -@@ -921,16 +921,21 @@ errout: - return NULL; - } - #endif -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode); - - static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry) - { +@@ -927,10 +927,14 @@ struct inode * inode; struct ext3_dir_entry_2 * de; struct buffer_head * bh; @@ -375,29 +381,49 @@ bh = ext3_find_entry(dentry, &de); inode = NULL; if (bh) { -@@ -942,6 +947,12 @@ static struct dentry *ext3_lookup(struct +@@ -942,7 +946,28 @@ return ERR_PTR(-EACCES); } } +- d_add(dentry, inode); ++ ++ /* verify this dentry is really new */ ++ assert(!dentry->d_inode); ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ assert(list_empty(&dentry->d_subdirs)); + ++ spin_lock(&dcache_lock); + if (inode && (alternate = iopen_connect_dentry(dentry, inode))) { ++ spin_unlock(&dcache_lock); + iput(inode); + return alternate; + } + - d_add(dentry, inode); ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ if (inode) /* d_instantiate */ ++ list_add(&dentry->d_alias, &inode->i_dentry); ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ ++ spin_unlock(&dcache_lock); ++ return NULL; } ---- linux/fs/ext3/super.c~iopen-2.4.20 Thu Jul 10 12:28:45 2003 -+++ linux-mmonroe/fs/ext3/super.c Thu Jul 10 12:28:54 2003 -@@ -835,6 +835,17 @@ static int parse_options (char * options + +Index: linux-2.4.22-uml/fs/ext3/super.c +=================================================================== +--- linux-2.4.22-uml.orig/fs/ext3/super.c Sun Nov 16 01:19:22 2003 ++++ linux-2.4.22-uml/fs/ext3/super.c Sun Nov 16 01:27:31 2003 +@@ -839,6 +839,18 @@ || !strcmp (this_char, "quota") || !strcmp (this_char, "usrquota")) /* Don't do anything ;-) */ ; + else if (!strcmp (this_char, "iopen")) { + set_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); -+ } else if (!strcmp (this_char, "noiopen")) { ++ } ++ else if (!strcmp (this_char, "noiopen")) { + clear_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + } @@ -408,9 +434,11 @@ else if (!strcmp (this_char, "journal")) { /* @@@ FIXME */ /* Eventually we will want to be able to create ---- linux/include/linux/ext3_fs.h~iopen-2.4.20 Thu Jul 10 12:28:46 2003 -+++ linux-mmonroe/include/linux/ext3_fs.h Thu Jul 10 12:30:12 2003 -@@ -322,6 +322,8 @@ struct ext3_inode { +Index: linux-2.4.22-uml/include/linux/ext3_fs.h +=================================================================== +--- linux-2.4.22-uml.orig/include/linux/ext3_fs.h 2004-01-30 14:17:59.000000000 -0700 ++++ linux-2.4.22-uml/include/linux/ext3_fs.h 2004-01-30 14:18:10.000000000 -0700 +@@ -322,6 +322,8 @@ #define EXT3_MOUNT_UPDATE_JOURNAL 0x1000 /* Update the journal format */ #define EXT3_MOUNT_NO_UID32 0x2000 /* Disable 32-bit UIDs */ #define EXT3_MOUNT_XATTR_USER 0x4000 /* Extended user attributes */ @@ -419,5 +447,3 @@ #define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ - -_ diff --git a/lustre/kernel_patches/patches/iopen-2.4.21-chaos.patch b/lustre/kernel_patches/patches/iopen-2.4.21-chaos.patch index 74d1d85..16bde95 100644 --- a/lustre/kernel_patches/patches/iopen-2.4.21-chaos.patch +++ b/lustre/kernel_patches/patches/iopen-2.4.21-chaos.patch @@ -16,7 +16,7 @@ Index: linux-2.4.21-chaos/Documentation/filesystems/ext2.txt sb=n Use alternate superblock at this location. -+iopen Makes an invisible pseudo-directory called ++iopen Makes an invisible pseudo-directory called + __iopen__ available in the root directory + of the filesystem. Allows open-by-inode- + number. i.e., inode 3145 can be accessed @@ -66,7 +66,7 @@ Index: linux-2.4.21-chaos/fs/ext3/inode.c + if (ext3_iopen_get_inode(inode)) + return; -+ ++ if(ext3_get_inode_loc(inode, &iloc)) goto bad_inode; bh = iloc.bh; @@ -74,17 +74,17 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c =================================================================== --- linux-2.4.21-chaos.orig/fs/ext3/iopen.c 2003-01-30 13:24:37.000000000 +0300 +++ linux-2.4.21-chaos/fs/ext3/iopen.c 2003-12-12 16:19:05.000000000 +0300 -@@ -0,0 +1,259 @@ +@@ -0,0 +1,258 @@ +/* + * linux/fs/ext3/iopen.c + * + * Special support for open by inode number + * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. -+ * ++ * + * + * Invariants: + * - there is only ever a single DCACHE_NFSD_DISCONNECTED dentry alias @@ -130,7 +130,7 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + struct list_head *lp; + struct dentry *alternate; + char buf[IOPEN_NAME_LEN]; -+ ++ + if (dentry->d_name.len >= IOPEN_NAME_LEN) + return ERR_PTR(-ENAMETOOLONG); + @@ -159,6 +159,9 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + return ERR_PTR(-ENOENT); + } + ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ + /* preferrably return a connected dentry */ + spin_lock(&dcache_lock); + list_for_each(lp, &inode->i_dentry) { @@ -167,7 +170,7 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + } + + if (!list_empty(&inode->i_dentry)) { -+ alternate = list_entry(inode->i_dentry.next, ++ alternate = list_entry(inode->i_dentry.next, + struct dentry, d_alias); + dget_locked(alternate); + alternate->d_vfs_flags |= DCACHE_REFERENCED; @@ -176,9 +179,14 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + return alternate; + } + dentry->d_flags |= DCACHE_NFSD_DISCONNECTED; ++ ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ list_add(&dentry->d_alias, &inode->i_dentry); /* d_instantiate */ ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ + spin_unlock(&dcache_lock); + -+ d_add(dentry, inode); + return NULL; +} + @@ -190,7 +198,7 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c +{ + const unsigned char *old_name, *new_name; + -+ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); ++ memcpy(dentry->d_iname, target->d_iname, DNAME_INLINE_LEN); + old_name = target->d_name.name; + new_name = dentry->d_name.name; + if (old_name == target->d_iname) @@ -203,6 +211,7 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + +/* This function is spliced into ext3_lookup and does the move of a + * disconnected dentry (if it exists) to a connected dentry. ++ * Caller must hold dcache_lock. + */ +struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode) +{ @@ -210,13 +219,6 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + struct list_head *lp; + + /* preferrably return a connected dentry */ -+ spin_lock(&dcache_lock); -+ /* verify this dentry is really new */ -+ assert(!de->d_inode); -+ assert(list_empty(&de->d_subdirs)); -+ assert(list_empty(&de->d_alias)); -+ -+ + list_for_each(lp, &inode->i_dentry) { + tmp = list_entry(lp, struct dentry, d_alias); + if (tmp->d_flags & DCACHE_NFSD_DISCONNECTED) { @@ -228,10 +230,8 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + } + } + -+ if (!goal) { -+ spin_unlock(&dcache_lock); -+ return NULL; -+ } ++ if (!goal) ++ return NULL; + + /* Move the goal to the de hash queue - like d_move() */ + goal->d_flags &= ~DCACHE_NFSD_DISCONNECTED; @@ -250,7 +250,6 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + list_add(&goal->d_child, &goal->d_parent->d_subdirs); + list_add(&de->d_child, &de->d_parent->d_subdirs); + __d_rehash(goal, 0); -+ spin_unlock(&dcache_lock); + + return goal; +} @@ -294,7 +293,7 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + + inode = iget(dir->i_sb, EXT3_BAD_INO); + -+ if (!inode) ++ if (!inode) + return 0; + d_add(dentry, inode); + return 1; @@ -323,7 +322,7 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.c + inode->u.ext3_i.i_dtime = 0; + inode->i_blksize = PAGE_SIZE; /* This is the optimal IO size + * (for stat), not the fs block -+ * size */ ++ * size */ + inode->i_blocks = 0; + inode->i_version = 1; + inode->i_generation = 0; @@ -338,20 +337,22 @@ Index: linux-2.4.21-chaos/fs/ext3/iopen.h =================================================================== --- linux-2.4.21-chaos.orig/fs/ext3/iopen.h 2003-01-30 13:24:37.000000000 +0300 +++ linux-2.4.21-chaos/fs/ext3/iopen.h 2003-12-12 16:19:05.000000000 +0300 -@@ -0,0 +1,13 @@ +@@ -0,0 +1,15 @@ +/* + * iopen.h + * + * Special support for opening files by inode number. -+ * ++ * + * Copyright (C) 2001 by Theodore Ts'o (tytso@alum.mit.edu). -+ * ++ * + * This file may be redistributed under the terms of the GNU General + * Public License. + */ + +extern int ext3_check_for_iopen(struct inode *dir, struct dentry *dentry); +extern int ext3_iopen_get_inode(struct inode *inode); ++extern struct dentry *iopen_connect_dentry(struct dentry *de, ++ struct inode *inode); Index: linux-2.4.21-chaos/fs/ext3/namei.c =================================================================== --- linux-2.4.21-chaos.orig/fs/ext3/namei.c 2003-12-12 16:18:59.000000000 +0300 @@ -365,14 +366,7 @@ Index: linux-2.4.21-chaos/fs/ext3/namei.c /* * define how far ahead to read directories while searching them. -@@ -922,16 +922,21 @@ - return NULL; - } - #endif -+struct dentry *iopen_connect_dentry(struct dentry *de, struct inode *inode); - - static struct dentry *ext3_lookup(struct inode * dir, struct dentry *dentry) - { +@@ -922,10 +922,14 @@ struct inode * inode; struct ext3_dir_entry_2 * de; struct buffer_head * bh; @@ -387,31 +381,49 @@ Index: linux-2.4.21-chaos/fs/ext3/namei.c bh = ext3_find_entry(dentry, &de); inode = NULL; if (bh) { -@@ -943,6 +948,12 @@ +@@ -943,7 +948,28 @@ return ERR_PTR(-EACCES); } } +- d_add(dentry, inode); ++ ++ /* verify this dentry is really new */ ++ assert(!dentry->d_inode); ++ assert(list_empty(&dentry->d_alias)); /* d_instantiate */ ++ assert(list_empty(&dentry->d_hash)); /* d_rehash */ ++ assert(list_empty(&dentry->d_subdirs)); + ++ spin_lock(&dcache_lock); + if (inode && (alternate = iopen_connect_dentry(dentry, inode))) { ++ spin_unlock(&dcache_lock); + iput(inode); + return alternate; + } + - d_add(dentry, inode); ++ /* d_add(), but don't drop dcache_lock before adding dentry to inode */ ++ if (inode) /* d_instantiate */ ++ list_add(&dentry->d_alias, &inode->i_dentry); ++ dentry->d_inode = inode; ++ ++ __d_rehash(dentry, 0); /* d_rehash */ ++ spin_unlock(&dcache_lock); ++ return NULL; } + Index: linux-2.4.21-chaos/fs/ext3/super.c =================================================================== --- linux-2.4.21-chaos.orig/fs/ext3/super.c 2003-12-12 16:18:51.000000000 +0300 +++ linux-2.4.21-chaos/fs/ext3/super.c 2003-12-12 16:19:05.000000000 +0300 -@@ -890,6 +890,17 @@ +@@ -890,6 +890,18 @@ || !strcmp (this_char, "quota") || !strcmp (this_char, "usrquota")) /* Don't do anything ;-) */ ; + else if (!strcmp (this_char, "iopen")) { + set_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); -+ } else if (!strcmp (this_char, "noiopen")) { ++ } ++ else if (!strcmp (this_char, "noiopen")) { + clear_opt (sbi->s_mount_opt, IOPEN); + clear_opt (sbi->s_mount_opt, IOPEN_NOPRIV); + } diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch index 2efed4f..e29ae29 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.18-18-chaos65.patch @@ -275,10 +275,10 @@ { struct dentry * result; struct inode *dir = parent->d_inode; -+ int counter = 0; ++ int counter = 0; +again: -+ counter++; ++ counter++; down(&dir->i_sem); /* * First re-do the cached lookup just in case it was created @@ -300,10 +300,10 @@ + if (!result->d_op->d_revalidate_it(result, flags, it) && + !d_invalidate(result)) { + dput(result); -+ if (counter > 10) -+ result = ERR_PTR(-ESTALE); -+ if (!IS_ERR(result)) -+ goto again; ++ if (counter > 10) ++ result = ERR_PTR(-ESTALE); ++ if (!IS_ERR(result)) ++ goto again; + } } return result; @@ -1427,8 +1427,8 @@ { struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) -+ if (!inode) -+ return -ENOENT; ++ if (!inode) ++ return -ENOENT; + if (inode->i_op && inode->i_op->revalidate_it) + return inode->i_op->revalidate_it(dentry, it); + else if (inode->i_op && inode->i_op->revalidate) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch index 98fd550..5fbd0fc 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.19-pre1.patch @@ -453,11 +453,11 @@ Index: linux-2.4.19-pre1/fs/namei.c + &dentry->d_name, 0, NULL); + d_invalidate(dentry); + dput(dentry); -+ if (IS_ERR(new)) { -+ err = PTR_ERR(new); -+ break; -+ } -+ nd->dentry = new; ++ if (IS_ERR(new)) { ++ err = PTR_ERR(new); ++ break; ++ } ++ nd->dentry = new; + } + } else + if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { @@ -1406,8 +1406,8 @@ Index: linux-2.4.19-pre1/fs/stat.c { struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) -+ if (!inode) -+ return -ENOENT; ++ if (!inode) ++ return -ENOENT; + if (inode->i_op && inode->i_op->revalidate_it) + return inode->i_op->revalidate_it(dentry, it); + else if (inode->i_op && inode->i_op->revalidate) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch index b49babd..6b6027a 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.19-suse.patch @@ -436,11 +436,11 @@ Index: linux-2.4.19.SuSE/fs/namei.c + &dentry->d_name, 0, NULL); + d_invalidate(dentry); + dput(dentry); -+ if (IS_ERR(new)) { -+ err = PTR_ERR(new); -+ break; -+ } -+ nd->dentry = new; ++ if (IS_ERR(new)) { ++ err = PTR_ERR(new); ++ break; ++ } ++ nd->dentry = new; + } + } else if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { @@ -1386,8 +1386,8 @@ Index: linux-2.4.19.SuSE/fs/stat.c { struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) -+ if (!inode) -+ return -ENOENT; ++ if (!inode) ++ return -ENOENT; + if (inode->i_op && inode->i_op->revalidate_it) + return inode->i_op->revalidate_it(dentry, it); + else if (inode->i_op && inode->i_op->revalidate) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch index a632e00..082b8b7 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.20-hp.patch @@ -482,11 +482,11 @@ + &dentry->d_name, 0, NULL); + d_invalidate(dentry); + dput(dentry); -+ if (IS_ERR(new)) { -+ err = PTR_ERR(new); -+ break; -+ } -+ nd->dentry = new; ++ if (IS_ERR(new)) { ++ err = PTR_ERR(new); ++ break; ++ } ++ nd->dentry = new; + } + } else if (dentry && dentry->d_op && dentry->d_op->d_revalidate) { @@ -1450,8 +1450,8 @@ { struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) -+ if (!inode) -+ return -ENOENT; ++ if (!inode) ++ return -ENOENT; + if (inode->i_op && inode->i_op->revalidate_it) + return inode->i_op->revalidate_it(dentry, it); + else if (inode->i_op && inode->i_op->revalidate) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch index c4c79b1..7d83b5e 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.20-vanilla.patch @@ -1370,8 +1370,8 @@ { struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) -+ if (!inode) -+ return -ENOENT; ++ if (!inode) ++ return -ENOENT; + if (inode->i_op && inode->i_op->revalidate_it) + return inode->i_op->revalidate_it(dentry, it); + else if (inode->i_op && inode->i_op->revalidate) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch index 1ceb50d..7587ad2 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.21-chaos.patch @@ -1390,8 +1390,8 @@ Index: linux-2.4.21-chaos/fs/stat.c { struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) -+ if (!inode) -+ return -ENOENT; ++ if (!inode) ++ return -ENOENT; + if (inode->i_op && inode->i_op->revalidate_it) + return inode->i_op->revalidate_it(dentry, it); + else if (inode->i_op && inode->i_op->revalidate) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse2.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse2.patch index 98c6c37..492e32a 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse2.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.21-suse2.patch @@ -1398,8 +1398,8 @@ Index: linux-2.4.21-suse2/fs/stat.c { struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) -+ if (!inode) -+ return -ENOENT; ++ if (!inode) ++ return -ENOENT; + if (inode->i_op && inode->i_op->revalidate_it) + return inode->i_op->revalidate_it(dentry, it); + else if (inode->i_op && inode->i_op->revalidate) diff --git a/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch b/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch index ace8619..ff5ef61 100644 --- a/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch +++ b/lustre/kernel_patches/patches/vfs_intent-2.4.22-rh.patch @@ -1370,8 +1370,8 @@ { struct inode * inode = dentry->d_inode; - if (inode->i_op && inode->i_op->revalidate) -+ if (!inode) -+ return -ENOENT; ++ if (!inode) ++ return -ENOENT; + if (inode->i_op && inode->i_op->revalidate_it) + return inode->i_op->revalidate_it(dentry, it); + else if (inode->i_op && inode->i_op->revalidate) diff --git a/lustre/kernel_patches/patches/vfs_intent_2.6.0-test1.patch b/lustre/kernel_patches/patches/vfs_intent_2.6.0-test1.patch index 1f840e8..3d75965 100644 --- a/lustre/kernel_patches/patches/vfs_intent_2.6.0-test1.patch +++ b/lustre/kernel_patches/patches/vfs_intent_2.6.0-test1.patch @@ -85,10 +85,10 @@ { struct dentry * result; struct inode *dir = parent->d_inode; -+ int counter = 0; ++ int counter = 0; +again: -+ counter++; ++ counter++; down(&dir->i_sem); /* * First re-do the cached lookup just in case it was created @@ -97,10 +97,10 @@ if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { dput(result); - result = ERR_PTR(-ENOENT); -+ if (counter > 10) -+ result = ERR_PTR(-ESTALE); -+ if (!IS_ERR(result)) -+ goto again; ++ if (counter > 10) ++ result = ERR_PTR(-ESTALE); ++ if (!IS_ERR(result)) ++ goto again; } } return result; diff --git a/lustre/kernel_patches/patches/vfs_intent_2.6.0-test6.patch b/lustre/kernel_patches/patches/vfs_intent_2.6.0-test6.patch index 5dd86e0..6742227 100644 --- a/lustre/kernel_patches/patches/vfs_intent_2.6.0-test6.patch +++ b/lustre/kernel_patches/patches/vfs_intent_2.6.0-test6.patch @@ -89,10 +89,10 @@ Index: linux-2.6.0-test6/fs/namei.c { struct dentry * result; struct inode *dir = parent->d_inode; -+ int counter = 0; ++ int counter = 0; +again: -+ counter++; ++ counter++; down(&dir->i_sem); /* * First re-do the cached lookup just in case it was created @@ -101,10 +101,10 @@ Index: linux-2.6.0-test6/fs/namei.c if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { dput(result); - result = ERR_PTR(-ENOENT); -+ if (counter > 10) -+ result = ERR_PTR(-ESTALE); -+ if (!IS_ERR(result)) -+ goto again; ++ if (counter > 10) ++ result = ERR_PTR(-ESTALE); ++ if (!IS_ERR(result)) ++ goto again; } } return result; diff --git a/lustre/kernel_patches/patches/vfs_intent_2.6.0.patch b/lustre/kernel_patches/patches/vfs_intent_2.6.0.patch index 8fa267c..7514caa 100644 --- a/lustre/kernel_patches/patches/vfs_intent_2.6.0.patch +++ b/lustre/kernel_patches/patches/vfs_intent_2.6.0.patch @@ -89,10 +89,10 @@ Index: linux-2.6.0/fs/namei.c { struct dentry * result; struct inode *dir = parent->d_inode; -+ int counter = 0; ++ int counter = 0; +again: -+ counter++; ++ counter++; down(&dir->i_sem); /* * First re-do the cached lookup just in case it was created @@ -101,10 +101,10 @@ Index: linux-2.6.0/fs/namei.c if (!result->d_op->d_revalidate(result, nd) && !d_invalidate(result)) { dput(result); - result = ERR_PTR(-ENOENT); -+ if (counter > 10) -+ result = ERR_PTR(-ESTALE); -+ if (!IS_ERR(result)) -+ goto again; ++ if (counter > 10) ++ result = ERR_PTR(-ESTALE); ++ if (!IS_ERR(result)) ++ goto again; } } return result; -- 1.8.3.1