Whamcloud - gitweb
- ext3 batching allocation against suse2 series
authoralex <alex>
Thu, 5 Feb 2004 17:58:11 +0000 (17:58 +0000)
committeralex <alex>
Thu, 5 Feb 2004 17:58:11 +0000 (17:58 +0000)
- ext3-mballoc* patches export ext3_new_blocks()

lustre/kernel_patches/patches/ext3-mballoc-2.4.21-suse2.patch [new file with mode: 0644]
lustre/kernel_patches/patches/ext3-mballoc-2.4.24.patch

diff --git a/lustre/kernel_patches/patches/ext3-mballoc-2.4.21-suse2.patch b/lustre/kernel_patches/patches/ext3-mballoc-2.4.21-suse2.patch
new file mode 100644 (file)
index 0000000..2fd940d
--- /dev/null
@@ -0,0 +1,368 @@
+Index: linux-2.4.21-suse2/fs/ext3/balloc.c
+===================================================================
+--- linux-2.4.21-suse2.orig/fs/ext3/balloc.c   2003-06-13 18:51:37.000000000 +0400
++++ linux-2.4.21-suse2/fs/ext3/balloc.c        2004-02-05 20:50:48.000000000 +0300
+@@ -11,6 +11,7 @@
+  *        David S. Miller (davem@caip.rutgers.edu), 1995
+  */
++#include <linux/module.h>
+ #include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/fs.h>
+@@ -1007,3 +1008,298 @@
+                       bitmap_count);
+ }
+ #endif
++
++#define MBDEBUG_
++#ifdef MBDEBUG
++#define mbdebug(fmt,a...)     printk(fmt, ##a)
++#else
++#define mbdebug(fmt,a...)
++#endif
++
++/*
++ * in alloc_status we track allocation: the best found extent, how many
++ * extents we've skipped, etc
++ */
++struct alloc_status {
++      struct inode *inode;
++      struct super_block *sb;
++      int goal;               /* goal for allocation */
++      int target_len;         /* goal for len */
++      int start, len;         /* the best found extent */
++      int num;                /* number of extent: to limit searching */
++};
++
++/*
++ * ext3_test_extent() compares requested extent with existing in as.
++ * if requested extent is better than that, then replace old one.
++ * then it tries to understand is new extent suitable or not
++ * return 1 if caller can complete searching
++ */
++inline int ext3_test_extent(struct alloc_status *as, int group,
++                              int start, int len)
++{
++      struct ext3_super_block * es = EXT3_SB(as->sb)->s_es;
++      unsigned long tmp;
++
++      J_ASSERT(as->target_len >= len);
++
++      mbdebug("found extent %d:%d\n", start, len);
++      tmp = start + group * EXT3_BLOCKS_PER_GROUP(as->sb)
++                      + le32_to_cpu(es->s_first_data_block);
++
++      /* account requests in order to limit searching */
++      as->num++;
++
++      if (as->num == 20)
++              return 1;
++
++      /* if hit goal, then searching may complete right now */
++      if (tmp == as->goal) {
++nice:
++              as->start = tmp;
++              as->len = len;
++              return 1;
++      }
++
++      /* if found extent has lenght we need, return it right now */
++      if (as->target_len == len)
++              goto nice;
++
++      /* first, check is found extent better than we have in as */
++      if (as->len > len) {
++better:
++              as->start = tmp;
++              as->len = len;
++              return 0;
++      }
++
++      /* FIXME: more checks! */
++      as->start = tmp;
++      as->len = len;
++
++      /* 1) closeness to goal */
++      
++      /* 2) extent lenght */
++      /* 3) number of tested extent (we check all found extents) */
++      /* */
++      return 0;
++}
++
++/*
++ * this routine tries to find upto *len free contig. blocks
++ * return number of found block (+ lenght of extent in *len)
++ * or -1 if no free blocks at all
++ */
++int ext3_find_free_extent(struct buffer_head *bh, int goal, int *len, int max)
++{
++      int i, l = 0;
++
++repeat:
++      if (goal >= max)
++              return -1;
++      /* find first free block */
++      i = ext3_find_next_zero_bit(bh->b_data, max, goal);
++      if (i >= max) {
++              /* no free block */
++              return -1;
++      }
++      /* check upto len block for ability to be allocated */
++      while (l < *len && i + l < max) {
++              if (!ext3_test_allocatable(i + l, bh))
++                      break;
++              l++;
++      }
++      if (l == 0) {
++              goal = i + 1;
++              goto repeat;
++      }
++      *len = l;
++      return i;
++}
++
++/*
++ * this routine loops over group, finds free extents and tests them
++ * for some criterias
++ * it may return negative value if group can't be loaded, 0 - if
++ * no good extent can be found, 1 - if good extent found
++ */
++int ext3_find_extent_in_group(struct alloc_status *as, int group,
++                              unsigned long goal, int len)
++{
++      int k, i, l, bitmap_nr, found = 0;
++      struct super_block *sb = as->sb;
++      int max = EXT3_BLOCKS_PER_GROUP(sb);
++      struct buffer_head *bh, *bmbh;
++      struct ext3_group_desc *gdp;
++
++      mbdebug("look for %d blocks in group %d starting from %lu\n",
++                      len, group, goal);
++
++      gdp = ext3_get_group_desc(as->sb, group, &bh);
++      if (!gdp)
++              return -EIO;
++
++      if (le16_to_cpu(gdp->bg_free_blocks_count) == 0)
++              return 0;
++
++      bitmap_nr = load_block_bitmap(as->sb, group);
++      if (bitmap_nr < 0)
++              return -EIO;
++
++      bmbh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr];
++
++      i = goal;
++      /* scan from goal to the end */
++repeat:
++      while (i < max) {
++              l = len;
++              k = ext3_find_free_extent(bmbh, i, &l, max);
++              i = k + l;
++              if (k < 0)
++                      break;
++              if (ext3_test_extent(as, group, k, l)) {
++                      found = 1;
++                      goto out;
++              }
++      }
++
++      if (goal) {
++              /* scan from 0 upto goal */
++              mbdebug("repeat from %lu in %d\n", goal, group);
++              max = goal - 1;
++              goal = i = 0;
++              goto repeat;
++      }
++out:
++      return found; 
++}
++
++#define check_in_committed(bh,j)      \
++      J_ASSERT_BH((bh), !ext3_test_bit((j), bh2jh((bh))->b_committed_data))
++
++int ext3_new_blocks(handle_t *handle, struct inode *inode, int *num,
++                      unsigned long goal, int *errp)
++{
++      struct super_block *sb = inode->i_sb;
++      int first_group, group, bitmap_nr;
++      struct buffer_head *bh, *bmbh;
++      struct ext3_super_block *es;
++      struct ext3_group_desc *gdp;
++      struct alloc_status as;
++      int err, bit, i;
++
++      int scaned = 0;
++
++      J_ASSERT(num && *num > 0);
++
++      if (DQUOT_ALLOC_BLOCK(inode, *num)) {
++              *errp = -EDQUOT;
++              return 0;
++      }
++
++      es = EXT3_SB(inode->i_sb)->s_es;
++
++      *errp = 0;
++      as.target_len = *num;
++      as.sb = sb;
++      as.inode = inode;
++      as.goal = goal;
++      as.start = -1;
++      as.len = 0;
++      as.num = 0;
++
++      lock_super(sb);
++      first_group = (goal - le32_to_cpu(es->s_first_data_block)) /
++                      EXT3_BLOCKS_PER_GROUP(sb);
++      goal = (goal - le32_to_cpu(es->s_first_data_block)) %
++                      EXT3_BLOCKS_PER_GROUP(sb);
++      group = first_group;
++      do {
++              scaned++;
++              err = ext3_find_extent_in_group(&as, group, goal, *num);
++              if (err < 0) 
++                      goto error_out;
++              else if (err)
++                      break;
++
++              /* reset goal for next groups */
++              goal = 0;
++
++              /* try next group */
++              if (++group == EXT3_SB(sb)->s_groups_count)
++                      group = 0;
++      } while (group != first_group);
++
++      if (as.len == 0) {
++              err = -ENOSPC;
++              goto error_out;
++      }
++
++      /* in the end we've found something, allocate it */
++      mbdebug("best extent: %u:%u\n", as.start, as.len);
++
++      group = (as.start - le32_to_cpu(es->s_first_data_block)) /
++              EXT3_BLOCKS_PER_GROUP(sb);
++      bit = (as.start - le32_to_cpu(es->s_first_data_block)) %
++              EXT3_BLOCKS_PER_GROUP(sb);
++      gdp = ext3_get_group_desc(sb, group, &bh);
++      if (!gdp) {
++              err = -EIO;
++              goto error_out; 
++      }
++
++      /* mark block(s) used in bitmap ... */
++      bitmap_nr = load_block_bitmap(sb, group);
++      if (bitmap_nr < 0) {
++              err = -EIO;
++              goto error_out;
++      }
++      bmbh = EXT3_SB(sb)->s_block_bitmap[bitmap_nr];
++      err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
++      if (err)
++              goto error_out;
++      err = ext3_journal_get_write_access(handle, bmbh);
++      if (err)
++              goto error_out;
++      err = ext3_journal_get_write_access(handle, bh);
++      if (err)
++              goto error_out;
++      for (i = 0; i < as.len; i++) {
++              J_ASSERT(!ext3_test_bit(bit + i, bmbh->b_data));
++              if (buffer_jbd(bmbh) && bh2jh(bmbh)->b_committed_data)
++                      check_in_committed(bmbh, bit + i);
++              set_bit(bit + i, bmbh->b_data);
++      }
++      err = ext3_journal_dirty_metadata(handle, bmbh);
++      if (err)
++              goto error_out;
++
++      /* ... and correct group descriptor */
++      gdp->bg_free_blocks_count =
++              cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - as.len);
++      es->s_free_blocks_count =
++              cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) - as.len);
++      err = ext3_journal_dirty_metadata(handle, bmbh);
++      if (err)
++              goto error_out;
++      err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
++      if (err)
++              goto error_out;
++      sb->s_dirt = 1;
++
++      if (*num != as.len)
++              DQUOT_FREE_BLOCK(inode, *num - as.len);
++      *num = as.len;
++
++out:
++      unlock_super(sb);
++      return as.start;
++
++error_out:
++      as.start = 0;
++      *errp = err;
++      goto out;
++}
++
++EXPORT_SYMBOL(ext3_new_blocks);
++
+Index: linux-2.4.21-suse2/fs/ext3/file.c
+===================================================================
+--- linux-2.4.21-suse2.orig/fs/ext3/file.c     2004-02-05 20:42:39.000000000 +0300
++++ linux-2.4.21-suse2/fs/ext3/file.c  2004-02-05 20:56:55.000000000 +0300
+@@ -70,6 +70,18 @@
+       int ret, err;
+       struct inode *inode = file->f_dentry->d_inode;
++#if 0
++      /* allocate all the space to be written */
++      if (EXT3_I(inode)->i_flags & EXT3_EXTENTS_FL) {
++              int blocksize = inode->i_sb->s_blocksize;
++              unsigned long start, end;
++
++              start = (unsigned long) *ppos / blocksize;
++              end = ((unsigned long) *ppos + count + blocksize - 1)
++                              / blocksize;
++              ext3_ext_allocate_nblocks(inode, start, end - start);
++      }
++#endif
+       ret = generic_file_write(file, buf, count, ppos);
+       /* Skip file flushing code if there was an error, or if nothing
+Index: linux-2.4.21-suse2/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.21-suse2.orig/fs/ext3/Makefile   2004-02-05 20:43:47.000000000 +0300
++++ linux-2.4.21-suse2/fs/ext3/Makefile        2004-02-05 20:50:48.000000000 +0300
+@@ -14,7 +14,7 @@
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+               ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \
+               extents.o
+-export-objs += extents.o
++export-objs += extents.o balloc.o
+ obj-m    := $(O_TARGET)
+ export-objs += xattr.o
+Index: linux-2.4.21-suse2/include/linux/ext3_fs.h
+===================================================================
+--- linux-2.4.21-suse2.orig/include/linux/ext3_fs.h    2004-02-05 20:42:40.000000000 +0300
++++ linux-2.4.21-suse2/include/linux/ext3_fs.h 2004-02-05 20:50:48.000000000 +0300
+@@ -58,6 +58,8 @@
+ #define ext3_debug(f, a...)   do {} while (0)
+ #endif
++#define EXT3_MULTIBLOCK_ALLOCATOR     1
++
+ /*
+  * Special inodes numbers
+  */
+@@ -668,6 +670,7 @@
+ extern struct ext3_group_desc * ext3_get_group_desc(struct super_block * sb,
+                                                   unsigned int block_group,
+                                                   struct buffer_head ** bh);
++extern int ext3_new_blocks(handle_t*, struct inode*, int*, unsigned long, int*);
+ /* dir.c */
+ extern int ext3_check_dir_entry(const char *, struct inode *,
index a234f96..93da5aa 100644 (file)
@@ -1,8 +1,16 @@
 Index: linux-2.4.24/fs/ext3/balloc.c
 ===================================================================
 --- linux-2.4.24.orig/fs/ext3/balloc.c 2004-01-10 17:04:42.000000000 +0300
-+++ linux-2.4.24/fs/ext3/balloc.c      2004-01-29 17:27:54.000000000 +0300
-@@ -1007,3 +1007,294 @@
++++ linux-2.4.24/fs/ext3/balloc.c      2004-02-05 20:35:11.000000000 +0300
+@@ -11,6 +11,7 @@
+  *        David S. Miller (davem@caip.rutgers.edu), 1995
+  */
++#include <linux/module.h>
+ #include <linux/config.h>
+ #include <linux/sched.h>
+ #include <linux/fs.h>
+@@ -1007,3 +1008,298 @@
                        bitmap_count);
  }
  #endif
@@ -19,6 +27,7 @@ Index: linux-2.4.24/fs/ext3/balloc.c
 + * extents we've skipped, etc
 + */
 +struct alloc_status {
++      struct inode *inode;
 +      struct super_block *sb;
 +      int goal;               /* goal for allocation */
 +      int target_len;         /* goal for len */
@@ -199,6 +208,7 @@ Index: linux-2.4.24/fs/ext3/balloc.c
 +      *errp = 0;
 +      as.target_len = *num;
 +      as.sb = sb;
++      as.inode = inode;
 +      as.goal = goal;
 +      as.start = -1;
 +      as.len = 0;
@@ -297,10 +307,12 @@ Index: linux-2.4.24/fs/ext3/balloc.c
 +      goto out;
 +}
 +
++EXPORT_SYMBOL(ext3_new_blocks);
++
 Index: linux-2.4.24/fs/ext3/file.c
 ===================================================================
---- linux-2.4.24.orig/fs/ext3/file.c   2004-01-12 20:36:32.000000000 +0300
-+++ linux-2.4.24/fs/ext3/file.c        2004-01-29 18:26:23.000000000 +0300
+--- linux-2.4.24.orig/fs/ext3/file.c   2004-01-31 02:06:18.000000000 +0300
++++ linux-2.4.24/fs/ext3/file.c        2004-02-05 20:57:07.000000000 +0300
 @@ -69,6 +69,18 @@
        int err;
        struct inode *inode = file->f_dentry->d_inode;
