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