Skip to content
Snippets Groups Projects
Commit 11347915 authored by alex's avatar alex
Browse files

- ext3 batching allocation against suse2 series

- ext3-mballoc* patches export ext3_new_blocks()
parent 053d78f9
No related branches found
No related tags found
No related merge requests found
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: linux-2.4.24/fs/ext3/balloc.c 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.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 +++ linux-2.4.24/fs/ext3/balloc.c 2004-02-05 20:35:11.000000000 +0300
@@ -1007,3 +1007,294 @@ @@ -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); bitmap_count);
} }
#endif #endif
...@@ -19,6 +27,7 @@ Index: linux-2.4.24/fs/ext3/balloc.c ...@@ -19,6 +27,7 @@ Index: linux-2.4.24/fs/ext3/balloc.c
+ * extents we've skipped, etc + * extents we've skipped, etc
+ */ + */
+struct alloc_status { +struct alloc_status {
+ struct inode *inode;
+ struct super_block *sb; + struct super_block *sb;
+ int goal; /* goal for allocation */ + int goal; /* goal for allocation */
+ int target_len; /* goal for len */ + int target_len; /* goal for len */
...@@ -199,6 +208,7 @@ Index: linux-2.4.24/fs/ext3/balloc.c ...@@ -199,6 +208,7 @@ Index: linux-2.4.24/fs/ext3/balloc.c
+ *errp = 0; + *errp = 0;
+ as.target_len = *num; + as.target_len = *num;
+ as.sb = sb; + as.sb = sb;
+ as.inode = inode;
+ as.goal = goal; + as.goal = goal;
+ as.start = -1; + as.start = -1;
+ as.len = 0; + as.len = 0;
...@@ -297,10 +307,12 @@ Index: linux-2.4.24/fs/ext3/balloc.c ...@@ -297,10 +307,12 @@ Index: linux-2.4.24/fs/ext3/balloc.c
+ goto out; + goto out;
+} +}
+ +
+EXPORT_SYMBOL(ext3_new_blocks);
+
Index: linux-2.4.24/fs/ext3/file.c 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.orig/fs/ext3/file.c 2004-01-31 02:06:18.000000000 +0300
+++ linux-2.4.24/fs/ext3/file.c 2004-01-29 18:26:23.000000000 +0300 +++ linux-2.4.24/fs/ext3/file.c 2004-02-05 20:57:07.000000000 +0300
@@ -69,6 +69,18 @@ @@ -69,6 +69,18 @@
int err; int err;
struct inode *inode = file->f_dentry->d_inode; struct inode *inode = file->f_dentry->d_inode;
...@@ -320,10 +332,23 @@ Index: linux-2.4.24/fs/ext3/file.c ...@@ -320,10 +332,23 @@ Index: linux-2.4.24/fs/ext3/file.c
ret = generic_file_write(file, buf, count, ppos); ret = generic_file_write(file, buf, count, ppos);
/* Skip file flushing code if there was an error, or if nothing /* 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 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.orig/include/linux/ext3_fs.h 2004-01-30 00:09:37.000000000 +0300
+++ linux-2.4.24/include/linux/ext3_fs.h 2004-01-29 16:29:36.000000000 +0300 +++ linux-2.4.24/include/linux/ext3_fs.h 2004-02-05 20:35:11.000000000 +0300
@@ -58,6 +58,8 @@ @@ -58,6 +58,8 @@
#define ext3_debug(f, a...) do {} while (0) #define ext3_debug(f, a...) do {} while (0)
#endif #endif
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment