Index: linux-2.6.9-full/include/linux/ext3_fs.h
===================================================================
--- linux-2.6.9-full.orig/include/linux/ext3_fs.h 2007-06-08 23:44:08.000000000 +0400
-+++ linux-2.6.9-full/include/linux/ext3_fs.h 2007-06-29 11:31:13.000000000 +0400
++++ linux-2.6.9-full/include/linux/ext3_fs.h 2007-07-19 09:39:07.000000000 +0400
@@ -57,6 +57,30 @@ struct statfs;
#define ext3_debug(f, a...) do {} while (0)
#endif
Index: linux-2.6.9-full/include/linux/ext3_fs_sb.h
===================================================================
--- linux-2.6.9-full.orig/include/linux/ext3_fs_sb.h 2007-06-08 23:44:07.000000000 +0400
-+++ linux-2.6.9-full/include/linux/ext3_fs_sb.h 2007-06-29 11:31:13.000000000 +0400
++++ linux-2.6.9-full/include/linux/ext3_fs_sb.h 2007-07-19 09:39:07.000000000 +0400
@@ -81,6 +81,61 @@ struct ext3_sb_info {
char *s_qf_names[MAXQUOTAS]; /* Names of quota files with journalled quota */
int s_jquota_fmt; /* Format of quota to use */
Index: linux-2.6.9-full/fs/ext3/super.c
===================================================================
--- linux-2.6.9-full.orig/fs/ext3/super.c 2007-06-08 23:44:08.000000000 +0400
-+++ linux-2.6.9-full/fs/ext3/super.c 2007-06-29 11:31:13.000000000 +0400
++++ linux-2.6.9-full/fs/ext3/super.c 2007-07-19 09:39:07.000000000 +0400
@@ -394,6 +394,7 @@ void ext3_put_super (struct super_block
struct ext3_super_block *es = sbi->s_es;
int i;
int ext3_prep_san_write(struct inode *inode, long *blocks,
Index: linux-2.6.9-full/fs/ext3/mballoc.c
===================================================================
---- linux-2.6.9-full.orig/fs/ext3/mballoc.c 2007-06-17 11:25:39.317298699 +0400
-+++ linux-2.6.9-full/fs/ext3/mballoc.c 2007-06-29 12:06:50.000000000 +0400
-@@ -0,0 +1,4371 @@
+--- linux-2.6.9-full.orig/fs/ext3/mballoc.c 2007-07-14 04:24:39.138985848 +0400
++++ linux-2.6.9-full/fs/ext3/mballoc.c 2007-07-20 11:31:03.000000000 +0400
+@@ -0,0 +1,4391 @@
+/*
+ * Copyright (c) 2003-2006, Cluster File Systems, Inc, info@clusterfs.com
+ * Written by Alex Tomas <alex@clusterfs.com>
+ unsigned long pa_end;
+
+ pa = list_entry(cur, struct ext3_prealloc_space, pa_inode_list);
++
++ if (pa->pa_deleted)
++ continue;
++ spin_lock(&pa->pa_lock);
++ if (pa->pa_deleted) {
++ spin_unlock(&pa->pa_lock);
++ continue;
++ }
++
+ pa_end = pa->pa_lstart + pa->pa_len;
+
+ /* PA must not overlap original request */
+ ac->ac_o_ex.fe_logical < pa->pa_lstart));
+
+ /* skip PA normalized request doesn't overlap with */
-+ if (pa->pa_lstart >= end)
++ if (pa->pa_lstart >= end) {
++ spin_unlock(&pa->pa_lock);
+ continue;
-+ if (pa_end <= start)
++ }
++ if (pa_end <= start) {
++ spin_unlock(&pa->pa_lock);
+ continue;
++ }
+ BUG_ON(pa->pa_lstart <= start && pa_end >= end);
+
+ if (pa_end <= ac->ac_o_ex.fe_logical) {
+ BUG_ON(pa->pa_lstart > end);
+ end = pa->pa_lstart;
+ }
++ spin_unlock(&pa->pa_lock);
+ }
+ rcu_read_unlock();
+ size = end - start;
+ struct ext3_prealloc_space *pa;
+ unsigned long pa_end;
+ pa = list_entry(cur, struct ext3_prealloc_space, pa_inode_list);
-+ pa_end = pa->pa_lstart + pa->pa_len;
-+ BUG_ON(!(start >= pa_end || end <= pa->pa_lstart));
++ spin_lock(&pa->pa_lock);
++ if (pa->pa_deleted == 0) {
++ pa_end = pa->pa_lstart + pa->pa_len;
++ BUG_ON(!(start >= pa_end || end <= pa->pa_lstart));
++ }
++ spin_unlock(&pa->pa_lock);
+ }
+ rcu_read_unlock();
+
+ }
+
+ /* if we still need more blocks and some PAs were used, try again */
-+ if (free < needed && busy)
++ if (free < needed && busy) {
++ ext3_unlock_group(sb, group);
+ goto repeat;
++ }
+
+ /* found anything to free? */
+ if (list_empty(&list)) {