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, int bufsiz)
148 {
149 struct statfs tmp;
150
151 tmp.f_type = EXT_SUPER_MAGIC;
152 tmp.f_bsize = 1024;
153 tmp.f_blocks = sb->u.ext_sb.s_nzones << sb->u.ext_sb.s_log_zone_size;
154 tmp.f_bfree = ext_count_free_blocks(sb);
155 tmp.f_bavail = tmp.f_bfree;
156 tmp.f_files = sb->u.ext_sb.s_ninodes;
157 tmp.f_ffree = ext_count_free_inodes(sb);
158 tmp.f_namelen = EXT_NAME_LEN;
159 memcpy_tofs(buf, &tmp, bufsiz);
160 }
161
162 #define inode_bmap(inode,nr) ((inode)->u.ext_i.i_data[(nr)])
163
164 static int block_bmap(struct buffer_head * bh, int nr)
165 {
166 int tmp;
167
168 if (!bh)
169 return 0;
170 tmp = ((unsigned long *) bh->b_data)[nr];
171 brelse(bh);
172 return tmp;
173 }
174
175 int ext_bmap(struct inode * inode,int block)
176 {
177 int i;
178
179 if (block<0) {
180 printk("ext_bmap: block<0");
181 return 0;
182 }
183 if (block >= 9+256+256*256+256*256*256) {
184 printk("ext_bmap: block>big");
185 return 0;
186 }
187 if (block<9)
188 return inode_bmap(inode,block);
189 block -= 9;
190 if (block<256) {
191 i = inode_bmap(inode,9);
192 if (!i)
193 return 0;
194 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
195 }
196 block -= 256;
197 if (block<256*256) {
198 i = inode_bmap(inode,10);
199 if (!i)
200 return 0;
201 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>8);
202 if (!i)
203 return 0;
204 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
205 }
206 block -= 256*256;
207 i = inode_bmap(inode,11);
208 if (!i)
209 return 0;
210 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>16);
211 if (!i)
212 return 0;
213 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block>>8) & 255);
214 if (!i)
215 return 0;
216 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
217 }
218
219 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
220 {
221 int tmp;
222 unsigned long * p;
223 struct buffer_head * result;
224
225 p = inode->u.ext_i.i_data + nr;
226 repeat:
227 tmp = *p;
228 if (tmp) {
229 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
230 if (tmp == *p)
231 return result;
232 brelse(result);
233 goto repeat;
234 }
235 if (!create)
236 return NULL;
237 tmp = ext_new_block(inode->i_sb);
238 if (!tmp)
239 return NULL;
240 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
241 if (*p) {
242 ext_free_block(inode->i_sb,tmp);
243 brelse(result);
244 goto repeat;
245 }
246 *p = tmp;
247 inode->i_ctime = CURRENT_TIME;
248 inode->i_dirt = 1;
249 return result;
250 }
251
252 static struct buffer_head * block_getblk(struct inode * inode,
253 struct buffer_head * bh, int nr, int create)
254 {
255 int tmp;
256 unsigned long * p;
257 struct buffer_head * result;
258
259 if (!bh)
260 return NULL;
261 if (!bh->b_uptodate) {
262 ll_rw_block(READ, 1, &bh);
263 wait_on_buffer(bh);
264 if (!bh->b_uptodate) {
265 brelse(bh);
266 return NULL;
267 }
268 }
269 p = nr + (unsigned long *) bh->b_data;
270 repeat:
271 tmp = *p;
272 if (tmp) {
273 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
274 if (tmp == *p) {
275 brelse(bh);
276 return result;
277 }
278 brelse(result);
279 goto repeat;
280 }
281 if (!create) {
282 brelse(bh);
283 return NULL;
284 }
285 tmp = ext_new_block(inode->i_sb);
286 if (!tmp) {
287 brelse(bh);
288 return NULL;
289 }
290 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
291 if (*p) {
292 ext_free_block(inode->i_sb,tmp);
293 brelse(result);
294 goto repeat;
295 }
296 *p = tmp;
297 mark_buffer_dirty(bh, 1);
298 brelse(bh);
299 return result;
300 }
301
302 struct buffer_head * ext_getblk(struct inode * inode, int block, int create)
303 {
304 struct buffer_head * bh;
305
306 if (block<0) {
307 printk("ext_getblk: block<0\n");
308 return NULL;
309 }
310 if (block >= 9+256+256*256+256*256*256) {
311 printk("ext_getblk: block>big\n");
312 return NULL;
313 }
314 if (block<9)
315 return inode_getblk(inode,block,create);
316 block -= 9;
317 if (block<256) {
318 bh = inode_getblk(inode,9,create);
319 return block_getblk(inode,bh,block,create);
320 }
321 block -= 256;
322 if (block<256*256) {
323 bh = inode_getblk(inode,10,create);
324 bh = block_getblk(inode,bh,block>>8,create);
325 return block_getblk(inode,bh,block & 255,create);
326 }
327 block -= 256*256;
328 bh = inode_getblk(inode,11,create);
329 bh = block_getblk(inode,bh,block>>16,create);
330 bh = block_getblk(inode,bh,(block>>8) & 255,create);
331 return block_getblk(inode,bh,block & 255,create);
332 }
333
334 struct buffer_head * ext_bread(struct inode * inode, int block, int create)
335 {
336 struct buffer_head * bh;
337
338 bh = ext_getblk(inode,block,create);
339 if (!bh || bh->b_uptodate)
340 return bh;
341 ll_rw_block(READ, 1, &bh);
342 wait_on_buffer(bh);
343 if (bh->b_uptodate)
344 return bh;
345 brelse(bh);
346 return NULL;
347 }
348
349 void ext_read_inode(struct inode * inode)
350 {
351 struct buffer_head * bh;
352 struct ext_inode * raw_inode;
353 int block;
354
355 block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
356 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
357 panic("unable to read i-node block");
358 raw_inode = ((struct ext_inode *) bh->b_data) +
359 (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
360 inode->i_mode = raw_inode->i_mode;
361 inode->i_uid = raw_inode->i_uid;
362 inode->i_gid = raw_inode->i_gid;
363 inode->i_nlink = raw_inode->i_nlinks;
364 inode->i_size = raw_inode->i_size;
365 inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
366 inode->i_blocks = inode->i_blksize = 0;
367 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
368 inode->i_rdev = raw_inode->i_zone[0];
369 else for (block = 0; block < 12; block++)
370 inode->u.ext_i.i_data[block] = raw_inode->i_zone[block];
371 brelse(bh);
372 inode->i_op = NULL;
373 if (S_ISREG(inode->i_mode))
374 inode->i_op = &ext_file_inode_operations;
375 else if (S_ISDIR(inode->i_mode))
376 inode->i_op = &ext_dir_inode_operations;
377 else if (S_ISLNK(inode->i_mode))
378 inode->i_op = &ext_symlink_inode_operations;
379 else if (S_ISCHR(inode->i_mode))
380 inode->i_op = &chrdev_inode_operations;
381 else if (S_ISBLK(inode->i_mode))
382 inode->i_op = &blkdev_inode_operations;
383 else if (S_ISFIFO(inode->i_mode))
384 init_fifo(inode);
385 }
386
387 static struct buffer_head * ext_update_inode(struct inode * inode)
388 {
389 struct buffer_head * bh;
390 struct ext_inode * raw_inode;
391 int block;
392
393 block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
394 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
395 panic("unable to read i-node block");
396 raw_inode = ((struct ext_inode *)bh->b_data) +
397 (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
398 raw_inode->i_mode = inode->i_mode;
399 raw_inode->i_uid = inode->i_uid;
400 raw_inode->i_gid = inode->i_gid;
401 raw_inode->i_nlinks = inode->i_nlink;
402 raw_inode->i_size = inode->i_size;
403 raw_inode->i_time = inode->i_mtime;
404 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
405 raw_inode->i_zone[0] = inode->i_rdev;
406 else for (block = 0; block < 12; block++)
407 raw_inode->i_zone[block] = inode->u.ext_i.i_data[block];
408 mark_buffer_dirty(bh, 1);
409 inode->i_dirt=0;
410 return bh;
411 }
412
413 void ext_write_inode(struct inode * inode)
414 {
415 struct buffer_head *bh;
416 bh = ext_update_inode (inode);
417 brelse(bh);
418 }
419
420 int ext_sync_inode (struct inode *inode)
421 {
422 int err = 0;
423 struct buffer_head *bh;
424
425 bh = ext_update_inode(inode);
426 if (bh && bh->b_dirt)
427 {
428 ll_rw_block(WRITE, 1, &bh);
429 wait_on_buffer(bh);
430 if (bh->b_req && !bh->b_uptodate)
431 {
432 printk ("IO error syncing ext inode [%04x:%08lx]\n",
433 inode->i_dev, inode->i_ino);
434 err = -1;
435 }
436 }
437 else if (!bh)
438 err = -1;
439 brelse (bh);
440 return err;
441 }
442