This source file includes following definitions.
- wait_on_buffer
- 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
20 #include <asm/system.h>
21 #include <asm/segment.h>
22
23 int sync_dev(int dev);
24
25 static inline void wait_on_buffer(struct buffer_head * bh)
26 {
27 cli();
28 while (bh->b_lock)
29 sleep_on(&bh->b_wait);
30 sti();
31 }
32
33 void ext_put_inode(struct inode *inode)
34 {
35 inode->i_size = 0;
36 ext_truncate(inode);
37 ext_free_inode(inode);
38 }
39
40 void ext_put_super(struct super_block *sb)
41 {
42
43 lock_super(sb);
44 sb->s_dev = 0;
45 if (sb->u.ext_sb.s_firstfreeinodeblock)
46 brelse (sb->u.ext_sb.s_firstfreeinodeblock);
47 if (sb->u.ext_sb.s_firstfreeblock)
48 brelse (sb->u.ext_sb.s_firstfreeblock);
49 free_super(sb);
50 return;
51 }
52
53 static struct super_operations ext_sops = {
54 ext_read_inode,
55 ext_write_inode,
56 ext_put_inode,
57 ext_put_super,
58 ext_write_super,
59 ext_statfs
60 };
61
62 struct super_block *ext_read_super(struct super_block *s,void *data)
63 {
64 struct buffer_head *bh;
65 struct ext_super_block *es;
66 int dev = s->s_dev,block;
67
68 lock_super(s);
69 if (!(bh = bread(dev, 1, BLOCK_SIZE))) {
70 s->s_dev=0;
71 free_super(s);
72 printk("bread failed\n");
73 return NULL;
74 }
75 es = (struct ext_super_block *) bh->b_data;
76 s->s_blocksize = 1024;
77 s->u.ext_sb.s_ninodes = es->s_ninodes;
78 s->u.ext_sb.s_nzones = es->s_nzones;
79 s->u.ext_sb.s_firstdatazone = es->s_firstdatazone;
80 s->u.ext_sb.s_log_zone_size = es->s_log_zone_size;
81 s->u.ext_sb.s_max_size = es->s_max_size;
82 s->s_magic = es->s_magic;
83 s->u.ext_sb.s_firstfreeblocknumber = es->s_firstfreeblock;
84 s->u.ext_sb.s_freeblockscount = es->s_freeblockscount;
85 s->u.ext_sb.s_firstfreeinodenumber = es->s_firstfreeinode;
86 s->u.ext_sb.s_freeinodescount = es->s_freeinodescount;
87 brelse(bh);
88 if (s->s_magic != EXT_SUPER_MAGIC) {
89 s->s_dev = 0;
90 free_super(s);
91 printk("magic match failed\n");
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 free_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 free_super (s);
113 return NULL;
114 }
115 }
116 free_super(s);
117
118 s->s_dev = dev;
119 s->s_op = &ext_sops;
120 if (!(s->s_mounted = iget(dev,EXT_ROOT_INO))) {
121 s->s_dev=0;
122 printk("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 bh->b_dirt = 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
161 }
162
163 #define inode_bmap(inode,nr) ((inode)->u.ext_i.i_data[(nr)])
164
165 static int block_bmap(struct buffer_head * bh, int nr)
166 {
167 int tmp;
168
169 if (!bh)
170 return 0;
171 tmp = ((unsigned long *) bh->b_data)[nr];
172 brelse(bh);
173 return tmp;
174 }
175
176 int ext_bmap(struct inode * inode,int block)
177 {
178 int i;
179
180 if (block<0) {
181 printk("ext_bmap: block<0");
182 return 0;
183 }
184 if (block >= 9+256+256*256+256*256*256) {
185 printk("ext_bmap: block>big");
186 return 0;
187 }
188 if (block<9)
189 return inode_bmap(inode,block);
190 block -= 9;
191 if (block<256) {
192 i = inode_bmap(inode,9);
193 if (!i)
194 return 0;
195 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
196 }
197 block -= 256;
198 if (block<256*256) {
199 i = inode_bmap(inode,10);
200 if (!i)
201 return 0;
202 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>8);
203 if (!i)
204 return 0;
205 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
206 }
207 block -= 256*256;
208 i = inode_bmap(inode,11);
209 if (!i)
210 return 0;
211 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>16);
212 if (!i)
213 return 0;
214 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),(block>>8) & 255);
215 if (!i)
216 return 0;
217 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 255);
218 }
219
220 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
221 {
222 int tmp;
223 unsigned long * p;
224 struct buffer_head * result;
225
226 p = inode->u.ext_i.i_data + nr;
227 repeat:
228 tmp = *p;
229 if (tmp) {
230 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
231 if (tmp == *p)
232 return result;
233 brelse(result);
234 goto repeat;
235 }
236 if (!create)
237 return NULL;
238 tmp = ext_new_block(inode->i_dev);
239 if (!tmp)
240 return NULL;
241 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
242 if (*p) {
243 ext_free_block(inode->i_dev,tmp);
244 brelse(result);
245 goto repeat;
246 }
247 *p = tmp;
248 inode->i_ctime = CURRENT_TIME;
249 inode->i_dirt = 1;
250 return result;
251 }
252
253 static struct buffer_head * block_getblk(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,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(bh->b_dev);
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(bh->b_dev,tmp);
293 brelse(result);
294 goto repeat;
295 }
296 *p = tmp;
297 bh->b_dirt = 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(bh,block,create);
320 }
321 block -= 256;
322 if (block<256*256) {
323 bh = inode_getblk(inode,10,create);
324 bh = block_getblk(bh,block>>8,create);
325 return block_getblk(bh,block & 255,create);
326 }
327 block -= 256*256;
328 bh = inode_getblk(inode,11,create);
329 bh = block_getblk(bh,block>>16,create);
330 bh = block_getblk(bh,(block>>8) & 255,create);
331 return block_getblk(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,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 = &ext_chrdev_inode_operations;
381 else if (S_ISBLK(inode->i_mode))
382 inode->i_op = &ext_blkdev_inode_operations;
383 else if (S_ISFIFO(inode->i_mode)) {
384 inode->i_op = &ext_fifo_inode_operations;
385 inode->i_pipe = 1;
386 PIPE_BASE(*inode) = NULL;
387 PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
388 PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
389 PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 0;
390 }
391 }
392
393 void ext_write_inode(struct inode * inode)
394 {
395 struct buffer_head * bh;
396 struct ext_inode * raw_inode;
397 int block;
398
399 block = 2 + (inode->i_ino-1)/EXT_INODES_PER_BLOCK;
400 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE)))
401 panic("unable to read i-node block");
402 raw_inode = ((struct ext_inode *)bh->b_data) +
403 (inode->i_ino-1)%EXT_INODES_PER_BLOCK;
404 raw_inode->i_mode = inode->i_mode;
405 raw_inode->i_uid = inode->i_uid;
406 raw_inode->i_gid = inode->i_gid;
407 raw_inode->i_nlinks = inode->i_nlink;
408 raw_inode->i_size = inode->i_size;
409 raw_inode->i_time = inode->i_mtime;
410 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
411 raw_inode->i_zone[0] = inode->i_rdev;
412 else for (block = 0; block < 12; block++)
413 raw_inode->i_zone[block] = inode->u.ext_i.i_data[block];
414 bh->b_dirt=1;
415 inode->i_dirt=0;
416 brelse(bh);
417 }