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_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 #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 ext_write_inode,
49 ext_put_inode,
50 ext_put_super,
51 ext_write_super,
52 ext_statfs
53 };
54
55 struct super_block *ext_read_super(struct super_block *s,void *data)
56 {
57 struct buffer_head *bh;
58 struct ext_super_block *es;
59 int dev = s->s_dev,block;
60
61 lock_super(s);
62 if (!(bh = bread(dev, 1, BLOCK_SIZE))) {
63 s->s_dev=0;
64 unlock_super(s);
65 printk("bread failed\n");
66 return NULL;
67 }
68 es = (struct ext_super_block *) bh->b_data;
69 s->s_blocksize = 1024;
70 s->u.ext_sb.s_ninodes = es->s_ninodes;
71 s->u.ext_sb.s_nzones = es->s_nzones;
72 s->u.ext_sb.s_firstdatazone = es->s_firstdatazone;
73 s->u.ext_sb.s_log_zone_size = es->s_log_zone_size;
74 s->u.ext_sb.s_max_size = es->s_max_size;
75 s->s_magic = es->s_magic;
76 s->u.ext_sb.s_firstfreeblocknumber = es->s_firstfreeblock;
77 s->u.ext_sb.s_freeblockscount = es->s_freeblockscount;
78 s->u.ext_sb.s_firstfreeinodenumber = es->s_firstfreeinode;
79 s->u.ext_sb.s_freeinodescount = es->s_freeinodescount;
80 brelse(bh);
81 if (s->s_magic != EXT_SUPER_MAGIC) {
82 s->s_dev = 0;
83 unlock_super(s);
84 printk("magic match failed\n");
85 return NULL;
86 }
87 if (!s->u.ext_sb.s_firstfreeblocknumber)
88 s->u.ext_sb.s_firstfreeblock = NULL;
89 else
90 if (!(s->u.ext_sb.s_firstfreeblock = bread(dev,
91 s->u.ext_sb.s_firstfreeblocknumber, BLOCK_SIZE))) {
92 printk ("ext_read_super: unable to read first free block\n");
93 s->s_dev = 0;
94 unlock_super(s);
95 return NULL;
96 }
97 if (!s->u.ext_sb.s_firstfreeinodenumber)
98 s->u.ext_sb.s_firstfreeinodeblock = NULL;
99 else {
100 block = 2 + (s->u.ext_sb.s_firstfreeinodenumber - 1) / EXT_INODES_PER_BLOCK;
101 if (!(s->u.ext_sb.s_firstfreeinodeblock = bread(dev, block, BLOCK_SIZE))) {
102 printk ("ext_read_super: unable to read first free inode block\n");
103 brelse(s->u.ext_sb.s_firstfreeblock);
104 s->s_dev = 0;
105 unlock_super (s);
106 return NULL;
107 }
108 }
109 unlock_super(s);
110
111 s->s_dev = dev;
112 s->s_op = &ext_sops;
113 if (!(s->s_mounted = iget(s,EXT_ROOT_INO))) {
114 s->s_dev=0;
115 printk("get root inode failed\n");
116 return NULL;
117 }
118 return s;
119 }
120
121 void ext_write_super (struct super_block *sb)
122 {
123 struct buffer_head * bh;
124 struct ext_super_block * es;
125
126 if (!(bh = bread(sb->s_dev, 1, BLOCK_SIZE))) {
127 printk ("ext_write_super: bread failed\n");
128 return;
129 }
130 es = (struct ext_super_block *) bh->b_data;
131 es->s_firstfreeblock = sb->u.ext_sb.s_firstfreeblocknumber;
132 es->s_freeblockscount = sb->u.ext_sb.s_freeblockscount;
133 es->s_firstfreeinode = sb->u.ext_sb.s_firstfreeinodenumber;
134 es->s_freeinodescount = sb->u.ext_sb.s_freeinodescount;
135 bh->b_dirt = 1;
136 brelse (bh);
137 sb->s_dirt = 0;
138 }
139
140 void ext_statfs (struct super_block *sb, struct statfs *buf)
141 {
142 long tmp;
143
144 put_fs_long(EXT_SUPER_MAGIC, &buf->f_type);
145 put_fs_long(1024, &buf->f_bsize);
146 put_fs_long(sb->u.ext_sb.s_nzones << sb->u.ext_sb.s_log_zone_size,
147 &buf->f_blocks);
148 tmp = ext_count_free_blocks(sb);
149 put_fs_long(tmp, &buf->f_bfree);
150 put_fs_long(tmp, &buf->f_bavail);
151 put_fs_long(sb->u.ext_sb.s_ninodes, &buf->f_files);
152 put_fs_long(ext_count_free_inodes(sb), &buf->f_ffree);
153
154 }
155
156 #define inode_bmap(inode,nr) ((inode)->u.ext_i.i_data[(nr)])
157
158 static int block_bmap(struct buffer_head * bh, int nr)
159 {
160 int tmp;
161
162 if (!bh)
163 return 0;
164 tmp = ((unsigned long *) bh->b_data)[nr];
165 brelse(bh);
166 return tmp;
167 }
168
169 int ext_bmap(struct inode * inode,int block)
170 {
171 int i;
172
173 if (block<0) {
174 printk("ext_bmap: block<0");
175 return 0;
176 }
177 if (block >= 9+256+256*256+256*256*256) {
178 printk("ext_bmap: block>big");
179 return 0;
180 }
181 if (block<9)
182 return inode_bmap(inode,block);
183 block -= 9;
184 if (block<256) {
185 i = inode_bmap(inode,9);
186 if (!i)
187 return 0;
188 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
189 }
190 block -= 256;
191 if (block<256*256) {
192 i = inode_bmap(inode,10);
193 if (!i)
194 return 0;
195 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>8);
196 if (!i)
197 return 0;
198 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
199 }
200 block -= 256*256;
201 i = inode_bmap(inode,11);
202 if (!i)
203 return 0;
204 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>16);
205 if (!i)
206 return 0;
207 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block>>8) & 255);
208 if (!i)
209 return 0;
210 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
211 }
212
213 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
214 {
215 int tmp;
216 unsigned long * p;
217 struct buffer_head * result;
218
219 p = inode->u.ext_i.i_data + nr;
220 repeat:
221 tmp = *p;
222 if (tmp) {
223 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
224 if (tmp == *p)
225 return result;
226 brelse(result);
227 goto repeat;
228 }
229 if (!create)
230 return NULL;
231 tmp = ext_new_block(inode->i_sb);
232 if (!tmp)
233 return NULL;
234 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
235 if (*p) {
236 ext_free_block(inode->i_sb,tmp);
237 brelse(result);
238 goto repeat;
239 }
240 *p = tmp;
241 inode->i_ctime = CURRENT_TIME;
242 inode->i_dirt = 1;
243 return result;
244 }
245
246 static struct buffer_head * block_getblk(struct inode * inode,
247 struct buffer_head * bh, int nr, int create)
248 {
249 int tmp;
250 unsigned long * p;
251 struct buffer_head * result;
252
253 if (!bh)
254 return NULL;
255 if (!bh->b_uptodate) {
256 ll_rw_block(READ,bh);
257 wait_on_buffer(bh);
258 if (!bh->b_uptodate) {
259 brelse(bh);
260 return NULL;
261 }
262 }
263 p = nr + (unsigned long *) bh->b_data;
264 repeat:
265 tmp = *p;
266 if (tmp) {
267 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
268 if (tmp == *p) {
269 brelse(bh);
270 return result;
271 }
272 brelse(result);
273 goto repeat;
274 }
275 if (!create) {
276 brelse(bh);
277 return NULL;
278 }
279 tmp = ext_new_block(inode->i_sb);
280 if (!tmp) {
281 brelse(bh);
282 return NULL;
283 }
284 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
285 if (*p) {
286 ext_free_block(inode->i_sb,tmp);
287 brelse(result);
288 goto repeat;
289 }
290 *p = tmp;
291 bh->b_dirt = 1;
292 brelse(bh);
293 return result;
294 }
295
296 struct buffer_head * ext_getblk(struct inode * inode, int block, int create)
297 {
298 struct buffer_head * bh;
299
300 if (block<0) {
301 printk("ext_getblk: block<0\n");
302 return NULL;
303 }
304 if (block >= 9+256+256*256+256*256*256) {
305 printk("ext_getblk: block>big\n");
306 return NULL;
307 }
308 if (block<9)
309 return inode_getblk(inode,block,create);
310 block -= 9;
311 if (block<256) {
312 bh = inode_getblk(inode,9,create);
313 return block_getblk(inode,bh,block,create);
314 }
315 block -= 256;
316 if (block<256*256) {
317 bh = inode_getblk(inode,10,create);
318 bh = block_getblk(inode,bh,block>>8,create);
319 return block_getblk(inode,bh,block & 255,create);
320 }
321 block -= 256*256;
322 bh = inode_getblk(inode,11,create);
323 bh = block_getblk(inode,bh,block>>16,create);
324 bh = block_getblk(inode,bh,(block>>8) & 255,create);
325 return block_getblk(inode,bh,block & 255,create);
326 }
327
328 struct buffer_head * ext_bread(struct inode * inode, int block, int create)
329 {
330 struct buffer_head * bh;
331
332 bh = ext_getblk(inode,block,create);
333 if (!bh || bh->b_uptodate)
334 return bh;
335 ll_rw_block(READ,bh);
336 wait_on_buffer(bh);
337 if (bh->b_uptodate)
338 return bh;
339 brelse(bh);
340 return NULL;
341 }
342
343 void ext_read_inode(struct inode * inode)
344 {
345 struct buffer_head * bh;
346 struct ext_inode * raw_inode;
347 int block;
348
349 block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
350 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
351 panic("unable to read i-node block");
352 raw_inode = ((struct ext_inode *) bh->b_data) +
353 (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
354 inode->i_mode = raw_inode->i_mode;
355 inode->i_uid = raw_inode->i_uid;
356 inode->i_gid = raw_inode->i_gid;
357 inode->i_nlink = raw_inode->i_nlinks;
358 inode->i_size = raw_inode->i_size;
359 inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
360 inode->i_blocks = inode->i_blksize = 0;
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->u.ext_i.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_pipe = 1;
380 PIPE_BASE(*inode) = NULL;
381 PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
382 PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
383 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
384 }
385 }
386
387 void ext_write_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 bh->b_dirt=1;
409 inode->i_dirt=0;
410 brelse(bh);
411 }