Whamcloud - gitweb
- configurable stack size fo x86_64
[fs/lustre-release.git] / lustre / kernel_patches / patches / ext3-reserve-inode-space-2.4.24.patch
1 Index: linux-2.4.24/fs/ext3/ialloc.c
2 ===================================================================
3 --- linux-2.4.24.orig/fs/ext3/ialloc.c  2004-08-02 22:13:13.000000000 +0400
4 +++ linux-2.4.24/fs/ext3/ialloc.c       2004-08-04 01:10:30.000000000 +0400
5 @@ -41,6 +41,24 @@
6   * when a file system is mounted (see ext3_read_super).
7   */
8  
9 +/*
10 + * this is very simple policy: files with O_INRESERVE goes to last group;
11 + * files with no O_INRESERVE goes to all groups, but last. probably we'll
12 + * specify group for O_INRESERVE files later -bzzz */
13 +static inline int ext3_group_allowed(struct super_block *sb, int mode, int group)
14 +{
15 +       if (!test_opt(sb, INRESERVE) || EXT3_SB(sb)->s_groups_count == 1)
16 +               return 1;
17 +
18 +       if (mode & EXT3_S_INRESERVE) {
19 +               if (group != EXT3_SB(sb)->s_groups_count - 1)
20 +                       return 0;
21 +       } else {
22 +               if (group == EXT3_SB(sb)->s_groups_count -1 )
23 +                       return 0;
24 +       }
25 +       return 1;
26 +}
27  
28  /*
29   * Read the inode allocation bitmap for a given block_group, reading
30 @@ -337,20 +355,33 @@
31         return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data);
32  }
33  
34 -int ext3_find_group_dir(const struct inode *dir,
35 +int ext3_find_group_dir(const struct inode *dir, int mode,
36                                 struct ext3_group_desc **gdp,
37                                 struct buffer_head **bh)
38  {
39         struct super_block *sb = dir->i_sb;
40         struct ext3_super_block *es;
41         struct ext3_group_desc *tmp;
42 -       int i = 0, j, avefreei;
43 +       int i = 0, j, ifree, avefreei;
44  
45         es = EXT3_SB(sb)->s_es;
46 -       avefreei = le32_to_cpu(es->s_free_inodes_count) /
47 -                       sb->u.ext3_sb.s_groups_count;
48 +       ifree = le32_to_cpu(es->s_free_inodes_count);
49 +       j = sb->u.ext3_sb.s_groups_count; 
50 +       if (test_opt(sb, INRESERVE) && EXT3_SB(sb)->s_groups_count > 1) {
51 +               tmp = ext3_get_group_desc(sb, EXT3_SB(sb)->s_groups_count-1, NULL);
52 +               if (mode & EXT3_S_INRESERVE) {
53 +                       ifree = le16_to_cpu(tmp->bg_free_blocks_count);
54 +                       j = 1;
55 +               } else {
56 +                       ifree -= le16_to_cpu(tmp->bg_free_blocks_count);
57 +                       j--;
58 +               }
59 +       }
60 +       avefreei = ifree / j;
61         for (j = 0; j < sb->u.ext3_sb.s_groups_count; j++) {
62                 struct buffer_head *temp_buffer;
63 +               if (!ext3_group_allowed(sb, mode, j))
64 +                       continue;
65                 tmp = ext3_get_group_desc(sb, j, &temp_buffer);
66                 if (tmp && le16_to_cpu(tmp->bg_free_inodes_count) &&
67                         le16_to_cpu(tmp->bg_free_inodes_count) >= avefreei) {
68 @@ -366,7 +397,7 @@
69         return i;
70  }
71  
72 -int ext3_find_group_other(const struct inode *dir,
73 +int ext3_find_group_other(const struct inode *dir, int mode,
74                                 struct ext3_group_desc **gdp,
75                                 struct buffer_head **bh)
76  {
77 @@ -379,7 +410,8 @@
78          */
79         i = dir->u.ext3_i.i_block_group;
80         tmp = ext3_get_group_desc(sb, i, bh);
81 -       if (tmp && le16_to_cpu(tmp->bg_free_inodes_count))
82 +       if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)
83 +                       && ext3_group_allowed(sb, mode, i))
84                 *gdp = tmp;
85         else {
86                 /*
87 @@ -390,6 +422,8 @@
88                         i += j;
89                         if (i >= sb->u.ext3_sb.s_groups_count)
90                                 i -= sb->u.ext3_sb.s_groups_count;
91 +                       if (!ext3_group_allowed(sb, mode, i))
92 +                               continue;
93                         tmp = ext3_get_group_desc (sb, i, bh);
94                         if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) {
95                                 *gdp = tmp;
96 @@ -405,6 +439,8 @@
97                 for (j = 2; j < sb->u.ext3_sb.s_groups_count; j++) {
98                         if (++i >= sb->u.ext3_sb.s_groups_count)
99                                 i = 0;
100 +                       if (!ext3_group_allowed(sb, mode, i))
101 +                               continue;
102                         tmp = ext3_get_group_desc (sb, i, bh);
103                         if (tmp && le16_to_cpu(tmp->bg_free_inodes_count)) {
104                                 *gdp = tmp;
105 @@ -421,8 +457,8 @@
106                                 struct buffer_head **bh)
107  {
108         if (S_ISDIR(mode))
109 -               return ext3_find_group_dir(dir, gdp, bh);
110 -       return ext3_find_group_other(dir, gdp, bh);
111 +               return ext3_find_group_dir(dir, mode, gdp, bh);
112 +       return ext3_find_group_other(dir, mode, gdp, bh);
113  }
114  
115  static int ext3_find_usable_inode(struct super_block *sb,
116 @@ -549,6 +585,8 @@
117         for (i = i + 1; i != k; i++) {
118                 if (i >= sb->u.ext3_sb.s_groups_count)
119                         i = 0;
120 +               if (!ext3_group_allowed(sb, mode, i))
121 +                       continue;
122                 tmp = ext3_get_group_desc(sb, i, &bh2);
123                 if (le16_to_cpu(tmp->bg_free_inodes_count) == 0)
124                         continue;
125 @@ -588,6 +626,7 @@
126         if (buffer_jbd(bh) && bh2jh(bh)->b_committed_data)
127                 J_ASSERT_BH(bh, !ext3_test_bit(j, bh2jh(bh)->b_committed_data));
128  
129 +       J_ASSERT(ext3_group_allowed(sb, mode, i));
130         j += i * EXT3_INODES_PER_GROUP(sb) + 1;
131         if (j < EXT3_FIRST_INO(sb) || j > le32_to_cpu(es->s_inodes_count)) {
132                 ext3_error (sb, "ext3_new_inode",
133 @@ -628,7 +667,7 @@
134                         mode |= S_ISGID;
135         } else
136                 inode->i_gid = current->fsgid;
137 -       inode->i_mode = mode;
138 +       inode->i_mode = mode & ~EXT3_S_INRESERVE;
139  
140         inode->i_ino = j;
141         /* This is the optimal IO size (for stat), not the fs block size */
142 Index: linux-2.4.24/fs/ext3/super.c
143 ===================================================================
144 --- linux-2.4.24.orig/fs/ext3/super.c   2004-08-02 22:13:12.000000000 +0400
145 +++ linux-2.4.24/fs/ext3/super.c        2004-08-04 00:10:07.000000000 +0400
146 @@ -723,6 +723,10 @@
147                                 return 0;
148                         *resgid = v;
149                 }
150 +               else if (!strcmp (this_char, "inrsv")) {
151 +                       set_opt (*mount_options, INRESERVE);
152 +                       J_ASSERT((EXT3_S_INRESERVE & S_IALLUGO) == 0);
153 +               }
154                 else if (!strcmp (this_char, "resuid")) {
155                         unsigned long v;
156                         if (want_numeric(value, "resuid", &v))
157 Index: linux-2.4.24/fs/ext3/namei.c
158 ===================================================================
159 --- linux-2.4.24.orig/fs/ext3/namei.c   2004-08-02 22:13:13.000000000 +0400
160 +++ linux-2.4.24/fs/ext3/namei.c        2004-08-03 03:21:09.000000000 +0400
161 @@ -1971,6 +1971,36 @@
162         return err;
163  }
164  
165 +static int ext3_create_it (struct inode * dir, struct dentry * dentry, int mode,
166 +                               struct lookup_intent *it)
167 +{
168 +       handle_t *handle; 
169 +       struct inode * inode;
170 +       int err;
171 +
172 +       handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
173 +                                       EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
174 +       if (IS_ERR(handle)) {
175 +               return PTR_ERR(handle);
176 +       }
177 +
178 +       if (IS_SYNC(dir))
179 +               handle->h_sync = 1;
180 +
181 +       if (it && it->it_flags & O_INRESERVE)
182 +               mode |= EXT3_S_INRESERVE;
183 +       inode = ext3_new_inode_wantedi (handle, dir, mode, dentry);
184 +       err = PTR_ERR(inode);
185 +       if (!IS_ERR(inode)) {
186 +               inode->i_op = &ext3_file_inode_operations;
187 +               inode->i_fop = &ext3_file_operations;
188 +               inode->i_mapping->a_ops = &ext3_aops;
189 +               err = ext3_add_nondir(handle, dentry, inode);
190 +       }
191 +       ext3_journal_stop(handle, dir);
192 +       return err;
193 +}
194 +
195  static int ext3_mknod (struct inode * dir, struct dentry *dentry,
196                         int mode, int rdev)
197  {
198 @@ -2803,6 +2833,7 @@
199   */
200  struct inode_operations ext3_dir_inode_operations = {
201         create:         ext3_create,            /* BKL held */
202 +       create_it:      ext3_create_it,         /* BKL held */
203         lookup:         ext3_lookup,            /* BKL held */
204         lookup_raw:     ext3_lookup_raw,        /* BKL held */
205         link:           ext3_link,              /* BKL held */
206 Index: linux-2.4.24/include/asm-i386/fcntl.h
207 ===================================================================
208 --- linux-2.4.24.orig/include/asm-i386/fcntl.h  2001-09-18 00:16:30.000000000 +0400
209 +++ linux-2.4.24/include/asm-i386/fcntl.h       2004-08-03 01:20:55.000000000 +0400
210 @@ -20,6 +20,7 @@
211  #define O_LARGEFILE    0100000
212  #define O_DIRECTORY    0200000 /* must be a directory */
213  #define O_NOFOLLOW     0400000 /* don't follow links */
214 +#define O_INRESERVE    01000000 /* allocate inodes in reserved space */
215  
216  #define F_DUPFD                0       /* dup */
217  #define F_GETFD                1       /* get close_on_exec */
218 Index: linux-2.4.24/include/linux/ext3_fs.h
219 ===================================================================
220 --- linux-2.4.24.orig/include/linux/ext3_fs.h   2004-08-02 22:13:12.000000000 +0400
221 +++ linux-2.4.24/include/linux/ext3_fs.h        2004-08-03 01:03:39.000000000 +0400
222 @@ -343,6 +343,7 @@
223  #define EXT3_MOUNT_ASYNCDEL            0x20000 /* Delayed deletion */
224  #define EXT3_MOUNT_EXTENTS             0x100000/* Extents support */
225  #define EXT3_MOUNT_EXTDEBUG            0x200000/* Extents debug */
226 +#define EXT3_MOUNT_INRESERVE           0x400000/* reserve one group for O_INRESERVE */
227  
228  /* Compatibility, for having both ext2_fs.h and ext3_fs.h included at once */
229  #ifndef _LINUX_EXT2_FS_H
230 @@ -482,6 +483,8 @@
231  
232  #define EXT3_GOOD_OLD_INODE_SIZE 128
233  
234 +#define EXT3_S_INRESERVE       01000000
235 +
236  /*
237   * Feature set definitions
238   */