This source file includes following definitions.
- ext_put_inode
- ext_put_super
- ext_read_super
- ext_write_super
- ext_statfs
- block_bmap
- ext_bmap
- inode_getblk
- block_getblk
- ext_getblk
- ext_bread
- ext_read_inode
- ext_update_inode
- ext_write_inode
- ext_sync_inode
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11
12
13 #ifdef MODULE
14 #include <linux/module.h>
15 #include <linux/version.h>
16 #else
17 #define MOD_INC_USE_COUNT
18 #define MOD_DEC_USE_COUNT
19 #endif
20
21 #include <linux/sched.h>
22 #include <linux/ext_fs.h>
23 #include <linux/kernel.h>
24 #include <linux/mm.h>
25 #include <linux/string.h>
26 #include <linux/stat.h>
27 #include <linux/locks.h>
28
29 #include <asm/system.h>
30 #include <asm/segment.h>
31
32 void ext_put_inode(struct inode *inode)
33 {
34 if (inode->i_nlink)
35 return;
36 inode->i_size = 0;
37 ext_truncate(inode);
38 ext_free_inode(inode);
39 }
40
41 void ext_put_super(struct super_block *sb)
42 {
43
44 lock_super(sb);
45 sb->s_dev = 0;
46 if (sb->u.ext_sb.s_firstfreeinodeblock)
47 brelse (sb->u.ext_sb.s_firstfreeinodeblock);
48 if (sb->u.ext_sb.s_firstfreeblock)
49 brelse (sb->u.ext_sb.s_firstfreeblock);
50 unlock_super(sb);
51 MOD_DEC_USE_COUNT;
52 return;
53 }
54
55 static struct super_operations ext_sops = {
56 ext_read_inode,
57 NULL,
58 ext_write_inode,
59 ext_put_inode,
60 ext_put_super,
61 ext_write_super,
62 ext_statfs,
63 NULL
64 };
65
66 struct super_block *ext_read_super(struct super_block *s,void *data,
67 int silent)
68 {
69 struct buffer_head *bh;
70 struct ext_super_block *es;
71 kdev_t dev = s->s_dev;
72 int block;
73
74 MOD_INC_USE_COUNT;
75 lock_super(s);
76 set_blocksize(dev, BLOCK_SIZE);
77 if (!(bh = bread(dev, 1, BLOCK_SIZE))) {
78 s->s_dev = 0;
79 unlock_super(s);
80 printk("EXT-fs: unable to read superblock\n");
81 MOD_DEC_USE_COUNT;
82 return NULL;
83 }
84 es = (struct ext_super_block *) bh->b_data;
85 s->s_blocksize = 1024;
86 s->s_blocksize_bits = 10;
87 s->u.ext_sb.s_ninodes = es->s_ninodes;
88 s->u.ext_sb.s_nzones = es->s_nzones;
89 s->u.ext_sb.s_firstdatazone = es->s_firstdatazone;
90 s->u.ext_sb.s_log_zone_size = es->s_log_zone_size;
91 s->u.ext_sb.s_max_size = es->s_max_size;
92 s->s_magic = es->s_magic;
93 s->u.ext_sb.s_firstfreeblocknumber = es->s_firstfreeblock;
94 s->u.ext_sb.s_freeblockscount = es->s_freeblockscount;
95 s->u.ext_sb.s_firstfreeinodenumber = es->s_firstfreeinode;
96 s->u.ext_sb.s_freeinodescount = es->s_freeinodescount;
97 brelse(bh);
98 if (s->s_magic != EXT_SUPER_MAGIC) {
99 s->s_dev = 0;
100 unlock_super(s);
101 if (!silent)
102 printk("VFS: Can't find an extfs filesystem on dev "
103 "%s.\n", kdevname(dev));
104 MOD_DEC_USE_COUNT;
105 return NULL;
106 }
107 if (!s->u.ext_sb.s_firstfreeblocknumber)
108 s->u.ext_sb.s_firstfreeblock = NULL;
109 else
110 if (!(s->u.ext_sb.s_firstfreeblock = bread(dev,
111 s->u.ext_sb.s_firstfreeblocknumber, BLOCK_SIZE))) {
112 printk("ext_read_super: unable to read first free block\n");
113 s->s_dev = 0;
114 unlock_super(s);
115 MOD_DEC_USE_COUNT;
116 return NULL;
117 }
118 if (!s->u.ext_sb.s_firstfreeinodenumber)
119 s->u.ext_sb.s_firstfreeinodeblock = NULL;
120 else {
121 block = 2 + (s->u.ext_sb.s_firstfreeinodenumber - 1) / EXT_INODES_PER_BLOCK;
122 if (!(s->u.ext_sb.s_firstfreeinodeblock = bread(dev, block, BLOCK_SIZE))) {
123 printk("ext_read_super: unable to read first free inode block\n");
124 brelse(s->u.ext_sb.s_firstfreeblock);
125 s->s_dev = 0;
126 unlock_super (s);
127 MOD_DEC_USE_COUNT;
128 return NULL;
129 }
130 }
131 unlock_super(s);
132
133 s->s_dev = dev;
134 s->s_op = &ext_sops;
135 if (!(s->s_mounted = iget(s,EXT_ROOT_INO))) {
136 s->s_dev = 0;
137 printk("EXT-fs: get root inode failed\n");
138 MOD_DEC_USE_COUNT;
139 return NULL;
140 }
141 return s;
142 }
143
144 void ext_write_super (struct super_block *sb)
145 {
146 struct buffer_head * bh;
147 struct ext_super_block * es;
148
149 if (!(bh = bread(sb->s_dev, 1, BLOCK_SIZE))) {
150 printk ("ext_write_super: bread failed\n");
151 return;
152 }
153 es = (struct ext_super_block *) bh->b_data;
154 es->s_firstfreeblock = sb->u.ext_sb.s_firstfreeblocknumber;
155 es->s_freeblockscount = sb->u.ext_sb.s_freeblockscount;
156 es->s_firstfreeinode = sb->u.ext_sb.s_firstfreeinodenumber;
157 es->s_freeinodescount = sb->u.ext_sb.s_freeinodescount;
158 mark_buffer_dirty(bh, 1);
159 brelse (bh);
160 sb->s_dirt = 0;
161 }
162
163 void ext_statfs (struct super_block *sb, struct statfs *buf, int bufsiz)
164 {
165 struct statfs tmp;
166
167 tmp.f_type = EXT_SUPER_MAGIC;
168 tmp.f_bsize = 1024;
169 tmp.f_blocks = sb->u.ext_sb.s_nzones << sb->u.ext_sb.s_log_zone_size;
170 tmp.f_bfree = ext_count_free_blocks(sb);
171 tmp.f_bavail = tmp.f_bfree;
172 tmp.f_files = sb->u.ext_sb.s_ninodes;
173 tmp.f_ffree = ext_count_free_inodes(sb);
174 tmp.f_namelen = EXT_NAME_LEN;
175 memcpy_tofs(buf, &tmp, bufsiz);
176 }
177
178 #define inode_bmap(inode,nr) ((inode)->u.ext_i.i_data[(nr)])
179
180 static int block_bmap(struct buffer_head * bh, int nr)
181 {
182 int tmp;
183
184 if (!bh)
185 return 0;
186 tmp = ((unsigned long *) bh->b_data)[nr];
187 brelse(bh);
188 return tmp;
189 }
190
191 int ext_bmap(struct inode * inode,int block)
192 {
193 int i;
194
195 if (block<0) {
196 printk("ext_bmap: block<0");
197 return 0;
198 }
199 if (block >= 9+256+256*256+256*256*256) {
200 printk("ext_bmap: block>big");
201 return 0;
202 }
203 if (block<9)
204 return inode_bmap(inode,block);
205 block -= 9;
206 if (block<256) {
207 i = inode_bmap(inode,9);
208 if (!i)
209 return 0;
210 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
211 }
212 block -= 256;
213 if (block<256*256) {
214 i = inode_bmap(inode,10);
215 if (!i)
216 return 0;
217 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>8);
218 if (!i)
219 return 0;
220 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
221 }
222 block -= 256*256;
223 i = inode_bmap(inode,11);
224 if (!i)
225 return 0;
226 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>16);
227 if (!i)
228 return 0;
229 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block>>8) & 255);
230 if (!i)
231 return 0;
232 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
233 }
234
235 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
236 {
237 int tmp;
238 unsigned long * p;
239 struct buffer_head * result;
240
241 p = inode->u.ext_i.i_data + nr;
242 repeat:
243 tmp = *p;
244 if (tmp) {
245 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
246 if (tmp == *p)
247 return result;
248 brelse(result);
249 goto repeat;
250 }
251 if (!create)
252 return NULL;
253 tmp = ext_new_block(inode->i_sb);
254 if (!tmp)
255 return NULL;
256 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
257 if (*p) {
258 ext_free_block(inode->i_sb,tmp);
259 brelse(result);
260 goto repeat;
261 }
262 *p = tmp;
263 inode->i_ctime = CURRENT_TIME;
264 inode->i_dirt = 1;
265 return result;
266 }
267
268 static struct buffer_head * block_getblk(struct inode * inode,
269 struct buffer_head * bh, int nr, int create)
270 {
271 int tmp;
272 unsigned long * p;
273 struct buffer_head * result;
274
275 if (!bh)
276 return NULL;
277 if (!bh->b_uptodate) {
278 ll_rw_block(READ, 1, &bh);
279 wait_on_buffer(bh);
280 if (!bh->b_uptodate) {
281 brelse(bh);
282 return NULL;
283 }
284 }
285 p = nr + (unsigned long *) bh->b_data;
286 repeat:
287 tmp = *p;
288 if (tmp) {
289 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
290 if (tmp == *p) {
291 brelse(bh);
292 return result;
293 }
294 brelse(result);
295 goto repeat;
296 }
297 if (!create) {
298 brelse(bh);
299 return NULL;
300 }
301 tmp = ext_new_block(inode->i_sb);
302 if (!tmp) {
303 brelse(bh);
304 return NULL;
305 }
306 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
307 if (*p) {
308 ext_free_block(inode->i_sb,tmp);
309 brelse(result);
310 goto repeat;
311 }
312 *p = tmp;
313 mark_buffer_dirty(bh, 1);
314 brelse(bh);
315 return result;
316 }
317
318 struct buffer_head * ext_getblk(struct inode * inode, int block, int create)
319 {
320 struct buffer_head * bh;
321
322 if (block<0) {
323 printk("ext_getblk: block<0\n");
324 return NULL;
325 }
326 if (block >= 9+256+256*256+256*256*256) {
327 printk("ext_getblk: block>big\n");
328 return NULL;
329 }
330 if (block<9)
331 return inode_getblk(inode,block,create);
332 block -= 9;
333 if (block<256) {
334 bh = inode_getblk(inode,9,create);
335 return block_getblk(inode,bh,block,create);
336 }
337 block -= 256;
338 if (block<256*256) {
339 bh = inode_getblk(inode,10,create);
340 bh = block_getblk(inode,bh,block>>8,create);
341 return block_getblk(inode,bh,block & 255,create);
342 }
343 block -= 256*256;
344 bh = inode_getblk(inode,11,create);
345 bh = block_getblk(inode,bh,block>>16,create);
346 bh = block_getblk(inode,bh,(block>>8) & 255,create);
347 return block_getblk(inode,bh,block & 255,create);
348 }
349
350 struct buffer_head * ext_bread(struct inode * inode, int block, int create)
351 {
352 struct buffer_head * bh;
353
354 bh = ext_getblk(inode,block,create);
355 if (!bh || bh->b_uptodate)
356 return bh;
357 ll_rw_block(READ, 1, &bh);
358 wait_on_buffer(bh);
359 if (bh->b_uptodate)
360 return bh;
361 brelse(bh);
362 return NULL;
363 }
364
365 void ext_read_inode(struct inode * inode)
366 {
367 struct buffer_head * bh;
368 struct ext_inode * raw_inode;
369 int block;
370
371 block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
372 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
373 panic("unable to read i-node block");
374 raw_inode = ((struct ext_inode *) bh->b_data) +
375 (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
376 inode->i_mode = raw_inode->i_mode;
377 inode->i_uid = raw_inode->i_uid;
378 inode->i_gid = raw_inode->i_gid;
379 inode->i_nlink = raw_inode->i_nlinks;
380 inode->i_size = raw_inode->i_size;
381 inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
382 inode->i_blocks = inode->i_blksize = 0;
383 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
384 inode->i_rdev = to_kdev_t(raw_inode->i_zone[0]);
385 else for (block = 0; block < 12; block++)
386 inode->u.ext_i.i_data[block] = raw_inode->i_zone[block];
387 brelse(bh);
388 inode->i_op = NULL;
389 if (S_ISREG(inode->i_mode))
390 inode->i_op = &ext_file_inode_operations;
391 else if (S_ISDIR(inode->i_mode))
392 inode->i_op = &ext_dir_inode_operations;
393 else if (S_ISLNK(inode->i_mode))
394 inode->i_op = &ext_symlink_inode_operations;
395 else if (S_ISCHR(inode->i_mode))
396 inode->i_op = &chrdev_inode_operations;
397 else if (S_ISBLK(inode->i_mode))
398 inode->i_op = &blkdev_inode_operations;
399 else if (S_ISFIFO(inode->i_mode))
400 init_fifo(inode);
401 }
402
403 static struct buffer_head * ext_update_inode(struct inode * inode)
404 {
405 struct buffer_head * bh;
406 struct ext_inode * raw_inode;
407 int block;
408
409 block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
410 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
411 panic("unable to read i-node block");
412 raw_inode = ((struct ext_inode *)bh->b_data) +
413 (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
414 raw_inode->i_mode = inode->i_mode;
415 raw_inode->i_uid = inode->i_uid;
416 raw_inode->i_gid = inode->i_gid;
417 raw_inode->i_nlinks = inode->i_nlink;
418 raw_inode->i_size = inode->i_size;
419 raw_inode->i_time = inode->i_mtime;
420 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
421 raw_inode->i_zone[0] = kdev_t_to_nr(inode->i_rdev);
422 else for (block = 0; block < 12; block++)
423 raw_inode->i_zone[block] = inode->u.ext_i.i_data[block];
424 mark_buffer_dirty(bh, 1);
425 inode->i_dirt=0;
426 return bh;
427 }
428
429 void ext_write_inode(struct inode * inode)
430 {
431 struct buffer_head *bh;
432 bh = ext_update_inode (inode);
433 brelse(bh);
434 }
435
436 int ext_sync_inode (struct inode *inode)
437 {
438 int err = 0;
439 struct buffer_head *bh;
440
441 bh = ext_update_inode(inode);
442 if (bh && bh->b_dirt)
443 {
444 ll_rw_block(WRITE, 1, &bh);
445 wait_on_buffer(bh);
446 if (bh->b_req && !bh->b_uptodate)
447 {
448 printk ("IO error syncing ext inode ["
449 "%s:%08lx]\n",
450 kdevname(inode->i_dev), inode->i_ino);
451 err = -1;
452 }
453 }
454 else if (!bh)
455 err = -1;
456 brelse (bh);
457 return err;
458 }
459
460 #ifdef MODULE
461
462 char kernel_version[] = UTS_RELEASE;
463
464 static struct file_system_type ext_fs_type = {
465 ext_read_super, "ext", 1, NULL
466 };
467
468 int init_module(void)
469 {
470 register_filesystem(&ext_fs_type);
471 return 0;
472 }
473
474 void cleanup_module(void)
475 {
476 unregister_filesystem(&ext_fs_type);
477 }
478
479 #endif