@@ -320,10 +332,23 @@ Index: linux-2.4.24/fs/ext3/file.c
        ret = generic_file_write(file, buf, count, ppos);
  
        /* Skip file flushing code if there was an error, or if nothing
+Index: linux-2.4.24/fs/ext3/Makefile
+===================================================================
+--- linux-2.4.24.orig/fs/ext3/Makefile 2004-02-05 18:44:25.000000000 +0300
++++ linux-2.4.24/fs/ext3/Makefile      2004-02-05 20:35:11.000000000 +0300
+@@ -14,7 +14,7 @@
+ obj-y    := balloc.o bitmap.o dir.o file.o fsync.o ialloc.o inode.o iopen.o \
+               ioctl.o namei.o super.o symlink.o hash.o ext3-exports.o \
+               xattr_trusted.o extents.o
+-export-objs += extents.o
++export-objs += extents.o balloc.o
+ obj-m    := $(O_TARGET)
 Index: linux-2.4.24/include/linux/ext3_fs.h
 ===================================================================
---- linux-2.4.24.orig/include/linux/ext3_fs.h  2004-01-26 23:17:19.000000000 +0300
-+++ linux-2.4.24/include/linux/ext3_fs.h       2004-01-29 16:29:36.000000000 +0300
+--- linux-2.4.24.orig/include/linux/ext3_fs.h  2004-01-30 00:09:37.000000000 +0300
++++ linux-2.4.24/include/linux/ext3_fs.h       2004-02-05 20:35:11.000000000 +0300
 @@ -58,6 +58,8 @@
  #define ext3_debug(f, a...)   do {} while (0)
  #endif