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