3 * BFS superblock and inode operations.
4 * Copyright (C) 1999-2006 Tigran Aivazian <tigran@aivazian.fsnet.co.uk>
5 * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
7 * Made endianness-clean by Andrew Stribblehill <ads@wompom.org>, 2005.
10 #include <linux/module.h>
12 #include <linux/slab.h>
13 #include <linux/init.h>
15 #include <linux/smp_lock.h>
16 #include <linux/buffer_head.h>
17 #include <linux/vfs.h>
18 #include <asm/uaccess.h>
21 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
22 MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux");
23 MODULE_LICENSE("GPL");
28 #define dprintf(x...) printf(x)
33 void dump_imap(const char *prefix
, struct super_block
* s
);
35 static void bfs_read_inode(struct inode
* inode
)
37 unsigned long ino
= inode
->i_ino
;
38 struct bfs_inode
* di
;
39 struct buffer_head
* bh
;
42 if (ino
< BFS_ROOT_INO
|| ino
> BFS_SB(inode
->i_sb
)->si_lasti
) {
43 printf("Bad inode number %s:%08lx\n", inode
->i_sb
->s_id
, ino
);
44 make_bad_inode(inode
);
48 block
= (ino
- BFS_ROOT_INO
)/BFS_INODES_PER_BLOCK
+ 1;
49 bh
= sb_bread(inode
->i_sb
, block
);
51 printf("Unable to read inode %s:%08lx\n", inode
->i_sb
->s_id
, ino
);
52 make_bad_inode(inode
);
56 off
= (ino
- BFS_ROOT_INO
) % BFS_INODES_PER_BLOCK
;
57 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
59 inode
->i_mode
= 0x0000FFFF & le32_to_cpu(di
->i_mode
);
60 if (le32_to_cpu(di
->i_vtype
) == BFS_VDIR
) {
61 inode
->i_mode
|= S_IFDIR
;
62 inode
->i_op
= &bfs_dir_inops
;
63 inode
->i_fop
= &bfs_dir_operations
;
64 } else if (le32_to_cpu(di
->i_vtype
) == BFS_VREG
) {
65 inode
->i_mode
|= S_IFREG
;
66 inode
->i_op
= &bfs_file_inops
;
67 inode
->i_fop
= &bfs_file_operations
;
68 inode
->i_mapping
->a_ops
= &bfs_aops
;
71 BFS_I(inode
)->i_sblock
= le32_to_cpu(di
->i_sblock
);
72 BFS_I(inode
)->i_eblock
= le32_to_cpu(di
->i_eblock
);
73 inode
->i_uid
= le32_to_cpu(di
->i_uid
);
74 inode
->i_gid
= le32_to_cpu(di
->i_gid
);
75 inode
->i_nlink
= le32_to_cpu(di
->i_nlink
);
76 inode
->i_size
= BFS_FILESIZE(di
);
77 inode
->i_blocks
= BFS_FILEBLOCKS(di
);
78 if (inode
->i_size
|| inode
->i_blocks
) dprintf("Registered inode with %lld size, %ld blocks\n", inode
->i_size
, inode
->i_blocks
);
79 inode
->i_atime
.tv_sec
= le32_to_cpu(di
->i_atime
);
80 inode
->i_mtime
.tv_sec
= le32_to_cpu(di
->i_mtime
);
81 inode
->i_ctime
.tv_sec
= le32_to_cpu(di
->i_ctime
);
82 inode
->i_atime
.tv_nsec
= 0;
83 inode
->i_mtime
.tv_nsec
= 0;
84 inode
->i_ctime
.tv_nsec
= 0;
85 BFS_I(inode
)->i_dsk_ino
= le16_to_cpu(di
->i_ino
); /* can be 0 so we store a copy */
90 static int bfs_write_inode(struct inode
* inode
, int unused
)
92 unsigned int ino
= (u16
)inode
->i_ino
;
93 unsigned long i_sblock
;
94 struct bfs_inode
* di
;
95 struct buffer_head
* bh
;
98 dprintf("ino=%08x\n", ino
);
100 if (ino
< BFS_ROOT_INO
|| ino
> BFS_SB(inode
->i_sb
)->si_lasti
) {
101 printf("Bad inode number %s:%08x\n", inode
->i_sb
->s_id
, ino
);
106 block
= (ino
- BFS_ROOT_INO
)/BFS_INODES_PER_BLOCK
+ 1;
107 bh
= sb_bread(inode
->i_sb
, block
);
109 printf("Unable to read inode %s:%08x\n", inode
->i_sb
->s_id
, ino
);
114 off
= (ino
- BFS_ROOT_INO
)%BFS_INODES_PER_BLOCK
;
115 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
117 if (ino
== BFS_ROOT_INO
)
118 di
->i_vtype
= cpu_to_le32(BFS_VDIR
);
120 di
->i_vtype
= cpu_to_le32(BFS_VREG
);
122 di
->i_ino
= cpu_to_le16(ino
);
123 di
->i_mode
= cpu_to_le32(inode
->i_mode
);
124 di
->i_uid
= cpu_to_le32(inode
->i_uid
);
125 di
->i_gid
= cpu_to_le32(inode
->i_gid
);
126 di
->i_nlink
= cpu_to_le32(inode
->i_nlink
);
127 di
->i_atime
= cpu_to_le32(inode
->i_atime
.tv_sec
);
128 di
->i_mtime
= cpu_to_le32(inode
->i_mtime
.tv_sec
);
129 di
->i_ctime
= cpu_to_le32(inode
->i_ctime
.tv_sec
);
130 i_sblock
= BFS_I(inode
)->i_sblock
;
131 di
->i_sblock
= cpu_to_le32(i_sblock
);
132 di
->i_eblock
= cpu_to_le32(BFS_I(inode
)->i_eblock
);
133 di
->i_eoffset
= cpu_to_le32(i_sblock
* BFS_BSIZE
+ inode
->i_size
- 1);
135 mark_buffer_dirty(bh
);
136 dprintf("Written ino=%d into %d:%d\n",le16_to_cpu(di
->i_ino
),block
,off
);
142 static void bfs_delete_inode(struct inode
* inode
)
144 unsigned long ino
= inode
->i_ino
;
145 struct bfs_inode
* di
;
146 struct buffer_head
* bh
;
148 struct super_block
* s
= inode
->i_sb
;
149 struct bfs_sb_info
* info
= BFS_SB(s
);
150 struct bfs_inode_info
* bi
= BFS_I(inode
);
152 dprintf("ino=%08lx\n", ino
);
154 truncate_inode_pages(&inode
->i_data
, 0);
156 if (ino
< BFS_ROOT_INO
|| ino
> info
->si_lasti
) {
157 printf("invalid ino=%08lx\n", ino
);
162 inode
->i_atime
= inode
->i_mtime
= inode
->i_ctime
= CURRENT_TIME_SEC
;
164 mark_inode_dirty(inode
);
165 block
= (ino
- BFS_ROOT_INO
)/BFS_INODES_PER_BLOCK
+ 1;
166 bh
= sb_bread(s
, block
);
168 printf("Unable to read inode %s:%08lx\n", inode
->i_sb
->s_id
, ino
);
172 off
= (ino
- BFS_ROOT_INO
)%BFS_INODES_PER_BLOCK
;
173 di
= (struct bfs_inode
*) bh
->b_data
+ off
;
175 info
->si_freeb
+= 1 + bi
->i_eblock
- bi
->i_sblock
;
177 clear_bit(ino
, info
->si_imap
);
178 dump_imap("delete_inode", s
);
182 mark_buffer_dirty(bh
);
185 /* if this was the last file, make the previous
186 block "last files last block" even if there is no real file there,
188 if (info
->si_lf_eblk
== BFS_I(inode
)->i_eblock
) {
189 info
->si_lf_eblk
= BFS_I(inode
)->i_sblock
- 1;
190 mark_buffer_dirty(info
->si_sbh
);
196 static void bfs_put_super(struct super_block
*s
)
198 struct bfs_sb_info
*info
= BFS_SB(s
);
199 brelse(info
->si_sbh
);
200 kfree(info
->si_imap
);
205 static int bfs_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
207 struct super_block
*s
= dentry
->d_sb
;
208 struct bfs_sb_info
*info
= BFS_SB(s
);
209 u64 id
= huge_encode_dev(s
->s_bdev
->bd_dev
);
210 buf
->f_type
= BFS_MAGIC
;
211 buf
->f_bsize
= s
->s_blocksize
;
212 buf
->f_blocks
= info
->si_blocks
;
213 buf
->f_bfree
= buf
->f_bavail
= info
->si_freeb
;
214 buf
->f_files
= info
->si_lasti
+ 1 - BFS_ROOT_INO
;
215 buf
->f_ffree
= info
->si_freei
;
216 buf
->f_fsid
.val
[0] = (u32
)id
;
217 buf
->f_fsid
.val
[1] = (u32
)(id
>> 32);
218 buf
->f_namelen
= BFS_NAMELEN
;
222 static void bfs_write_super(struct super_block
*s
)
225 if (!(s
->s_flags
& MS_RDONLY
))
226 mark_buffer_dirty(BFS_SB(s
)->si_sbh
);
231 static struct kmem_cache
* bfs_inode_cachep
;
233 static struct inode
*bfs_alloc_inode(struct super_block
*sb
)
235 struct bfs_inode_info
*bi
;
236 bi
= kmem_cache_alloc(bfs_inode_cachep
, GFP_KERNEL
);
239 return &bi
->vfs_inode
;
242 static void bfs_destroy_inode(struct inode
*inode
)
244 kmem_cache_free(bfs_inode_cachep
, BFS_I(inode
));
247 static void init_once(struct kmem_cache
*cachep
, void *foo
)
249 struct bfs_inode_info
*bi
= foo
;
251 inode_init_once(&bi
->vfs_inode
);
254 static int init_inodecache(void)
256 bfs_inode_cachep
= kmem_cache_create("bfs_inode_cache",
257 sizeof(struct bfs_inode_info
),
258 0, (SLAB_RECLAIM_ACCOUNT
|
261 if (bfs_inode_cachep
== NULL
)
266 static void destroy_inodecache(void)
268 kmem_cache_destroy(bfs_inode_cachep
);
271 static const struct super_operations bfs_sops
= {
272 .alloc_inode
= bfs_alloc_inode
,
273 .destroy_inode
= bfs_destroy_inode
,
274 .read_inode
= bfs_read_inode
,
275 .write_inode
= bfs_write_inode
,
276 .delete_inode
= bfs_delete_inode
,
277 .put_super
= bfs_put_super
,
278 .write_super
= bfs_write_super
,
279 .statfs
= bfs_statfs
,
282 void dump_imap(const char *prefix
, struct super_block
* s
)
286 char *tmpbuf
= (char *)get_zeroed_page(GFP_KERNEL
);
290 for (i
=BFS_SB(s
)->si_lasti
; i
>=0; i
--) {
291 if (i
> PAGE_SIZE
-100) break;
292 if (test_bit(i
, BFS_SB(s
)->si_imap
))
297 printk(KERN_ERR
"BFS-fs: %s: lasti=%08lx <%s>\n", prefix
, BFS_SB(s
)->si_lasti
, tmpbuf
);
298 free_page((unsigned long)tmpbuf
);
302 static int bfs_fill_super(struct super_block
*s
, void *data
, int silent
)
304 struct buffer_head
* bh
;
305 struct bfs_super_block
* bfs_sb
;
306 struct inode
* inode
;
307 unsigned i
, imap_len
;
308 struct bfs_sb_info
* info
;
310 info
= kzalloc(sizeof(*info
), GFP_KERNEL
);
315 sb_set_blocksize(s
, BFS_BSIZE
);
320 bfs_sb
= (struct bfs_super_block
*)bh
->b_data
;
321 if (le32_to_cpu(bfs_sb
->s_magic
) != BFS_MAGIC
) {
323 printf("No BFS filesystem on %s (magic=%08x)\n",
324 s
->s_id
, le32_to_cpu(bfs_sb
->s_magic
));
327 if (BFS_UNCLEAN(bfs_sb
, s
) && !silent
)
328 printf("%s is unclean, continuing\n", s
->s_id
);
330 s
->s_magic
= BFS_MAGIC
;
332 info
->si_lasti
= (le32_to_cpu(bfs_sb
->s_start
) - BFS_BSIZE
)/sizeof(struct bfs_inode
)
335 imap_len
= info
->si_lasti
/8 + 1;
336 info
->si_imap
= kzalloc(imap_len
, GFP_KERNEL
);
339 for (i
=0; i
<BFS_ROOT_INO
; i
++)
340 set_bit(i
, info
->si_imap
);
343 inode
= iget(s
, BFS_ROOT_INO
);
345 kfree(info
->si_imap
);
348 s
->s_root
= d_alloc_root(inode
);
351 kfree(info
->si_imap
);
355 info
->si_blocks
= (le32_to_cpu(bfs_sb
->s_end
) + 1)>>BFS_BSIZE_BITS
; /* for statfs(2) */
356 info
->si_freeb
= (le32_to_cpu(bfs_sb
->s_end
) + 1 - le32_to_cpu(bfs_sb
->s_start
))>>BFS_BSIZE_BITS
;
358 info
->si_lf_eblk
= 0;
359 info
->si_lf_sblk
= 0;
360 info
->si_lf_ioff
= 0;
362 for (i
=BFS_ROOT_INO
; i
<=info
->si_lasti
; i
++) {
363 struct bfs_inode
*di
;
364 int block
= (i
- BFS_ROOT_INO
)/BFS_INODES_PER_BLOCK
+ 1;
365 int off
= (i
- BFS_ROOT_INO
) % BFS_INODES_PER_BLOCK
;
366 unsigned long sblock
, eblock
;
370 bh
= sb_bread(s
, block
);
376 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
382 set_bit(i
, info
->si_imap
);
383 info
->si_freeb
-= BFS_FILEBLOCKS(di
);
385 sblock
= le32_to_cpu(di
->i_sblock
);
386 eblock
= le32_to_cpu(di
->i_eblock
);
387 if (eblock
> info
->si_lf_eblk
) {
388 info
->si_lf_eblk
= eblock
;
389 info
->si_lf_sblk
= sblock
;
390 info
->si_lf_ioff
= BFS_INO2OFF(i
);
394 if (!(s
->s_flags
& MS_RDONLY
)) {
395 mark_buffer_dirty(info
->si_sbh
);
398 dump_imap("read_super", s
);
408 static int bfs_get_sb(struct file_system_type
*fs_type
,
409 int flags
, const char *dev_name
, void *data
, struct vfsmount
*mnt
)
411 return get_sb_bdev(fs_type
, flags
, dev_name
, data
, bfs_fill_super
, mnt
);
414 static struct file_system_type bfs_fs_type
= {
415 .owner
= THIS_MODULE
,
417 .get_sb
= bfs_get_sb
,
418 .kill_sb
= kill_block_super
,
419 .fs_flags
= FS_REQUIRES_DEV
,
422 static int __init
init_bfs_fs(void)
424 int err
= init_inodecache();
427 err
= register_filesystem(&bfs_fs_type
);
432 destroy_inodecache();
437 static void __exit
exit_bfs_fs(void)
439 unregister_filesystem(&bfs_fs_type
);
440 destroy_inodecache();
443 module_init(init_bfs_fs
)
444 module_exit(exit_bfs_fs
)