--- linux-2.6.18.i386.orig/fs/ext4/ialloc.c
+++ linux-2.6.18.i386/fs/ext4/ialloc.c
@@ -622,12 +622,15 @@ struct inode *ext4_new_inode(handle_t *h
- return ERR_PTR(-EPERM);
-
sb = dir->i_sb;
+ trace_mark(ext4_request_inode, "dev %s dir %lu mode %d", sb->s_id,
+ dir->i_ino, mode);
+ sbi = EXT4_SB(sb);
+ if (sbi->s_max_dir_size > 0 && i_size_read(dir) >= sbi->s_max_dir_size)
+ return ERR_PTR(-EFBIG);
#include "ext4.h"
#include "ext4_jbd2.h"
-@@ -67,6 +68,8 @@ static void ext4_write_super_lockfs(stru
-
- struct page *ext4_zero_page;
-
-+struct proc_dir_entry *proc_root_ext4;
-+
- ext4_fsblk_t ext4_block_bitmap(struct super_block *sb,
- struct ext4_group_desc *bg)
- {
-@@ -551,6 +554,9 @@ static void ext4_put_super(struct super_
- }
- if (sbi->s_mmp_tsk)
- kthread_stop(sbi->s_mmp_tsk);
-+
-+ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
-+
- sb->s_fs_info = NULL;
- kfree(sbi);
- return;
-@@ -2185,6 +2191,46 @@ static unsigned long ext4_get_stripe_siz
+@@ -551,6 +554,7 @@ static void ext4_put_super(struct super_
+ ext4_commit_super(sb, es, 1);
+ }
+ if (sbi->s_proc) {
++ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_proc);
+ remove_proc_entry("inode_readahead_blks", sbi->s_proc);
+ remove_proc_entry(sb->s_id, ext4_proc_root);
+ }
+@@ -2185,6 +2191,48 @@ static unsigned long ext4_get_stripe_siz
return 0;
}
++#ifdef CONFIG_PROC_FS
+static int ext4_max_dir_size_read(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ sbi->s_max_dir_size = value;
+ return count;
+}
++#endif
+
static int ext4_fill_super(struct super_block *sb, void *data, int silent)
__releases(kernel_lock)
__acquires(kernel_lock)
-@@ -2208,6 +2254,7 @@ static int ext4_fill_super(struct super_
- int needs_recovery;
- __le32 features;
- __u64 blocks_count;
-+ struct proc_dir_entry *proc;
-
- sbi = kzalloc(sizeof(*sbi), GFP_KERNEL);
- if (!sbi)
-@@ -2743,6 +2790,22 @@ static int ext4_fill_super(struct super_
- ext4_ext_init(sb);
- ext4_mb_init(sb, needs_recovery);
-
-+ sbi->s_max_dir_size = EXT4_DEFAULT_MAX_DIR_SIZE;
-+ proc = create_proc_entry(EXT4_MAX_DIR_SIZE_NAME,
-+ S_IFREG | S_IRUGO | S_IWUSR, sbi->s_mb_proc);
-+ if (proc == NULL) {
-+ printk(KERN_ERR "EXT4-fs: unable to create %s\n",
-+ EXT4_MAX_DIR_SIZE_NAME);
-+ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
-+ remove_proc_entry(sbi->s_mb_proc->name, proc_root_ext4);
-+ sbi->s_mb_proc = NULL;
-+ ret = -ENOMEM;
-+ goto failed_mount4;
-+ }
-+ proc->data = sbi;
-+ proc->read_proc = ext4_max_dir_size_read;
-+ proc->write_proc = ext4_max_dir_size_write;
+@@ -2743,6 +2790,20 @@ static int ext4_fill_super(struct super_
+ p->proc_fops = &ext4_ui_proc_fops,
+ p->data = &sbi->s_inode_goal;
+ }
++ sbi->s_max_dir_size = EXT4_DEFAULT_MAX_DIR_SIZE;
++ p = create_proc_entry(EXT4_MAX_DIR_SIZE_NAME,
++ S_IFREG | S_IRUGO | S_IWUSR, sbi->s_proc);
++ if (p == NULL) {
++ printk(KERN_ERR "EXT4-fs: unable to create %s\n",
++ EXT4_MAX_DIR_SIZE_NAME);
++ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_proc);
++ ret = -ENOMEM;
++ goto failed_mount;
++ }
++ p->data = sbi;
++ p->read_proc = ext4_max_dir_size_read;
++ p->write_proc = ext4_max_dir_size_write;
+
- lock_kernel();
- return 0;
-
-@@ -3082,7 +3145,6 @@ static void ext4_commit_super(struct sup
- sync_dirty_buffer(sbh);
- }
+ }
+ #endif
--
- /*
- * Have we just finished recovery? If so, and if we are mounting (or
- * remounting) the filesystem readonly, then we will end up with a
Index: linux-2.6.18.i386/fs/ext4/ext4_sb.h
===================================================================
--- linux-2.6.18.i386.orig/fs/ext4/ext4_sb.h
===================================================================
--- linux-2.6.18.i386.orig/fs/ext4/ext4.h
+++ linux-2.6.18.i386/fs/ext4/ext4.h
-@@ -992,6 +992,14 @@ struct mmp_struct {
+@@ -992,6 +992,12 @@ struct mmp_struct {
*/
#define EXT4_MMP_MIN_CHECK_INTERVAL 5
-+extern struct proc_dir_entry *proc_root_ext4;
-+
+/*
+ * max directory size tunable
+ */
/*
* Function prototypes
*/
-Index: linux-2.6.18.i386/fs/ext4/mballoc.h
-===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/mballoc.h
-+++ linux-2.6.18.i386/fs/ext4/mballoc.h
-@@ -257,7 +257,6 @@ static void ext4_mb_store_history(struct
-
- #define in_range(b, first, len) ((b) >= (first) && (b) <= (first) + (len) - 1)
-
--static struct proc_dir_entry *proc_root_ext4;
- struct buffer_head *read_block_bitmap(struct super_block *, ext4_group_t);
-
- static void ext4_mb_generate_from_pa(struct super_block *sb, void *bitmap,
-Index: linux-2.6.18.i386/fs/ext4/mballoc.c
-===================================================================
---- linux-2.6.18.i386.orig/fs/ext4/mballoc.c
-+++ linux-2.6.18.i386/fs/ext4/mballoc.c
-@@ -2821,6 +2821,7 @@ err_out:
- remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
- remove_proc_entry(devname, proc_root_ext4);
- sbi->s_mb_proc = NULL;
-
-@@ -2842,7 +2843,9 @@ static int ext4_mb_destroy_per_dev_proc(
- remove_proc_entry(EXT4_MB_MIN_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_MAX_TO_SCAN_NAME, sbi->s_mb_proc);
- remove_proc_entry(EXT4_MB_STATS_NAME, sbi->s_mb_proc);
-+ remove_proc_entry(EXT4_MAX_DIR_SIZE_NAME, sbi->s_mb_proc);
- remove_proc_entry(devname, proc_root_ext4);
-+ sbi->s_mb_proc = NULL;
-
- return 0;
- }