From caabd4ce8ee6a6bac01ec9d515052cc9a6b7bd15 Mon Sep 17 00:00:00 2001 From: adilger Date: Wed, 25 Aug 2004 07:25:38 +0000 Subject: [PATCH] Add ext3-nlinks for RHEL3/chaos --- .../patches/ext3-nlinks-2.4.21-chaos.patch | 174 +++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 lustre/kernel_patches/patches/ext3-nlinks-2.4.21-chaos.patch diff --git a/lustre/kernel_patches/patches/ext3-nlinks-2.4.21-chaos.patch b/lustre/kernel_patches/patches/ext3-nlinks-2.4.21-chaos.patch new file mode 100644 index 0000000..debe4b3 --- /dev/null +++ b/lustre/kernel_patches/patches/ext3-nlinks-2.4.21-chaos.patch @@ -0,0 +1,174 @@ +Index: 69chaos/fs/ext3/namei.c +=================================================================== +--- 69chaos.orig/fs/ext3/namei.c 2004-08-24 23:56:04.000000000 -0700 ++++ 69chaos/fs/ext3/namei.c 2004-08-24 23:57:20.000000000 -0700 +@@ -1542,11 +1542,16 @@ + static inline void ext3_inc_count(handle_t *handle, struct inode *inode) + { + inode->i_nlink++; ++ if (is_dx(inode) && inode->i_nlink > 1) { ++ if (inode->i_nlink >= 65000) /* limit is 16-bit i_links_count */ ++ inode->i_nlink = 1; ++ } + } + + static inline void ext3_dec_count(handle_t *handle, struct inode *inode) + { +- inode->i_nlink--; ++ if (!S_ISDIR(inode->i_mode) || inode->i_nlink > 2) ++ inode->i_nlink--; + } + + static int ext3_add_nondir(handle_t *handle, +@@ -1650,7 +1655,7 @@ + struct ext3_dir_entry_2 * de; + int err; + +- if (dir->i_nlink >= EXT3_LINK_MAX) ++ if (EXT3_DIR_LINK_MAXED(dir)) + return -EMLINK; + + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + +@@ -1672,7 +1677,7 @@ + inode->i_size = EXT3_I(inode)->i_disksize = inode->i_sb->s_blocksize; + dir_block = ext3_bread (handle, inode, 0, 1, &err); + if (!dir_block) { +- inode->i_nlink--; /* is this nlink == 0? */ ++ ext3_dec_count(handle, inode); /* is this nlink == 0? */ + ext3_mark_inode_dirty(handle, inode); + iput (inode); + goto out_stop; +@@ -1704,7 +1709,7 @@ + iput (inode); + goto out_stop; + } +- dir->i_nlink++; ++ ext3_inc_count(handle, dir); + ext3_update_dx_flag(dir); + ext3_mark_inode_dirty(handle, dir); + d_instantiate(dentry, inode); +@@ -1765,10 +1770,11 @@ + } + de = (struct ext3_dir_entry_2 *) bh->b_data; + } +- if (!ext3_check_dir_entry ("empty_dir", inode, de, bh, +- offset)) { +- brelse (bh); +- return 1; ++ if (!ext3_check_dir_entry("empty_dir", inode, de, bh, offset)) { ++ /* On error skip the de and offset to the next block. */ ++ de = (void *)(bh->b_data + sb->s_blocksize); ++ offset = (offset | (sb->s_blocksize - 1)) + 1; ++ continue; + } + if (le32_to_cpu(de->inode)) { + brelse (bh); +@@ -1960,14 +1966,14 @@ + retval = ext3_delete_entry(handle, dir, de, bh); + if (retval) + goto end_rmdir; +- if (inode->i_nlink != 2) +- ext3_warning (inode->i_sb, "ext3_rmdir", +- "empty directory has nlink!=2 (%d)", +- inode->i_nlink); ++ if (!EXT3_DIR_LINK_EMPTY(inode)) ++ ext3_warning(inode->i_sb, __FUNCTION__, ++ "empty directory has too many links (%d)", ++ inode->i_nlink); + inode->i_version = ++event; + inode->i_nlink = 0; + ext3_orphan_add(handle, inode); +- dir->i_nlink--; ++ ext3_dec_count(handle, dir); + inode->i_ctime = dir->i_ctime = dir->i_mtime = CURRENT_TIME; + ext3_mark_inode_dirty(handle, inode); + ext3_update_dx_flag(dir); +@@ -2019,7 +2025,7 @@ + dir->i_ctime = dir->i_mtime = CURRENT_TIME; + ext3_update_dx_flag(dir); + ext3_mark_inode_dirty(handle, dir); +- inode->i_nlink--; ++ ext3_dec_count(handle, inode); + if (!inode->i_nlink) + ext3_orphan_add(handle, inode); + inode->i_ctime = dir->i_ctime; +@@ -2111,9 +2117,8 @@ + if (S_ISDIR(inode->i_mode)) + return -EPERM; + +- if (inode->i_nlink >= EXT3_LINK_MAX) { ++ if (EXT3_DIR_LINK_MAXED(inode)) + return -EMLINK; +- } + + handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + + EXT3_INDEX_EXTRA_TRANS_BLOCKS); +@@ -2197,8 +2202,8 @@ + if (le32_to_cpu(PARENT_INO(dir_bh->b_data)) != old_dir->i_ino) + goto end_rename; + retval = -EMLINK; +- if (!new_inode && new_dir!=old_dir && +- new_dir->i_nlink >= EXT3_LINK_MAX) ++ if (!new_inode && new_dir != old_dir && ++ EXT3_DIR_LINK_MAXED(new_dir)) + goto end_rename; + } + if (!new_bh) { +@@ -2256,7 +2261,7 @@ + } + + if (new_inode) { +- new_inode->i_nlink--; ++ ext3_dec_count(handle, new_inode); + new_inode->i_ctime = CURRENT_TIME; + } + old_dir->i_ctime = old_dir->i_mtime = CURRENT_TIME; +@@ -2267,11 +2272,11 @@ + PARENT_INO(dir_bh->b_data) = le32_to_cpu(new_dir->i_ino); + BUFFER_TRACE(dir_bh, "call ext3_journal_dirty_metadata"); + ext3_journal_dirty_metadata(handle, dir_bh); +- old_dir->i_nlink--; ++ ext3_dec_count(handle, old_dir); + if (new_inode) { +- new_inode->i_nlink--; ++ ext3_dec_count(handle, new_inode); + } else { +- new_dir->i_nlink++; ++ ext3_inc_count(handle, new_dir); + ext3_update_dx_flag(new_dir); + ext3_mark_inode_dirty(handle, new_dir); + } +Index: 69chaos/include/linux/ext3_fs.h +=================================================================== +--- 69chaos.orig/include/linux/ext3_fs.h 2004-08-24 23:55:45.000000000 -0700 ++++ 69chaos/include/linux/ext3_fs.h 2004-08-24 23:56:47.000000000 -0700 +@@ -44,7 +44,7 @@ + /* + * Always enable hashed directories + */ +-#define CONFIG_EXT3_INDEX ++#define CONFIG_EXT3_INDEX 1 + + /* + * Debug code +@@ -582,14 +582,15 @@ + */ + + #ifdef CONFIG_EXT3_INDEX +- #define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ +- EXT3_FEATURE_COMPAT_DIR_INDEX) && \ ++#define is_dx(dir) (EXT3_HAS_COMPAT_FEATURE(dir->i_sb, \ ++ EXT3_FEATURE_COMPAT_DIR_INDEX) && \ + (EXT3_I(dir)->i_flags & EXT3_INDEX_FL)) +-#define EXT3_DIR_LINK_MAX(dir) (!is_dx(dir) && (dir)->i_nlink >= EXT3_LINK_MAX) +-#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || (dir)->i_nlink == 1) ++#define EXT3_DIR_LINK_MAXED(dir) (!is_dx(dir) && (dir)->i_nlink >=EXT3_LINK_MAX) ++#define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2 || \ ++ (is_dx(dir) && (dir)->i_nlink == 1)) + #else + #define is_dx(dir) 0 +-#define EXT3_DIR_LINK_MAX(dir) ((dir)->i_nlink >= EXT3_LINK_MAX) ++#define EXT3_DIR_LINK_MAXED(dir) ((dir)->i_nlink >= EXT3_LINK_MAX) + #define EXT3_DIR_LINK_EMPTY(dir) ((dir)->i_nlink == 2) + #endif + -- 1.8.3.1