Whamcloud - gitweb
b=17569
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-max-dir-size-2.6.5-suse.patch
1 Index: linux-2.6.5-7.314/fs/ext3/ialloc.c
2 ===================================================================
3 --- linux-2.6.5-7.314.orig/fs/ext3/ialloc.c
4 +++ linux-2.6.5-7.314/fs/ext3/ialloc.c
5 @@ -520,12 +520,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.5-7.314/fs/ext3/super.c
23 ===================================================================
24 --- linux-2.6.5-7.314.orig/fs/ext3/super.c
25 +++ linux-2.6.5-7.314/fs/ext3/super.c
26 @@ -37,6 +37,12 @@
27  #include "acl.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 @@ -431,6 +437,7 @@ void ext3_put_super (struct super_block 
40                 invalidate_bdev(sbi->journal_bdev, 0);
41                 ext3_blkdev_remove(sbi);
42         }
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 @@ -1253,6 +1260,45 @@ static unsigned long descriptor_loc(stru
48         return (first_data_block + has_super + (bg * sbi->s_blocks_per_group));
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 @@ -1273,6 +1319,7 @@ static int ext3_fill_super (struct super
94         int db_count;
95         int i;
96         int needs_recovery;
97 +       struct proc_dir_entry *proc;
98  
99         sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
100         if (!sbi)
101 @@ -1299,6 +1346,23 @@ static int ext3_fill_super (struct super
102                                     sb->s_id);
103         }
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 @@ -1713,6 +1777,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.5-7.314/include/linux/ext3_fs_sb.h
134 ===================================================================
135 --- linux-2.6.5-7.314.orig/include/linux/ext3_fs_sb.h
136 +++ linux-2.6.5-7.314/include/linux/ext3_fs_sb.h
137 @@ -119,6 +119,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;