This source file includes following definitions.
- xiafs_put_inode
- xiafs_put_super
- xiafs_read_super
- xiafs_statfs
- zone_bmap
- xiafs_bmap
- get_prev_addr
- dt_getblk
- indt_getblk
- xiafs_getblk
- xiafs_bread
- xiafs_read_inode
- xiafs_write_inode
1
2
3
4
5
6
7
8
9
10
11
12 #include <linux/sched.h>
13 #include <linux/xia_fs.h>
14 #include <linux/kernel.h>
15 #include <linux/mm.h>
16 #include <linux/string.h>
17 #include <linux/stat.h>
18 #include <linux/locks.h>
19 #include <asm/system.h>
20 #include <asm/segment.h>
21
22 #include "xiafs_mac.h"
23
24 static u_long random_nr;
25
26 void xiafs_put_inode(struct inode *inode)
27 {
28 if (inode->i_nlink)
29 return;
30 inode->i_size = 0;
31 xiafs_truncate(inode);
32 xiafs_free_inode(inode);
33 }
34
35 void xiafs_put_super(struct super_block *sb)
36 {
37 int i;
38
39 lock_super(sb);
40 sb->s_dev = 0;
41 for(i = 0 ; i < _XIAFS_IMAP_SLOTS ; i++)
42 brelse(sb->u.xiafs_sb.s_imap_buf[i]);
43 for(i = 0 ; i < _XIAFS_ZMAP_SLOTS ; i++)
44 brelse(sb->u.xiafs_sb.s_zmap_buf[i]);
45 unlock_super(sb);
46 }
47
48 static struct super_operations xiafs_sops = {
49 xiafs_read_inode,
50 NULL,
51 xiafs_write_inode,
52 xiafs_put_inode,
53 xiafs_put_super,
54 NULL,
55 xiafs_statfs
56 };
57
58 struct super_block *xiafs_read_super(struct super_block *s, void *data,
59 int silent)
60 {
61 struct buffer_head *bh;
62 struct xiafs_super_block *sp;
63 int i, z, dev;
64
65 dev=s->s_dev;
66 lock_super(s);
67 if (!(bh = bread(dev, 0, BLOCK_SIZE))) {
68 s->s_dev=0;
69 unlock_super(s);
70 printk("XIA-FS: read super_block failed (%s %d)\n", WHERE_ERR);
71 return NULL;
72 }
73 sp = (struct xiafs_super_block *) bh->b_data;
74 s->s_magic = sp->s_magic;
75 if (s->s_magic != _XIAFS_SUPER_MAGIC) {
76 s->s_dev = 0;
77 unlock_super(s);
78 brelse(bh);
79 if (!silent)
80 printk("VFS: Can't find a xiafs filesystem on dev 0x%04x.\n",
81 dev);
82 return NULL;
83 }
84 s->s_blocksize = sp->s_zone_size;
85 s->u.xiafs_sb.s_nzones = sp->s_nzones;
86 s->u.xiafs_sb.s_ninodes = sp->s_ninodes;
87 s->u.xiafs_sb.s_ndatazones = sp->s_ndatazones;
88 s->u.xiafs_sb.s_imap_zones = sp->s_imap_zones;
89 s->u.xiafs_sb.s_zmap_zones = sp->s_zmap_zones;
90 s->u.xiafs_sb.s_firstdatazone = sp->s_firstdatazone;
91 s->u.xiafs_sb.s_zone_shift = sp->s_zone_shift;
92 s->u.xiafs_sb.s_max_size = sp->s_max_size;
93 brelse(bh);
94 for (i=0;i < _XIAFS_IMAP_SLOTS;i++) {
95 s->u.xiafs_sb.s_imap_buf[i] = NULL;
96 s->u.xiafs_sb.s_imap_iznr[i] = -1;
97 }
98 for (i=0;i < _XIAFS_ZMAP_SLOTS;i++) {
99 s->u.xiafs_sb.s_zmap_buf[i] = NULL;
100 s->u.xiafs_sb.s_zmap_zznr[i] = -1;
101 }
102 z=1;
103 if ( s->u.xiafs_sb.s_imap_zones > _XIAFS_IMAP_SLOTS )
104 s->u.xiafs_sb.s_imap_cached=1;
105 else {
106 s->u.xiafs_sb.s_imap_cached=0;
107 for (i=0 ; i < s->u.xiafs_sb.s_imap_zones ; i++) {
108 if (!(s->u.xiafs_sb.s_imap_buf[i]=bread(dev, z++, XIAFS_ZSIZE(s))))
109 goto xiafs_read_super_fail;
110 s->u.xiafs_sb.s_imap_iznr[i]=i;
111 }
112 }
113 if ( s->u.xiafs_sb.s_zmap_zones > _XIAFS_ZMAP_SLOTS )
114 s->u.xiafs_sb.s_zmap_cached=1;
115 else {
116 s->u.xiafs_sb.s_zmap_cached=0;
117 for (i=0 ; i < s->u.xiafs_sb.s_zmap_zones ; i++) {
118 if (!(s->u.xiafs_sb.s_zmap_buf[i]=bread(dev, z++, XIAFS_ZSIZE(s))))
119 goto xiafs_read_super_fail;
120 s->u.xiafs_sb.s_zmap_zznr[i]=i;
121 }
122 }
123
124 s->s_dev = dev;
125 s->s_op = &xiafs_sops;
126 s->s_mounted = iget(s, _XIAFS_ROOT_INO);
127 if (!s->s_mounted)
128 goto xiafs_read_super_fail;
129 unlock_super(s);
130 random_nr=CURRENT_TIME;
131 return s;
132
133 xiafs_read_super_fail:
134 for(i=0; i < _XIAFS_IMAP_SLOTS; i++)
135 brelse(s->u.xiafs_sb.s_imap_buf[i]);
136 for(i=0; i < _XIAFS_ZMAP_SLOTS; i++)
137 brelse(s->u.xiafs_sb.s_zmap_buf[i]);
138 s->s_dev=0;
139 unlock_super(s);
140 printk("XIA-FS: read bitmaps failed (%s %d)\n", WHERE_ERR);
141 return NULL;
142 }
143
144 void xiafs_statfs(struct super_block *sb, struct statfs *buf)
145 {
146 long tmp;
147
148 put_fs_long(_XIAFS_SUPER_MAGIC, &buf->f_type);
149 put_fs_long(XIAFS_ZSIZE(sb), &buf->f_bsize);
150 put_fs_long(sb->u.xiafs_sb.s_ndatazones, &buf->f_blocks);
151 tmp = xiafs_count_free_zones(sb);
152 put_fs_long(tmp, &buf->f_bfree);
153 put_fs_long(tmp, &buf->f_bavail);
154 put_fs_long(sb->u.xiafs_sb.s_ninodes, &buf->f_files);
155 put_fs_long(xiafs_count_free_inodes(sb), &buf->f_ffree);
156 put_fs_long(_XIAFS_NAME_LEN, &buf->f_namelen);
157
158 }
159
160 static int zone_bmap(struct buffer_head * bh, int nr)
161 {
162 int tmp;
163
164 if (!bh)
165 return 0;
166 tmp = ((u_long *) bh->b_data)[nr];
167 brelse(bh);
168 return tmp;
169 }
170
171 int xiafs_bmap(struct inode * inode,int zone)
172 {
173 int i;
174
175 if (zone < 0) {
176 printk("XIA-FS: block < 0 (%s %d)\n", WHERE_ERR);
177 return 0;
178 }
179 if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) {
180 printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR);
181 return 0;
182 }
183 if (!IS_RDONLY (inode)) {
184 inode->i_atime = CURRENT_TIME;
185 inode->i_dirt = 1;
186 }
187 if (zone < 8)
188 return inode->u.xiafs_i.i_zone[zone];
189 zone -= 8;
190 if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) {
191 i = inode->u.xiafs_i.i_ind_zone;
192 if (i)
193 i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)), zone);
194 return i;
195 }
196 zone -= XIAFS_ADDRS_PER_Z(inode->i_sb);
197 i = inode->u.xiafs_i.i_dind_zone;
198 if (i)
199 i = zone_bmap(bread(inode->i_dev, i, XIAFS_ZSIZE(inode->i_sb)),
200 zone >> XIAFS_ADDRS_PER_Z_BITS(inode->i_sb));
201 if (i)
202 i= zone_bmap(bread(inode->i_dev,i, XIAFS_ZSIZE(inode->i_sb)),
203 zone & (XIAFS_ADDRS_PER_Z(inode->i_sb)-1));
204 return i;
205 }
206
207 static u_long get_prev_addr(struct inode * inode, int zone)
208 {
209 u_long tmp;
210
211 if (zone > 0)
212 while (--zone >= 0)
213 if ((tmp=xiafs_bmap(inode, zone)))
214 return tmp;
215 random_nr=(random_nr+23)%inode->i_sb->u.xiafs_sb.s_ndatazones;
216 return random_nr + inode->i_sb->u.xiafs_sb.s_firstdatazone;
217 }
218
219 static struct buffer_head *
220 dt_getblk(struct inode * inode, u_long *lp, int create, u_long prev_addr)
221 {
222 int tmp;
223 struct buffer_head * result;
224
225 repeat:
226 if ((tmp=*lp)) {
227 result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
228 if (tmp == *lp)
229 return result;
230 brelse(result);
231 goto repeat;
232 }
233 if (!create)
234 return NULL;
235 tmp = xiafs_new_zone(inode->i_sb, prev_addr);
236 if (!tmp)
237 return NULL;
238 result = getblk(inode->i_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
239 if (*lp) {
240 xiafs_free_zone(inode->i_sb, tmp);
241 brelse(result);
242 goto repeat;
243 }
244 *lp = tmp;
245 inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
246 return result;
247 }
248
249 static struct buffer_head *
250 indt_getblk(struct inode * inode, struct buffer_head * bh,
251 int nr, int create, u_long prev_addr)
252 {
253 int tmp;
254 u_long *lp;
255 struct buffer_head * result;
256
257 if (!bh)
258 return NULL;
259 if (!bh->b_uptodate) {
260 ll_rw_block(READ, 1, &bh);
261 wait_on_buffer(bh);
262 if (!bh->b_uptodate) {
263 brelse(bh);
264 return NULL;
265 }
266 }
267 lp = nr + (u_long *) bh->b_data;
268 repeat:
269 if ((tmp=*lp)) {
270 result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
271 if (tmp == *lp) {
272 brelse(bh);
273 return result;
274 }
275 brelse(result);
276 goto repeat;
277 }
278 if (!create) {
279 brelse(bh);
280 return NULL;
281 }
282 tmp = xiafs_new_zone(inode->i_sb, prev_addr);
283 if (!tmp) {
284 brelse(bh);
285 return NULL;
286 }
287 result = getblk(bh->b_dev, tmp, XIAFS_ZSIZE(inode->i_sb));
288 if (*lp) {
289 xiafs_free_zone(inode->i_sb, tmp);
290 brelse(result);
291 goto repeat;
292 }
293 *lp = tmp;
294 inode->i_blocks+=2 << XIAFS_ZSHIFT(inode->i_sb);
295 bh->b_dirt = 1;
296 brelse(bh);
297 return result;
298 }
299
300 struct buffer_head * xiafs_getblk(struct inode * inode, int zone, int create)
301 {
302 struct buffer_head * bh;
303 u_long prev_addr=0;
304
305 if (zone<0) {
306 printk("XIA-FS: zone < 0 (%s %d)\n", WHERE_ERR);
307 return NULL;
308 }
309 if (zone >= 8+(1+XIAFS_ADDRS_PER_Z(inode->i_sb))*XIAFS_ADDRS_PER_Z(inode->i_sb)) {
310 if (!create)
311 printk("XIA-FS: zone > big (%s %d)\n", WHERE_ERR);
312 return NULL;
313 }
314 if (create)
315 prev_addr=get_prev_addr(inode, zone);
316 if (zone < 8)
317 return dt_getblk(inode, zone+inode->u.xiafs_i.i_zone, create, prev_addr);
318 zone -= 8;
319 if (zone < XIAFS_ADDRS_PER_Z(inode->i_sb)) {
320 bh = dt_getblk(inode, &(inode->u.xiafs_i.i_ind_zone), create, prev_addr);
321 bh = indt_getblk(inode, bh, zone, create, prev_addr);
322 return bh;
323 }
324 zone -= XIAFS_ADDRS_PER_Z(inode->i_sb);
325 bh = dt_getblk(inode, &(inode->u.xiafs_i.i_dind_zone), create, prev_addr);
326 bh = indt_getblk(inode, bh, zone>>XIAFS_ADDRS_PER_Z_BITS(inode->i_sb),
327 create, prev_addr);
328 bh = indt_getblk(inode, bh, zone&(XIAFS_ADDRS_PER_Z(inode->i_sb)-1),
329 create, prev_addr);
330 return bh;
331 }
332
333 struct buffer_head * xiafs_bread(struct inode * inode, int zone, int create)
334 {
335 struct buffer_head * bh;
336
337 bh = xiafs_getblk(inode, zone, create);
338 if (!bh || bh->b_uptodate)
339 return bh;
340 ll_rw_block(READ, 1, &bh);
341 wait_on_buffer(bh);
342 if (bh->b_uptodate)
343 return bh;
344 brelse(bh);
345 return NULL;
346 }
347
348 void xiafs_read_inode(struct inode * inode)
349 {
350 struct buffer_head * bh;
351 struct xiafs_inode * raw_inode;
352 int zone;
353 ino_t ino;
354
355 ino = inode->i_ino;
356 inode->i_op = NULL;
357 inode->i_mode=0;
358 if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
359 printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR);
360 return;
361 }
362 zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones +
363 inode->i_sb->u.xiafs_sb.s_zmap_zones +
364 (ino-1)/ XIAFS_INODES_PER_Z(inode->i_sb);
365 if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) {
366 printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR);
367 return;
368 }
369 raw_inode = ((struct xiafs_inode *) bh->b_data) +
370 ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) - 1));
371 inode->i_mode = raw_inode->i_mode;
372 inode->i_uid = raw_inode->i_uid;
373 inode->i_gid = raw_inode->i_gid;
374 inode->i_nlink = raw_inode->i_nlinks;
375 inode->i_size = raw_inode->i_size;
376 inode->i_mtime = raw_inode->i_mtime;
377 inode->i_atime = raw_inode->i_atime;
378 inode->i_ctime = raw_inode->i_ctime;
379 inode->i_blksize = XIAFS_ZSIZE(inode->i_sb);
380 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode)) {
381 inode->i_blocks=0;
382 inode->i_rdev = raw_inode->i_zone[0];
383 } else {
384 XIAFS_GET_BLOCKS(raw_inode, inode->i_blocks);
385 for (zone = 0; zone < 8; zone++)
386 inode->u.xiafs_i.i_zone[zone] = raw_inode->i_zone[zone] & 0xffffff;
387 inode->u.xiafs_i.i_ind_zone = raw_inode->i_ind_zone & 0xffffff;
388 inode->u.xiafs_i.i_dind_zone = raw_inode->i_dind_zone & 0xffffff;
389 }
390 brelse(bh);
391 if (S_ISREG(inode->i_mode))
392 inode->i_op = &xiafs_file_inode_operations;
393 else if (S_ISDIR(inode->i_mode))
394 inode->i_op = &xiafs_dir_inode_operations;
395 else if (S_ISLNK(inode->i_mode))
396 inode->i_op = &xiafs_symlink_inode_operations;
397 else if (S_ISCHR(inode->i_mode))
398 inode->i_op = &chrdev_inode_operations;
399 else if (S_ISBLK(inode->i_mode))
400 inode->i_op = &blkdev_inode_operations;
401 else if (S_ISFIFO(inode->i_mode))
402 init_fifo(inode);
403 }
404
405 void xiafs_write_inode(struct inode * inode)
406 {
407 struct buffer_head * bh;
408 struct xiafs_inode * raw_inode;
409 int zone;
410 ino_t ino;
411
412 if (IS_RDONLY (inode)) {
413 printk("XIA-FS: write_inode on a read-only filesystem (%s %d)\n", WHERE_ERR);
414 inode->i_dirt = 0;
415 return;
416 }
417
418 ino = inode->i_ino;
419 if (!ino || ino > inode->i_sb->u.xiafs_sb.s_ninodes) {
420 printk("XIA-FS: bad inode number (%s %d)\n", WHERE_ERR);
421 inode->i_dirt=0;
422 return;
423 }
424 zone = 1 + inode->i_sb->u.xiafs_sb.s_imap_zones +
425 inode->i_sb->u.xiafs_sb.s_zmap_zones +
426 (ino-1) / XIAFS_INODES_PER_Z(inode->i_sb);
427 if (!(bh=bread(inode->i_dev, zone, XIAFS_ZSIZE(inode->i_sb)))) {
428 printk("XIA-FS: read i-node zone failed (%s %d)\n", WHERE_ERR);
429 inode->i_dirt=0;
430 return;
431 }
432 raw_inode = ((struct xiafs_inode *)bh->b_data) +
433 ((ino-1) & (XIAFS_INODES_PER_Z(inode->i_sb) -1));
434 raw_inode->i_mode = inode->i_mode;
435 raw_inode->i_uid = inode->i_uid;
436 raw_inode->i_gid = inode->i_gid;
437 raw_inode->i_nlinks = inode->i_nlink;
438 raw_inode->i_size = inode->i_size;
439 raw_inode->i_atime = inode->i_atime;
440 raw_inode->i_ctime = inode->i_ctime;
441 raw_inode->i_mtime = inode->i_mtime;
442 if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode))
443 raw_inode->i_zone[0] = inode->i_rdev;
444 else {
445 XIAFS_PUT_BLOCKS(raw_inode, inode->i_blocks);
446 for (zone = 0; zone < 8; zone++)
447 raw_inode->i_zone[zone] = (raw_inode->i_zone[zone] & 0xff000000)
448 | (inode->u.xiafs_i.i_zone[zone] & 0xffffff);
449 raw_inode->i_ind_zone = (raw_inode->i_ind_zone & 0xff000000)
450 | (inode->u.xiafs_i.i_ind_zone & 0xffffff);
451 raw_inode->i_dind_zone = (raw_inode->i_dind_zone & 0xff000000)
452 | (inode->u.xiafs_i.i_dind_zone & 0xffffff);
453 }
454 inode->i_dirt=0;
455 bh->b_dirt=1;
456 brelse(bh);
457 }
458
459