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