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