From 3f8c5ac582201e420c1ab1ca659d7665f7855140 Mon Sep 17 00:00:00 2001 From: alex Date: Sat, 7 Aug 2004 14:09:37 +0000 Subject: [PATCH] b=3550 - with ext3-reserve-inode-space patch ext3 reserve last group for creation with O_INRESERVE flag only (in order to save patch) --- .../patches/ext3-reserve-inode-space-2.4.24.patch | 238 +++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 lustre/kernel_patches/patches/ext3-reserve-inode-space-2.4.24.patch diff --git a/lustre/kernel_patches/patches/ext3-reserve-inode-space-2.4.24.patch b/lustre/kernel_patches/patches/ext3-reserve-inode-space-2.4.24.patch new file mode 100644 index 0000000..65c6419 --- /dev/null +++ b/lustre/kernel_patches/patches/ext3-reserve-inode-space-2.4.24.patch @@ -0,0 +1,238 @@ +Index: linux-2.4.24/fs/ext3/ialloc.c +=================================================================== +--- linux-2.4.24.orig/fs/ext3/ialloc.c 2004-08-02 22:13:13.000000000 +0400 ++++ linux-2.4.24/fs/ext3/ialloc.c 2004-08-04 01:10:30.000000000 +0400 +@@ -41,6 +41,24 @@ + * when a file system is mounted (see ext3_read_super). + */ + ++/* ++ * this is very simple policy: files with O_INRESERVE goes to last group; ++ * files with no O_INRESERVE goes to all groups, but last. probably we'll ++ * specify group for O_INRESERVE files later -bzzz */ ++static inline int ext3_group_allowed(struct super_block *sb, int mode, int group) ++{ ++ if (!test_opt(sb, INRESERVE) || EXT3_SB(sb)->s_groups_count == 1) ++ return 1; ++ ++ if (mode & EXT3_S_INRESERVE) { ++ if (group != EXT3_SB(sb)->s_groups_count - 1) ++ return 0; ++ } else { ++ if (group == EXT3_SB(sb)->s_groups_count -1 ) ++ return 0; ++ } ++ return 1; ++} + + /* + * Read the inode allocation bitmap for a given block_group, reading +@@ -337,20 +355,33 @@ + return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data); + } + +-int ext3_find_group_dir(const struct inode *dir, ++int ext3_find_group_dir(const struct inode *dir, int mode, + struct ext3_group_desc **gdp, + struct buffer_head **bh) + { + struct super_block *sb = dir->i_sb; + struct ext3_super_block *es; + struct ext3_group_desc *tmp; +- int i = 0, j, avefreei; ++ int i = 0, j, ifree, avefreei; + + es = EXT3_SB(sb)->s_es; +- avefreei = le32_to_cpu(es->s_free_inodes_count) / +- sb->u.ext3_sb.s_groups_count; ++ ifree = le32_to_cpu(es->s_free_inodes_count); ++ j = sb->u.ext3_sb.s_groups_count; ++ if (test_opt(sb, INRESERVE) && EXT3_SB(sb)->s_groups_count > 1) { ++ tmp = ext3_get_group_desc(sb, EXT3_SB(sb)->s_groups_count-1, NULL); ++ if (mode & EXT3_S_INRESERVE) { ++ ifree = le16_to_cpu(tmp->bg_free_blocks_count); ++ j = 1; ++ } else { ++ ifree -= le16_to_cpu(tmp->bg_free_blocks_count); ++ j--; ++ } ++ } ++ avefreei = ifree / j; + for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) { + struct buffer_head *temp_buffer; ++ if (!ext3_group_allowed(sb, mode, j)) ++ continue; + tmp = ext3_get_group_desc(sb, j, &temp_buffer); + if (tmp && le16_to_cpu(tmp->bg_free_inodes_count) && + le16_to_cpu(tmp->bg_free_inodes_count) >= avefreei) { +@@ -366,7 +397,7 @@ + return i; + } + +-int ext3_find_group_other(const struct inode *dir, ++int ext3_find_group_other(const struct inode *dir, int mode, + struct ext3_group_desc **gdp, + struct buffer_head **bh) + { +@@ -379,7 +410,8 @@ + */ + i = dir->u.ext3_i.i_block_group; + tmp = ext3_get_group_desc(sb, i, bh); +- if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) ++ if (tmp && le16_to_cpu(tmp->bg_free_inodes_count) ++ && ext3_group_allowed(sb, mode, i)) + *gdp = tmp; + else { + /* +@@ -390,6 +422,8 @@ + i += j; + if (i >= sb->u.ext3_sb.s_groups_count) + i -= sb->u.ext3_sb.s_groups_count; ++ if (!ext3_group_allowed(sb, mode, i)) ++ continue; + tmp = ext3_get_group_desc (sb, i, bh); + if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) { + *gdp = tmp; +@@ -405,6 +439,8 @@ + for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) { + if (++i >= sb->u.ext3_sb.s_groups_count) + i = 0; ++ if (!ext3_group_allowed(sb, mode, i)) ++ continue; + tmp = ext3_get_group_desc (sb, i, bh); + if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) { + *gdp = tmp; +@@ -421,8 +457,8 @@ + struct buffer_head **bh) + { + if (S_ISDIR(mode)) +- return ext3_find_group_dir(dir, gdp, bh); +- return ext3_find_group_other(dir, gdp, bh); ++ return ext3_find_group_dir(dir, mode, gdp, bh); ++ return ext3_find_group_other(dir, mode, gdp, bh); + } + + static int ext3_find_usable_inode(struct super_block *sb, +@@ -549,6 +585,8 @@ + for (i = i + 1; i != k; i++) { + if (i >= sb->u.ext3_sb.s_groups_count) + i = 0; ++ if (!ext3_group_allowed(sb, mode, i)) ++ continue; + tmp = ext3_get_group_desc(sb, i, &bh2); + if (le16_to_cpu(tmp->bg_free_inodes_count) == 0) + continue; +@@ -588,6 +626,7 @@ + if (buffer_jbd(bh) && bh2jh(bh)->b_committed_data) + J_ASSERT_BH(bh, !ext3_test_bit(j, bh2jh(bh)->b_committed_data)); + ++ J_ASSERT(ext3_group_allowed(sb, mode, i)); + j += i * EXT3_INODES_PER_GROUP(sb) + 1; + if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) { + ext3_error (sb, "ext3_new_inode", +@@ -628,7 +667,7 @@ + mode |= S_ISGID; + } else + inode->i_gid = current->fsgid; +- inode->i_mode = mode; ++ inode->i_mode = mode & ~EXT3_S_INRESERVE; + + inode->i_ino = j; + /* This is the optimal IO size (for stat), not the fs block size */ +Index: linux-2.4.24/fs/ext3/super.c +=================================================================== +--- linux-2.4.24.orig/fs/ext3/super.c 2004-08-02 22:13:12.000000000 +0400 ++++ linux-2.4.24/fs/ext3/super.c 2004-08-04 00:10:07.000000000 +0400 +@@ -723,6 +723,10 @@ + return 0; + *resgid = v; + } ++ else if (!strcmp (this_char, "inrsv")) { ++ set_opt (*mount_options, INRESERVE); ++ J_ASSERT((EXT3_S_INRESERVE & S_IALLUGO) == 0); ++ } + else if (!strcmp (this_char, "resuid")) { + unsigned long v; + if (want_numeric(value, "resuid", &v)) +Index: linux-2.4.24/fs/ext3/namei.c +=================================================================== +--- linux-2.4.24.orig/fs/ext3/namei.c 2004-08-02 22:13:13.000000000 +0400 ++++ linux-2.4.24/fs/ext3/namei.c 2004-08-03 03:21:09.000000000 +0400 +@@ -1971,6 +1971,36 @@ + return err; + } + ++static int ext3_create_it (struct inode * dir, struct dentry * dentry, int mode, ++ struct lookup_intent *it) ++{ ++ handle_t *handle; ++ struct inode * inode; ++ int err; ++ ++ handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS + ++ EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3); ++ if (IS_ERR(handle)) { ++ return PTR_ERR(handle); ++ } ++ ++ if (IS_SYNC(dir)) ++ handle->h_sync = 1; ++ ++ if (it && it->it_flags & O_INRESERVE) ++ mode |= EXT3_S_INRESERVE; ++ inode = ext3_new_inode_wantedi (handle, dir, mode, dentry); ++ err = PTR_ERR(inode); ++ if (!IS_ERR(inode)) { ++ inode->i_op = &ext3_file_inode_operations; ++ inode->i_fop = &ext3_file_operations; ++ inode->i_mapping->a_ops = &ext3_aops; ++ err = ext3_add_nondir(handle, dentry, inode); ++ } ++ ext3_journal_stop(handle, dir); ++ return err; ++} ++ + static int ext3_mknod (struct inode * dir, struct dentry *dentry, + int mode, int rdev) + { +@@ -2803,6 +2833,7 @@ + */ + struct inode_operations ext3_dir_inode_operations = { + create: ext3_create, /* BKL held */ ++ create_it: ext3_create_it, /* BKL held */ + lookup: ext3_lookup, /* BKL held */ + lookup_raw: ext3_lookup_raw, /* BKL held */ + link: ext3_link, /* BKL held */ +Index: linux-2.4.24/include/asm-i386/fcntl.h +=================================================================== +--- linux-2.4.24.orig/include/asm-i386/fcntl.h 2001-09-18 00:16:30.000000000 +0400 ++++ linux-2.4.24/include/asm-i386/fcntl.h 2004-08-03 01:20:55.000000000 +0400 +@@ -20,6 +20,7 @@ + #define O_LARGEFILE 0100000 + #define O_DIRECTORY 0200000 /* must be a directory */ + #define O_NOFOLLOW 0400000 /* don't follow links */ ++#define O_INRESERVE 01000000 /* allocate inodes in reserved space */ + + #define F_DUPFD 0 /* dup */ + #define F_GETFD 1 /* get close_on_exec */ +Index: linux-2.4.24/include/linux/ext3_fs.h +=================================================================== +--- linux-2.4.24.orig/include/linux/ext3_fs.h 2004-08-02 22:13:12.000000000 +0400 ++++ linux-2.4.24/include/linux/ext3_fs.h 2004-08-03 01:03:39.000000000 +0400 +@@ -343,6 +343,7 @@ + #define EXT3_MOUNT_ASYNCDEL 0x20000 /* Delayed deletion */ + #define EXT3_MOUNT_EXTENTS 0x100000/* Extents support */ + #define EXT3_MOUNT_EXTDEBUG 0x200000/* Extents debug */ ++#define EXT3_MOUNT_INRESERVE 0x400000/* reserve one group for O_INRESERVE */ + + /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */ + #ifndef _LINUX_EXT2_FS_H +@@ -482,6 +483,8 @@ + + #define EXT3_GOOD_OLD_INODE_SIZE 128 + ++#define EXT3_S_INRESERVE 01000000 ++ + /* + * Feature set definitions + */ -- 1.8.3.1