This source file includes following definitions.
- ext_put_inode
- ext_put_super
- ext_read_super
- ext_write_super
- ext_statfs
- _ext_bmap
- ext_bmap
- ext_create_block
- ext_read_inode
- ext_write_inode
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/sched.h>
14 #include <linux/ext_fs.h>
15 #include <linux/kernel.h>
16 #include <linux/mm.h>
17 #include <linux/string.h>
18 #include <linux/stat.h>
19
20 #include <asm/system.h>
21 #include <asm/segment.h>
22
23 int sync_dev(int dev);
24
25 void ext_put_inode(struct inode *inode)
26 {
27 inode->i_size = 0;
28 ext_truncate(inode);
29 ext_free_inode(inode);
30 }
31
32 void ext_put_super(struct super_block *sb)
33 {
34 #ifdef EXTFS_BITMAP
35 int i;
36 #endif
37
38 lock_super(sb);
39 sb->s_dev = 0;
40 #ifdef EXTFS_BITMAP
41 for(i = 0 ; i < EXT_I_MAP_SLOTS ; i++)
42 brelse(sb->u.ext_sb.s_imap[i]);
43 for(i = 0 ; i < EXT_Z_MAP_SLOTS ; i++)
44 brelse(sb->u.ext_sb.s_zmap[i]);
45 #endif
46 #ifdef EXTFS_FREELIST
47 if (sb->u.ext_sb.s_imap[1])
48 brelse (sb->u.ext_sb.s_imap[1]);
49 if (sb->u.ext_sb.s_zmap[1])
50 brelse (sb->u.ext_sb.s_zmap[1]);
51 #endif
52 free_super(sb);
53 return;
54 }
55
56 static struct super_operations ext_sops = {
57 ext_read_inode,
58 ext_write_inode,
59 ext_put_inode,
60 ext_put_super,
61 ext_write_super,
62 ext_statfs
63 };
64
65 struct super_block *ext_read_super(struct super_block *s,void *data)
66 {
67 struct buffer_head *bh;
68 struct ext_super_block *es;
69 int dev = s->s_dev,block;
70 #ifdef EXTFS_BITMAP
71 int i;
72 #endif
73
74 lock_super(s);
75 if (!(bh = bread(dev, 1, BLOCK_SIZE))) {
76 s->s_dev=0;
77 free_super(s);
78 printk("bread failed\n");
79 return NULL;
80 }
81
82
83 es = (struct ext_super_block *) bh->b_data;
84 s->s_blocksize = 1024;
85 s->u.ext_sb.s_ninodes = es->s_ninodes;
86 s->u.ext_sb.s_nzones = es->s_nzones;
87 #ifdef EXTFS_BITMAP
88 s->u.ext_sb.s_imap_blocks = es->s_imap_blocks;
89 s->u.ext_sb.s_zmap_blocks = es->s_zmap_blocks;
90 #endif
91 s->u.ext_sb.s_firstdatazone = es->s_firstdatazone;
92 s->u.ext_sb.s_log_zone_size = es->s_log_zone_size;
93 s->u.ext_sb.s_max_size = es->s_max_size;
94 s->s_magic = es->s_magic;
95 #ifdef EXTFS_FREELIST
96 s->u.ext_sb.s_zmap[0] = (struct buffer_head *) es->s_firstfreeblock;
97 s->u.ext_sb.s_zmap[2] = (struct buffer_head *) es->s_freeblockscount;
98 s->u.ext_sb.s_imap[0] = (struct buffer_head *) es->s_firstfreeinode;
99 s->u.ext_sb.s_imap[2] = (struct buffer_head *) es->s_freeinodescount;
100 #endif
101 brelse(bh);
102 if (s->s_magic != EXT_SUPER_MAGIC) {
103 s->s_dev = 0;
104 free_super(s);
105 printk("magic match failed\n");
106 return NULL;
107 }
108 #ifdef EXTFS_BITMAP
109 for (i=0;i < EXT_I_MAP_SLOTS;i++)
110 s->u.ext_sb.s_imap[i] = NULL;
111 for (i=0;i < EXT_Z_MAP_SLOTS;i++)
112 s->u.ext_sb.s_zmap[i] = NULL;
113 block=2;
114 for (i=0 ; i < s->u.ext_sb.s_imap_blocks ; i++)
115 if (s->u.ext_sb.s_imap[i]=bread(dev, block, BLOCK_SIZE))
116 block++;
117 else
118 break;
119 for (i=0 ; i < s->u.ext_sb.s_zmap_blocks ; i++)
120 if (s->u.ext_sb.s_zmap[i]=bread(dev, block, BLOCK_SIZE))
121 block++;
122 else
123 break;
124 if (block != 2+s->u.ext_sb.s_imap_blocks+s->u.ext_sb.s_zmap_blocks) {
125 for(i=0;i<EXT_I_MAP_SLOTS;i++)
126 brelse(s->u.ext_sb.s_imap[i]);
127 for(i=0;i<EXT_Z_MAP_SLOTS;i++)
128 brelse(s->u.ext_sb.s_zmap[i]);
129 s->s_dev=0;
130 free_super(s);
131 printk("block failed\n");
132 return NULL;
133 }
134 s->u.ext_sb.s_imap[0]->b_data[0] |= 1;
135 s->u.ext_sb.s_zmap[0]->b_data[0] |= 1;
136 #endif
137 #ifdef EXTFS_FREELIST
138 if (!s->u.ext_sb.s_zmap[0])
139 s->u.ext_sb.s_zmap[1] = NULL;
140 else
141 if (!(s->u.ext_sb.s_zmap[1] = bread(dev, (unsigned long) s->u.ext_sb.s_zmap[0], BLOCK_SIZE))) {
142 printk ("ext_read_super: unable to read first free block\n");
143 s->s_dev = 0;
144 free_super(s);
145 return NULL;
146 }
147 if (!s->u.ext_sb.s_imap[0])
148 s->u.ext_sb.s_imap[1] = NULL;
149 else {
150 block = 2 + (((unsigned long) s->u.ext_sb.s_imap[0]) - 1) / EXT_INODES_PER_BLOCK;
151 if (!(s->u.ext_sb.s_imap[1] = bread(dev, block, BLOCK_SIZE))) {
152 printk ("ext_read_super: unable to read first free inode block\n");
153 brelse(s->u.ext_sb.s_zmap[1]);
154 s->s_dev = 0;
155 free_super (s);
156 return NULL;
157 }
158 }
159 #endif
160
161 free_super(s);
162
163 s->s_dev = dev;
164 s->s_op = &ext_sops;
165 if (!(s->s_mounted = iget(dev,EXT_ROOT_INO))) {
166 s->s_dev=0;
167 printk("get root inode failed\n");
168 return NULL;
169 }
170 return s;
171 }
172
173 void ext_write_super (struct super_block *sb)
174 {
175 #ifdef EXTFS_FREELIST
176 struct buffer_head * bh;
177 struct ext_super_block * es;
178
179 #ifdef EXTFS_DEBUG
180 printk ("ext_write_super called\n");
181 #endif
182 if (!(bh = bread(sb->s_dev, 1, BLOCK_SIZE))) {
183 printk ("ext_write_super: bread failed\n");
184 return;
185 }
186 es = (struct ext_super_block *) bh->b_data;
187 es->s_firstfreeblock = (unsigned long) sb->u.ext_sb.s_zmap[0];
188 es->s_freeblockscount = (unsigned long) sb->u.ext_sb.s_zmap[2];
189 es->s_firstfreeinode = (unsigned long) sb->u.ext_sb.s_imap[0];
190 es->s_freeinodescount = (unsigned long) sb->u.ext_sb.s_imap[2];
191 bh->b_dirt = 1;
192 brelse (bh);
193 sb->s_dirt = 0;
194 #endif
195 }
196
197 void ext_statfs (struct super_block *sb, struct statfs *buf)
198 {
199 long tmp;
200
201 put_fs_long(EXT_SUPER_MAGIC, &buf->f_type);
202 put_fs_long(1024, &buf->f_bsize);
203 put_fs_long(sb->u.ext_sb.s_nzones << sb->u.ext_sb.s_log_zone_size, &buf->f_blocks);
204 tmp = ext_count_free_blocks(sb);
205 put_fs_long(tmp, &buf->f_bfree);
206 put_fs_long(tmp, &buf->f_bavail);
207 put_fs_long(sb->u.ext_sb.s_ninodes, &buf->f_files);
208 put_fs_long(ext_count_free_inodes(sb), &buf->f_ffree);
209
210 }
211
212 static int _ext_bmap(struct inode * inode,int block,int create)
213 {
214 struct buffer_head * bh;
215 int i;
216
217 if (block<0) {
218 printk("_ext_bmap: block<0");
219 return 0;
220 }
221 if (block >= 9+256+256*256+256*256*256) {
222 printk("_ext_bmap: block>big");
223 return 0;
224 }
225 if (block<9) {
226 if (create && !inode->i_data[block])
227 if (inode->i_data[block]=ext_new_block(inode->i_dev)) {
228 inode->i_ctime=CURRENT_TIME;
229 inode->i_dirt=1;
230 }
231 return inode->i_data[block];
232 }
233 block -= 9;
234 if (block<256) {
235 if (create && !inode->i_data[9])
236 if (inode->i_data[9]=ext_new_block(inode->i_dev)) {
237 inode->i_dirt=1;
238 inode->i_ctime=CURRENT_TIME;
239 }
240 if (!inode->i_data[9])
241 return 0;
242 if (!(bh = bread(inode->i_dev, inode->i_data[9], BLOCK_SIZE)))
243 return 0;
244 i = ((unsigned long *) (bh->b_data))[block];
245 if (create && !i)
246 if (i=ext_new_block(inode->i_dev)) {
247 ((unsigned long *) (bh->b_data))[block]=i;
248 bh->b_dirt=1;
249 }
250 brelse(bh);
251 return i;
252 }
253 block -= 256;
254 if (block<256*256) {
255 if (create && !inode->i_data[10])
256 if (inode->i_data[10]=ext_new_block(inode->i_dev)) {
257 inode->i_dirt=1;
258 inode->i_ctime=CURRENT_TIME;
259 }
260 if (!inode->i_data[10])
261 return 0;
262 if (!(bh=bread(inode->i_dev, inode->i_data[10], BLOCK_SIZE)))
263 return 0;
264 i = ((unsigned long *)bh->b_data)[block>>8];
265 if (create && !i)
266 if (i=ext_new_block(inode->i_dev)) {
267 ((unsigned long *) (bh->b_data))[block>>8]=i;
268 bh->b_dirt=1;
269 }
270 brelse(bh);
271 if (!i)
272 return 0;
273 if (!(bh=bread(inode->i_dev, i, BLOCK_SIZE)))
274 return 0;
275 i = ((unsigned long *)bh->b_data)[block&255];
276 if (create && !i)
277 if (i=ext_new_block(inode->i_dev)) {
278 ((unsigned long *) (bh->b_data))[block&255]=i;
279 bh->b_dirt=1;
280 }
281 brelse(bh);
282 return i;
283 }
284 if (create && !inode->i_data[11])
285 if (inode->i_data[11] = ext_new_block(inode->i_dev)) {
286 inode->i_dirt = 1;
287 inode->i_ctime = CURRENT_TIME;
288 }
289 if (!inode->i_data[11])
290 return 0;
291 if (!(bh = bread(inode->i_dev, inode->i_data[11], BLOCK_SIZE)))
292 return 0;
293 i = ((unsigned long *) bh->b_data)[block >> 16];
294 if (create && !i)
295 if (i = ext_new_block(inode->i_dev)) {
296 ((unsigned long *) bh->b_data)[block >> 16] = i;
297 bh->b_dirt = 1;
298 }
299 brelse (bh);
300 if (!i)
301 return 0;
302 if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
303 return 0;
304 i = ((unsigned long *) bh->b_data)[(block >> 8) & 255];
305 if (create && !i)
306 if (i = ext_new_block(inode->i_dev)) {
307 ((unsigned long *) bh->b_data)[(block >> 8) & 255] = i;
308 bh->b_dirt = 1;
309 }
310 brelse (bh);
311 if (!i)
312 return 0;
313 if (!(bh = bread(inode->i_dev, i, BLOCK_SIZE)))
314 return 0;
315 i = ((unsigned long *) bh->b_data)[block & 255];
316 if (create && !i)
317 if (i = ext_new_block(inode->i_dev)) {
318 ((unsigned long *) bh->b_data)[block & 255] = i;
319 bh->b_dirt = 1;
320 }
321 brelse (bh);
322 return i;
323
324 printk("ext_bmap: triple indirection not yet implemented\n");
325 return 0;
326 }
327
328 int ext_bmap(struct inode * inode,int block)
329 {
330 return _ext_bmap(inode,block,0);
331 }
332
333 int ext_create_block(struct inode * inode, int block)
334 {
335 return _ext_bmap(inode,block,1);
336 }
337
338 void ext_read_inode(struct inode * inode)
339 {
340 struct buffer_head * bh;
341 struct ext_inode * raw_inode;
342 int block;
343
344 #ifdef EXTFS_BITMAP
345 block = 2 + inode->i_sb->u.ext_sb.s_imap_blocks + inode->i_sb->u.ext_sb.s_zmap_blocks +
346 (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
347 #endif
348 #ifdef EXTFS_FREELIST
349 block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
350 #endif
351 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
352 panic("unable to read i-node block");
353 raw_inode = ((struct ext_inode *) bh->b_data) +
354 (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
355 inode->i_mode = raw_inode->i_mode;
356 inode->i_uid = raw_inode->i_uid;
357 inode->i_gid = raw_inode->i_gid;
358 inode->i_nlink = raw_inode->i_nlinks;
359 inode->i_size = raw_inode->i_size;
360 inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
361 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
362 inode->i_rdev = raw_inode->i_zone[0];
363 else for (block = 0; block < 12; block++)
364 inode->i_data[block] = raw_inode->i_zone[block];
365 brelse(bh);
366 inode->i_op = NULL;
367 if (S_ISREG(inode->i_mode))
368 inode->i_op = &ext_file_inode_operations;
369 else if (S_ISDIR(inode->i_mode))
370 inode->i_op = &ext_dir_inode_operations;
371 else if (S_ISLNK(inode->i_mode))
372 inode->i_op = &ext_symlink_inode_operations;
373 else if (S_ISCHR(inode->i_mode))
374 inode->i_op = &ext_chrdev_inode_operations;
375 else if (S_ISBLK(inode->i_mode))
376 inode->i_op = &ext_blkdev_inode_operations;
377 else if (S_ISFIFO(inode->i_mode)) {
378 inode->i_op = &ext_fifo_inode_operations;
379 inode->i_size = 0;
380 inode->i_pipe = 1;
381 PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
382 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
383 }
384 }
385
386 void ext_write_inode(struct inode * inode)
387 {
388 struct buffer_head * bh;
389 struct ext_inode * raw_inode;
390 int block;
391
392 #ifdef EXTFS_BITMAP
393 block = 2 + inode->i_sb->u.ext_sb.s_imap_blocks + inode->i_sb->u.ext_sb.s_zmap_blocks +
394 (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
395 #endif
396 #ifdef EXTFS_FREELIST
397 block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
398 #endif
399 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
400 panic("unable to read i-node block");
401 raw_inode = ((struct ext_inode *)bh->b_data) +
402 (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
403 raw_inode->i_mode = inode->i_mode;
404 raw_inode->i_uid = inode->i_uid;
405 raw_inode->i_gid = inode->i_gid;
406 raw_inode->i_nlinks = inode->i_nlink;
407 raw_inode->i_size = inode->i_size;
408 raw_inode->i_time = inode->i_mtime;
409 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
410 raw_inode->i_zone[0] = inode->i_rdev;
411 else for (block = 0; block < 12; block++)
412 raw_inode->i_zone[block] = inode->i_data[block];
413 bh->b_dirt=1;
414 inode->i_dirt=0;
415 brelse(bh);
416 }