Whamcloud - gitweb
b=20581 MDS returns full hash for readdir to decrease hash collision
[fs/lustre-release.git] / ldiskfs / kernel_patches / patches / ext3-max-dir-size.patch
1 Index: linux-stage/fs/ext3/ialloc.c
2 ===================================================================
3 --- linux-stage.orig/fs/ext3/ialloc.c
4 +++ linux-stage/fs/ext3/ialloc.c
5 @@ -521,12 +521,15 @@ struct inode *ext3_new_inode(handle_t
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-stage/fs/ext3/super.c
23 ===================================================================
24 --- linux-stage.orig/fs/ext3/super.c
25 +++ linux-stage/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 @@ -444,6 +450,7 @@ static void ext3_put_super (struct su
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 @@ -703,7 +710,7 @@ enum {
48         Opt_iopen, Opt_noiopen, Opt_iopen_nopriv,
49         Opt_grpquota,
50         Opt_extents, Opt_noextents, Opt_extdebug,
51 -       Opt_mballoc, Opt_nomballoc, Opt_stripe,
52 +       Opt_mballoc, Opt_nomballoc, Opt_stripe, Opt_maxdirsize
53  };
54  
55  static match_table_t tokens = {
56 @@ -762,8 +769,9 @@ static match_table_t tokens = {
57         {Opt_mballoc, "mballoc"},
58         {Opt_nomballoc, "nomballoc"},
59         {Opt_stripe, "stripe=%u"},
60 -       {Opt_err, NULL},
61         {Opt_resize, "resize"},
62 +       {Opt_maxdirsize, "maxdirsize=%u"},
63 +       {Opt_err, NULL}
64  };
65  
66  static ext3_fsblk_t get_sb_block(void **data)
67 @@ -1128,6 +1136,13 @@ clear_qf_name:
68                                 return 0;
69                         sbi->s_stripe = option;
70                         break;
71 +               case Opt_maxdirsize:
72 +                       if (match_int(&args[0], &option))
73 +                               return 0;
74 +                       if (option <= 0)
75 +                               return 0;
76 +                       sbi->s_max_dir_size = option;
77 +                       break;
78                 default:
79                         printk (KERN_ERR
80                                 "EXT3-fs: Unrecognized mount option \"%s\" "
81 @@ -1875,6 +1890,45 @@ failed:
82         return 1;
83  }
84  
85 +static int ext3_max_dir_size_read(char *page, char **start, off_t off,
86 +                                  int count, int *eof, void *data)
87 +{
88 +       struct ext3_sb_info *sbi = data;
89 +       int len;
90 +
91 +       *eof = 1;
92 +       if (off != 0)
93 +               return 0;
94 +
95 +       len = sprintf(page, "%lu\n", sbi->s_max_dir_size);
96 +       *start = page;
97 +       return len;
98 +}
99 +
100 +static int ext3_max_dir_size_write(struct file *file, const char *buffer,
101 +                                   unsigned long count, void *data)
102 +{
103 +       struct ext3_sb_info *sbi = data;
104 +       char str[32];
105 +       unsigned long value;
106 +       char *end;
107 +
108 +       if (count >= sizeof(str)) {
109 +               printk(KERN_ERR "EXT3-fs: %s string too long, max %u bytes\n",
110 +                      EXT3_MAX_DIR_SIZE_NAME, (int)sizeof(str));
111 +               return -EOVERFLOW;
112 +       }
113 +
114 +       if (copy_from_user(str, buffer, count))
115 +               return -EFAULT;
116 +
117 +       value = simple_strtol(str, &end, 0);
118 +       if (value < 0)
119 +               return -ERANGE;
120 +
121 +       sbi->s_max_dir_size = value;
122 +       return count;
123 +}
124  
125  static int ext3_fill_super (struct super_block *sb, void *data, int silent)
126  {
127 @@ -1896,6 +1950,7 @@ static int ext3_fill_super (struct su
128         int i;
129         int needs_recovery;
130         __le32 features;
131 +       struct proc_dir_entry *proc;
132  
133         sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
134         if (!sbi)
135 @@ -1924,6 +1979,23 @@ static int ext3_fill_super (struct su
136  
137         unlock_kernel();
138  
139 +       sbi->s_max_dir_size = EXT3_DEFAULT_MAX_DIR_SIZE;
140 +       proc = create_proc_entry(EXT3_MAX_DIR_SIZE_NAME,
141 +                                S_IFREG | S_IRUGO | S_IWUSR, sbi->s_dev_proc);
142 +       if (proc == NULL) {
143 +               printk(KERN_ERR "EXT3-fs: unable to create %s\n",
144 +                      EXT3_MAX_DIR_SIZE_NAME);
145 +               remove_proc_entry(EXT3_MAX_DIR_SIZE_NAME, sbi->s_dev_proc);
146 +               remove_proc_entry(sb->s_id, proc_root_ext3);
147 +               sbi->s_dev_proc = NULL;
148 +               sb->s_fs_info = NULL;
149 +               kfree(sbi);
150 +               return -ENOMEM;
151 +       }
152 +       proc->data = sbi;
153 +       proc->read_proc = ext3_max_dir_size_read;
154 +       proc->write_proc = ext3_max_dir_size_write;
155 +
156         blocksize = sb_min_blocksize(sb, EXT3_MIN_BLOCK_SIZE);
157         if (!blocksize) {
158                 printk(KERN_ERR "EXT3-fs: unable to set blocksize\n");
159 @@ -2361,6 +2433,7 @@ failed_mount:
160         ext3_blkdev_remove(sbi);
161         brelse(bh);
162  out_fail:
163 +       remove_proc_entry(EXT3_MAX_DIR_SIZE_NAME, sbi->s_dev_proc);
164         if (sbi->s_dev_proc) {
165                 remove_proc_entry(sbi->s_dev_proc->name, proc_root_ext3);
166                 sbi->s_dev_proc = NULL;
167 Index: linux-stage/include/linux/ext3_fs_sb.h
168 ===================================================================
169 --- linux-stage.orig/include/linux/ext3_fs_sb.h
170 +++ linux-stage/include/linux/ext3_fs_sb.h
171 @@ -132,6 +132,8 @@ struct ext3_sb_info {
172         unsigned long s_mb_last_group;
173         unsigned long s_mb_last_start;
174  
175 +       unsigned long s_max_dir_size;
176 +
177         /* history to debug policy */
178         struct ext3_mb_history *s_mb_history;
179         int s_mb_history_cur;