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