This source file includes following definitions.
- minix_put_inode
- minix_put_super
- minix_read_super
- minix_statfs
- block_bmap
- minix_bmap
- inode_getblk
- block_getblk
- minix_getblk
- minix_bread
- minix_read_inode
- minix_update_inode
- minix_write_inode
- minix_sync_inode
1
2
3
4
5
6
7 #include <linux/sched.h>
8 #include <linux/minix_fs.h>
9 #include <linux/kernel.h>
10 #include <linux/mm.h>
11 #include <linux/string.h>
12 #include <linux/stat.h>
13 #include <linux/locks.h>
14
15 #include <asm/system.h>
16 #include <asm/segment.h>
17
18 void minix_put_inode(struct inode *inode)
19 {
20 if (inode->i_nlink)
21 return;
22 inode->i_size = 0;
23 minix_truncate(inode);
24 minix_free_inode(inode);
25 }
26
27 void minix_put_super(struct super_block *sb)
28 {
29 int i;
30
31 lock_super(sb);
32 sb->s_dev = 0;
33 for(i = 0 ; i < MINIX_I_MAP_SLOTS ; i++)
34 brelse(sb->u.minix_sb.s_imap[i]);
35 for(i = 0 ; i < MINIX_Z_MAP_SLOTS ; i++)
36 brelse(sb->u.minix_sb.s_zmap[i]);
37 unlock_super(sb);
38 return;
39 }
40
41 static struct super_operations minix_sops = {
42 minix_read_inode,
43 NULL,
44 minix_write_inode,
45 minix_put_inode,
46 minix_put_super,
47 NULL,
48 minix_statfs,
49 NULL
50 };
51
52 struct super_block *minix_read_super(struct super_block *s,void *data,
53 int silent)
54 {
55 struct buffer_head *bh;
56 struct minix_super_block *ms;
57 int i,dev=s->s_dev,block;
58
59 if (32 != sizeof (struct minix_inode))
60 panic("bad i-node size");
61 lock_super(s);
62 if (!(bh = bread(dev,1,BLOCK_SIZE))) {
63 s->s_dev=0;
64 unlock_super(s);
65 printk("MINIX-fs: unable to read superblock\n");
66 return NULL;
67 }
68 ms = (struct minix_super_block *) bh->b_data;
69 s->s_blocksize = 1024;
70 s->u.minix_sb.s_ninodes = ms->s_ninodes;
71 s->u.minix_sb.s_nzones = ms->s_nzones;
72 s->u.minix_sb.s_imap_blocks = ms->s_imap_blocks;
73 s->u.minix_sb.s_zmap_blocks = ms->s_zmap_blocks;
74 s->u.minix_sb.s_firstdatazone = ms->s_firstdatazone;
75 s->u.minix_sb.s_log_zone_size = ms->s_log_zone_size;
76 s->u.minix_sb.s_max_size = ms->s_max_size;
77 s->s_magic = ms->s_magic;
78 brelse(bh);
79 if (s->s_magic == MINIX_SUPER_MAGIC) {
80 s->u.minix_sb.s_dirsize = 16;
81 s->u.minix_sb.s_namelen = 14;
82 } else if (s->s_magic == MINIX_SUPER_MAGIC2) {
83 s->u.minix_sb.s_dirsize = 32;
84 s->u.minix_sb.s_namelen = 30;
85 } else {
86 s->s_dev = 0;
87 unlock_super(s);
88 if (!silent)
89 printk("VFS: Can't find a minix filesystem on dev 0x%04x.\n",
90 dev);
91 return NULL;
92 }
93 for (i=0;i < MINIX_I_MAP_SLOTS;i++)
94 s->u.minix_sb.s_imap[i] = NULL;
95 for (i=0;i < MINIX_Z_MAP_SLOTS;i++)
96 s->u.minix_sb.s_zmap[i] = NULL;
97 block=2;
98 for (i=0 ; i < s->u.minix_sb.s_imap_blocks ; i++)
99 if ((s->u.minix_sb.s_imap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
100 block++;
101 else
102 break;
103 for (i=0 ; i < s->u.minix_sb.s_zmap_blocks ; i++)
104 if ((s->u.minix_sb.s_zmap[i]=bread(dev,block,BLOCK_SIZE)) != NULL)
105 block++;
106 else
107 break;
108 if (block != 2+s->u.minix_sb.s_imap_blocks+s->u.minix_sb.s_zmap_blocks) {
109 for(i=0;i<MINIX_I_MAP_SLOTS;i++)
110 brelse(s->u.minix_sb.s_imap[i]);
111 for(i=0;i<MINIX_Z_MAP_SLOTS;i++)
112 brelse(s->u.minix_sb.s_zmap[i]);
113 s->s_dev=0;
114 unlock_super(s);
115 printk("MINIX-fs: bad superblock or unable to read bitmaps\n");
116 return NULL;
117 }
118 s->u.minix_sb.s_imap[0]->b_data[0] |= 1;
119 s->u.minix_sb.s_zmap[0]->b_data[0] |= 1;
120
121 s->s_dev = dev;
122 s->s_op = &minix_sops;
123 s->s_mounted = iget(s,MINIX_ROOT_INO);
124 unlock_super(s);
125 if (!s->s_mounted) {
126 s->s_dev = 0;
127 printk("MINIX-fs: get root inode failed\n");
128 return NULL;
129 }
130 return s;
131 }
132
133 void minix_statfs(struct super_block *sb, struct statfs *buf)
134 {
135 long tmp;
136
137 put_fs_long(MINIX_SUPER_MAGIC, &buf->f_type);
138 put_fs_long(1024, &buf->f_bsize);
139 put_fs_long(sb->u.minix_sb.s_nzones << sb->u.minix_sb.s_log_zone_size, &buf->f_blocks);
140 tmp = minix_count_free_blocks(sb);
141 put_fs_long(tmp, &buf->f_bfree);
142 put_fs_long(tmp, &buf->f_bavail);
143 put_fs_long(sb->u.minix_sb.s_ninodes, &buf->f_files);
144 put_fs_long(minix_count_free_inodes(sb), &buf->f_ffree);
145 put_fs_long(sb->u.minix_sb.s_namelen, &buf->f_namelen);
146
147 }
148
149 #define inode_bmap(inode,nr) ((inode)->u.minix_i.i_data[(nr)])
150
151 static int block_bmap(struct buffer_head * bh, int nr)
152 {
153 int tmp;
154
155 if (!bh)
156 return 0;
157 tmp = ((unsigned short *) bh->b_data)[nr];
158 brelse(bh);
159 return tmp;
160 }
161
162 int minix_bmap(struct inode * inode,int block)
163 {
164 int i;
165
166 if (block<0) {
167 printk("minix_bmap: block<0");
168 return 0;
169 }
170 if (block >= 7+512+512*512) {
171 printk("minix_bmap: block>big");
172 return 0;
173 }
174 if (block < 7)
175 return inode_bmap(inode,block);
176 block -= 7;
177 if (block < 512) {
178 i = inode_bmap(inode,7);
179 if (!i)
180 return 0;
181 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block);
182 }
183 block -= 512;
184 i = inode_bmap(inode,8);
185 if (!i)
186 return 0;
187 i = block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block>>9);
188 if (!i)
189 return 0;
190 return block_bmap(bread(inode->i_dev,i,BLOCK_SIZE),block & 511);
191 }
192
193 static struct buffer_head * inode_getblk(struct inode * inode, int nr, int create)
194 {
195 int tmp;
196 unsigned short *p;
197 struct buffer_head * result;
198
199 p = inode->u.minix_i.i_data + nr;
200 repeat:
201 tmp = *p;
202 if (tmp) {
203 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
204 if (tmp == *p)
205 return result;
206 brelse(result);
207 goto repeat;
208 }
209 if (!create)
210 return NULL;
211 tmp = minix_new_block(inode->i_sb);
212 if (!tmp)
213 return NULL;
214 result = getblk(inode->i_dev, tmp, BLOCK_SIZE);
215 if (*p) {
216 minix_free_block(inode->i_sb,tmp);
217 brelse(result);
218 goto repeat;
219 }
220 *p = tmp;
221 inode->i_ctime = CURRENT_TIME;
222 inode->i_dirt = 1;
223 return result;
224 }
225
226 static struct buffer_head * block_getblk(struct inode * inode,
227 struct buffer_head * bh, int nr, int create)
228 {
229 int tmp;
230 unsigned short *p;
231 struct buffer_head * result;
232
233 if (!bh)
234 return NULL;
235 if (!bh->b_uptodate) {
236 ll_rw_block(READ, 1, &bh);
237 wait_on_buffer(bh);
238 if (!bh->b_uptodate) {
239 brelse(bh);
240 return NULL;
241 }
242 }
243 p = nr + (unsigned short *) bh->b_data;
244 repeat:
245 tmp = *p;
246 if (tmp) {
247 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
248 if (tmp == *p) {
249 brelse(bh);
250 return result;
251 }
252 brelse(result);
253 goto repeat;
254 }
255 if (!create) {
256 brelse(bh);
257 return NULL;
258 }
259 tmp = minix_new_block(inode->i_sb);
260 if (!tmp) {
261 brelse(bh);
262 return NULL;
263 }
264 result = getblk(bh->b_dev, tmp, BLOCK_SIZE);
265 if (*p) {
266 minix_free_block(inode->i_sb,tmp);
267 brelse(result);
268 goto repeat;
269 }
270 *p = tmp;
271 bh->b_dirt = 1;
272 brelse(bh);
273 return result;
274 }
275
276 struct buffer_head * minix_getblk(struct inode * inode, int block, int create)
277 {
278 struct buffer_head * bh;
279
280 if (block<0) {
281 printk("minix_getblk: block<0");
282 return NULL;
283 }
284 if (block >= 7+512+512*512) {
285 printk("minix_getblk: block>big");
286 return NULL;
287 }
288 if (block < 7)
289 return inode_getblk(inode,block,create);
290 block -= 7;
291 if (block < 512) {
292 bh = inode_getblk(inode,7,create);
293 return block_getblk(inode, bh, block, create);
294 }
295 block -= 512;
296 bh = inode_getblk(inode,8,create);
297 bh = block_getblk(inode, bh, block>>9, create);
298 return block_getblk(inode, bh, block & 511, create);
299 }
300
301 struct buffer_head * minix_bread(struct inode * inode, int block, int create)
302 {
303 struct buffer_head * bh;
304
305 bh = minix_getblk(inode,block,create);
306 if (!bh || bh->b_uptodate)
307 return bh;
308 ll_rw_block(READ, 1, &bh);
309 wait_on_buffer(bh);
310 if (bh->b_uptodate)
311 return bh;
312 brelse(bh);
313 return NULL;
314 }
315
316 void minix_read_inode(struct inode * inode)
317 {
318 struct buffer_head * bh;
319 struct minix_inode * raw_inode;
320 int block, ino;
321
322 ino = inode->i_ino;
323 inode->i_op = NULL;
324 inode->i_mode = 0;
325 if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
326 printk("Bad inode number on dev 0x%04x: %d is out of range\n",
327 inode->i_dev, ino);
328 return;
329 }
330 block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks +
331 inode->i_sb->u.minix_sb.s_zmap_blocks +
332 (ino-1)/MINIX_INODES_PER_BLOCK;
333 if (!(bh=bread(inode->i_dev,block, BLOCK_SIZE))) {
334 printk("Major problem: unable to read inode from dev 0x%04x\n",
335 inode->i_dev);
336 return;
337 }
338 raw_inode = ((struct minix_inode *) bh->b_data) +
339 (ino-1)%MINIX_INODES_PER_BLOCK;
340 inode->i_mode = raw_inode->i_mode;
341 inode->i_uid = raw_inode->i_uid;
342 inode->i_gid = raw_inode->i_gid;
343 inode->i_nlink = raw_inode->i_nlinks;
344 inode->i_size = raw_inode->i_size;
345 inode->i_mtime = inode->i_atime = inode->i_ctime = raw_inode->i_time;
346 inode->i_blocks = inode->i_blksize = 0;
347 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
348 inode->i_rdev = raw_inode->i_zone[0];
349 else for (block = 0; block < 9; block++)
350 inode->u.minix_i.i_data[block] = raw_inode->i_zone[block];
351 brelse(bh);
352 if (S_ISREG(inode->i_mode))
353 inode->i_op = &minix_file_inode_operations;
354 else if (S_ISDIR(inode->i_mode))
355 inode->i_op = &minix_dir_inode_operations;
356 else if (S_ISLNK(inode->i_mode))
357 inode->i_op = &minix_symlink_inode_operations;
358 else if (S_ISCHR(inode->i_mode))
359 inode->i_op = &chrdev_inode_operations;
360 else if (S_ISBLK(inode->i_mode))
361 inode->i_op = &blkdev_inode_operations;
362 else if (S_ISFIFO(inode->i_mode))
363 init_fifo(inode);
364 }
365
366 static struct buffer_head * minix_update_inode(struct inode * inode)
367 {
368 struct buffer_head * bh;
369 struct minix_inode * raw_inode;
370 int ino, block;
371
372 ino = inode->i_ino;
373 if (!ino || ino >= inode->i_sb->u.minix_sb.s_ninodes) {
374 printk("Bad inode number on dev 0x%04x: %d is out of range\n",
375 inode->i_dev, ino);
376 inode->i_dirt = 0;
377 return 0;
378 }
379 block = 2 + inode->i_sb->u.minix_sb.s_imap_blocks + inode->i_sb->u.minix_sb.s_zmap_blocks +
380 (ino-1)/MINIX_INODES_PER_BLOCK;
381 if (!(bh=bread(inode->i_dev, block, BLOCK_SIZE))) {
382 printk("unable to read i-node block\n");
383 inode->i_dirt = 0;
384 return 0;
385 }
386 raw_inode = ((struct minix_inode *)bh->b_data) +
387 (ino-1)%MINIX_INODES_PER_BLOCK;
388 raw_inode->i_mode = inode->i_mode;
389 raw_inode->i_uid = inode->i_uid;
390 raw_inode->i_gid = inode->i_gid;
391 raw_inode->i_nlinks = inode->i_nlink;
392 raw_inode->i_size = inode->i_size;
393 raw_inode->i_time = inode->i_mtime;
394 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
395 raw_inode->i_zone[0] = inode->i_rdev;
396 else for (block = 0; block < 9; block++)
397 raw_inode->i_zone[block] = inode->u.minix_i.i_data[block];
398 inode->i_dirt=0;
399 bh->b_dirt=1;
400 return bh;
401 }
402
403 void minix_write_inode(struct inode * inode)
404 {
405 struct buffer_head *bh;
406 bh = minix_update_inode(inode);
407 brelse(bh);
408 }
409
410 int minix_sync_inode(struct inode * inode)
411 {
412 int err = 0;
413 struct buffer_head *bh;
414
415 bh = minix_update_inode(inode);
416 if (bh && bh->b_dirt)
417 {
418 ll_rw_block(WRITE, 1, &bh);
419 wait_on_buffer(bh);
420 if (bh->b_req && !bh->b_uptodate)
421 {
422 printk ("IO error syncing minix inode [%04x:%08x]\n",
423 inode->i_dev, inode->i_ino);
424 err = -1;
425 }
426 }
427 else if (!bh)
428 err = -1;
429 brelse (bh);
430 return err;
431 }