Whamcloud - gitweb
b=3550
authoralex <alex>
Sat, 7 Aug 2004 14:09:37 +0000 (14:09 +0000)
committeralex <alex>
Sat, 7 Aug 2004 14:09:37 +0000 (14:09 +0000)
- with ext3-reserve-inode-space patch ext3 reserve last group for
  creation with O_INRESERVE flag only
  (in order to save patch)

lustre/kernel_patches/patches/ext3-reserve-inode-space-2.4.24.patch [new file with mode: 0644]

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 (file)
index 0000000..65c6419
--- /dev/null
@@ -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
+  */