Whamcloud - gitweb
b=19872
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-max-dir-size.patch
1 Index: linux-2.6.18-92.1.17/fs/ext3/ialloc.c
2 ===================================================================
3 --- linux-2.6.18-92.1.17.orig/fs/ext3/ialloc.c
4 +++ linux-2.6.18-92.1.17/fs/ext3/ialloc.c
5 @@ -521,12 +521,15 @@ struct inode *ext3_new_inode(handle_t *h
6                 return ERR_PTR(-EPERM);
7  
8         sb = dir->i_sb;
9 +       sbi = EXT3_SB(sb);
10 +       if (sbi->s_max_dir_size > 0 && i_size_read(dir) >= sbi->s_max_dir_size)
11 +               return ERR_PTR(-EFBIG);
12 +
13         inode = new_inode(sb);
14         if (!inode)
15                 return ERR_PTR(-ENOMEM);
16         ei = EXT3_I(inode);
17  
18 -       sbi = EXT3_SB(sb);
19         es = sbi->s_es;
20         if (goal) {
21                 group = (goal - 1) / EXT3_INODES_PER_GROUP(sb);
22 Index: linux-2.6.18-92.1.17/fs/ext3/super.c
23 ===================================================================
24 --- linux-2.6.18-92.1.17.orig/fs/ext3/super.c
25 +++ linux-2.6.18-92.1.17/fs/ext3/super.c
26 @@ -45,6 +45,12 @@
27  #include "namei.h"
28  #include "group.h"
29  
30 +/*
31 + * max directory size tunable
32 + */
33 +#define EXT3_DEFAULT_MAX_DIR_SIZE              0
34 +#define EXT3_MAX_DIR_SIZE_NAME         "max_dir_size"
35 +
36  static int ext3_load_journal(struct super_block *, struct ext3_super_block *,
37                              unsigned long journal_devnum);
38  static int ext3_create_journal(struct super_block *, struct ext3_super_block *,
39 @@ -439,6 +445,7 @@ static void ext3_put_super (struct super
40         }
41         if (sbi->s_mmp_tsk)
42                 kthread_stop(sbi->s_mmp_tsk);
43 +       remove_proc_entry(EXT3_MAX_DIR_SIZE_NAME, sbi->s_dev_proc);
44         if (sbi->s_dev_proc) {
45                 remove_proc_entry(sbi->s_dev_proc->name, proc_root_ext3);
46                 sbi->s_dev_proc = NULL;
47 @@ -1854,6 +1861,45 @@ failed:
48         return 1;
49  }
50  
51 +static int ext3_max_dir_size_read(char *page, char **start, off_t off,
52 +                                  int count, int *eof, void *data)
53 +{
54 +       struct ext3_sb_info *sbi = data;
55 +       int len;
56 +
57 +       *eof = 1;
58 +       if (off != 0)
59 +               return 0;
60 +
61 +       len = sprintf(page, "%lu\n", sbi->s_max_dir_size);
62 +       *start = page;
63 +       return len;
64 +}
65 +
66 +static int ext3_max_dir_size_write(struct file *file, const char *buffer,
67 +                                   unsigned long count, void *data)
68 +{
69 +       struct ext3_sb_info *sbi = data;
70 +       char str[32];
71 +       unsigned long value;
72 +       char *end;
73 +
74 +       if (count >= sizeof(str)) {
75 +               printk(KERN_ERR "EXT3-fs: %s string too long, max %u bytes\n",
76 +                      EXT3_MAX_DIR_SIZE_NAME, (int)sizeof(str));
77 +               return -EOVERFLOW;
78 +       }
79 +
80 +       if (copy_from_user(str, buffer, count))
81 +               return -EFAULT;
82 +
83 +       value = simple_strtol(str, &end, 0);
84 +       if (value < 0)
85 +               return -ERANGE;
86 +
87 +       sbi->s_max_dir_size = value;
88 +       return count;
89 +}
90  
91  static int ext3_fill_super (struct super_block *sb, void *data, int silent)
92  {
93 @@ -1875,6 +1921,7 @@ static int ext3_fill_super (struct super
94         int i;
95         int needs_recovery;
96         __le32 features;
97 +       struct proc_dir_entry *proc;
98  
99         sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
100         if (!sbi)
101 @@ -1903,6 +1950,23 @@ static int ext3_fill_super (struct super
102  
103         unlock_kernel();
104  
105 +       sbi->s_max_dir_size = EXT3_DEFAULT_MAX_DIR_SIZE;
106 +       proc = create_proc_entry(EXT3_MAX_DIR_SIZE_NAME,
107 +                                S_IFREG | S_IRUGO | S_IWUSR, sbi->s_dev_proc);
108 +       if (proc == NULL) {
109 +               printk(KERN_ERR "EXT3-fs: unable to create %s\n", 
110 +                      EXT3_MAX_DIR_SIZE_NAME);
111 +               remove_proc_entry(EXT3_MAX_DIR_SIZE_NAME, sbi->s_dev_proc);
112 +               remove_proc_entry(sb->s_id, proc_root_ext3);
113 +               sbi->s_dev_proc = NULL;
114 +               sb->s_fs_info = NULL;
115 +               kfree(sbi);
116 +               return -ENOMEM;
117 +       }
118 +       proc->data = sbi;
119 +       proc->read_proc = ext3_max_dir_size_read;
120 +       proc->write_proc = ext3_max_dir_size_write;
121 +
122         blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
123         if (!blocksize) {
124                 printk(KERN_ERR "EXT3-fs: unable to set blocksize\n");
125 @@ -2338,6 +2402,7 @@ failed_mount:
126         ext3_blkdev_remove(sbi);
127         brelse(bh);
128  out_fail:
129 +       remove_proc_entry(EXT3_MAX_DIR_SIZE_NAME, sbi->s_dev_proc);
130         if (sbi->s_dev_proc) {
131                 remove_proc_entry(sbi->s_dev_proc->name, proc_root_ext3);
132                 sbi->s_dev_proc = NULL;
133 Index: linux-2.6.18-92.1.17/include/linux/ext3_fs_sb.h
134 ===================================================================
135 --- linux-2.6.18-92.1.17.orig/include/linux/ext3_fs_sb.h
136 +++ linux-2.6.18-92.1.17/include/linux/ext3_fs_sb.h
137 @@ -132,6 +132,8 @@ struct ext3_sb_info {
138         unsigned long s_mb_last_group;
139         unsigned long s_mb_last_start;
140  
141 +       unsigned long s_max_dir_size;
142 +
143         /* history to debug policy */
144         struct ext3_mb_history *s_mb_history;
145         int s_mb_history_cur;