3 * BFS superblock and inode operations.
4 * Copyright (C) 1999,2000 Tigran Aivazian <tigran@veritas.com>
5 * From fs/minix, Copyright (C) 1991, 1992 Linus Torvalds.
8 #include <linux/module.h>
10 #include <linux/slab.h>
11 #include <linux/init.h>
13 #include <linux/smp_lock.h>
14 #include <linux/buffer_head.h>
15 #include <linux/vfs.h>
16 #include <asm/uaccess.h>
19 MODULE_AUTHOR("Tigran A. Aivazian <tigran@veritas.com>");
20 MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux");
21 MODULE_LICENSE("GPL");
26 #define dprintf(x...) printf(x)
31 void dump_imap(const char *prefix
, struct super_block
* s
);
33 static void bfs_read_inode(struct inode
* inode
)
35 unsigned long ino
= inode
->i_ino
;
36 struct bfs_inode
* di
;
37 struct buffer_head
* bh
;
40 if (ino
< BFS_ROOT_INO
|| ino
> BFS_SB(inode
->i_sb
)->si_lasti
) {
41 printf("Bad inode number %s:%08lx\n", inode
->i_sb
->s_id
, ino
);
42 make_bad_inode(inode
);
46 block
= (ino
- BFS_ROOT_INO
)/BFS_INODES_PER_BLOCK
+ 1;
47 bh
= sb_bread(inode
->i_sb
, block
);
49 printf("Unable to read inode %s:%08lx\n", inode
->i_sb
->s_id
, ino
);
50 make_bad_inode(inode
);
54 off
= (ino
- BFS_ROOT_INO
) % BFS_INODES_PER_BLOCK
;
55 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
57 inode
->i_mode
= 0x0000FFFF & di
->i_mode
;
58 if (di
->i_vtype
== BFS_VDIR
) {
59 inode
->i_mode
|= S_IFDIR
;
60 inode
->i_op
= &bfs_dir_inops
;
61 inode
->i_fop
= &bfs_dir_operations
;
62 } else if (di
->i_vtype
== BFS_VREG
) {
63 inode
->i_mode
|= S_IFREG
;
64 inode
->i_op
= &bfs_file_inops
;
65 inode
->i_fop
= &bfs_file_operations
;
66 inode
->i_mapping
->a_ops
= &bfs_aops
;
69 inode
->i_uid
= di
->i_uid
;
70 inode
->i_gid
= di
->i_gid
;
71 inode
->i_nlink
= di
->i_nlink
;
72 inode
->i_size
= BFS_FILESIZE(di
);
73 inode
->i_blocks
= BFS_FILEBLOCKS(di
);
74 inode
->i_blksize
= PAGE_SIZE
;
75 inode
->i_atime
.tv_sec
= di
->i_atime
;
76 inode
->i_mtime
.tv_sec
= di
->i_mtime
;
77 inode
->i_ctime
.tv_sec
= di
->i_ctime
;
78 inode
->i_atime
.tv_nsec
= 0;
79 inode
->i_mtime
.tv_nsec
= 0;
80 inode
->i_ctime
.tv_nsec
= 0;
81 BFS_I(inode
)->i_dsk_ino
= di
->i_ino
; /* can be 0 so we store a copy */
82 BFS_I(inode
)->i_sblock
= di
->i_sblock
;
83 BFS_I(inode
)->i_eblock
= di
->i_eblock
;
88 static int bfs_write_inode(struct inode
* inode
, int unused
)
90 unsigned long ino
= inode
->i_ino
;
91 struct bfs_inode
* di
;
92 struct buffer_head
* bh
;
95 if (ino
< BFS_ROOT_INO
|| ino
> BFS_SB(inode
->i_sb
)->si_lasti
) {
96 printf("Bad inode number %s:%08lx\n", inode
->i_sb
->s_id
, ino
);
101 block
= (ino
- BFS_ROOT_INO
)/BFS_INODES_PER_BLOCK
+ 1;
102 bh
= sb_bread(inode
->i_sb
, block
);
104 printf("Unable to read inode %s:%08lx\n", inode
->i_sb
->s_id
, ino
);
109 off
= (ino
- BFS_ROOT_INO
)%BFS_INODES_PER_BLOCK
;
110 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
112 if (inode
->i_ino
== BFS_ROOT_INO
)
113 di
->i_vtype
= BFS_VDIR
;
115 di
->i_vtype
= BFS_VREG
;
117 di
->i_ino
= inode
->i_ino
;
118 di
->i_mode
= inode
->i_mode
;
119 di
->i_uid
= inode
->i_uid
;
120 di
->i_gid
= inode
->i_gid
;
121 di
->i_nlink
= inode
->i_nlink
;
122 di
->i_atime
= inode
->i_atime
.tv_sec
;
123 di
->i_mtime
= inode
->i_mtime
.tv_sec
;
124 di
->i_ctime
= inode
->i_ctime
.tv_sec
;
125 di
->i_sblock
= BFS_I(inode
)->i_sblock
;
126 di
->i_eblock
= BFS_I(inode
)->i_eblock
;
127 di
->i_eoffset
= di
->i_sblock
* BFS_BSIZE
+ inode
->i_size
- 1;
129 mark_buffer_dirty(bh
);
135 static void bfs_delete_inode(struct inode
* inode
)
137 unsigned long ino
= inode
->i_ino
;
138 struct bfs_inode
* di
;
139 struct buffer_head
* bh
;
141 struct super_block
* s
= inode
->i_sb
;
142 struct bfs_sb_info
* info
= BFS_SB(s
);
144 dprintf("ino=%08lx\n", inode
->i_ino
);
146 if (inode
->i_ino
< BFS_ROOT_INO
|| inode
->i_ino
> info
->si_lasti
) {
147 printf("invalid ino=%08lx\n", inode
->i_ino
);
152 inode
->i_atime
= inode
->i_mtime
= inode
->i_ctime
= CURRENT_TIME_SEC
;
154 mark_inode_dirty(inode
);
155 block
= (ino
- BFS_ROOT_INO
)/BFS_INODES_PER_BLOCK
+ 1;
156 bh
= sb_bread(s
, block
);
158 printf("Unable to read inode %s:%08lx\n", inode
->i_sb
->s_id
, ino
);
162 off
= (ino
- BFS_ROOT_INO
)%BFS_INODES_PER_BLOCK
;
163 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
165 info
->si_freeb
+= BFS_FILEBLOCKS(di
);
167 clear_bit(di
->i_ino
, info
->si_imap
);
168 dump_imap("delete_inode", s
);
172 mark_buffer_dirty(bh
);
175 /* if this was the last file, make the previous
176 block "last files last block" even if there is no real file there,
178 if (info
->si_lf_eblk
== BFS_I(inode
)->i_eblock
) {
179 info
->si_lf_eblk
= BFS_I(inode
)->i_sblock
- 1;
180 mark_buffer_dirty(info
->si_sbh
);
186 static void bfs_put_super(struct super_block
*s
)
188 struct bfs_sb_info
*info
= BFS_SB(s
);
189 brelse(info
->si_sbh
);
190 kfree(info
->si_imap
);
195 static int bfs_statfs(struct super_block
*s
, struct kstatfs
*buf
)
197 struct bfs_sb_info
*info
= BFS_SB(s
);
198 u64 id
= huge_encode_dev(s
->s_bdev
->bd_dev
);
199 buf
->f_type
= BFS_MAGIC
;
200 buf
->f_bsize
= s
->s_blocksize
;
201 buf
->f_blocks
= info
->si_blocks
;
202 buf
->f_bfree
= buf
->f_bavail
= info
->si_freeb
;
203 buf
->f_files
= info
->si_lasti
+ 1 - BFS_ROOT_INO
;
204 buf
->f_ffree
= info
->si_freei
;
205 buf
->f_fsid
.val
[0] = (u32
)id
;
206 buf
->f_fsid
.val
[1] = (u32
)(id
>> 32);
207 buf
->f_namelen
= BFS_NAMELEN
;
211 static void bfs_write_super(struct super_block
*s
)
214 if (!(s
->s_flags
& MS_RDONLY
))
215 mark_buffer_dirty(BFS_SB(s
)->si_sbh
);
220 static kmem_cache_t
* bfs_inode_cachep
;
222 static struct inode
*bfs_alloc_inode(struct super_block
*sb
)
224 struct bfs_inode_info
*bi
;
225 bi
= kmem_cache_alloc(bfs_inode_cachep
, SLAB_KERNEL
);
228 return &bi
->vfs_inode
;
231 static void bfs_destroy_inode(struct inode
*inode
)
233 kmem_cache_free(bfs_inode_cachep
, BFS_I(inode
));
236 static void init_once(void * foo
, kmem_cache_t
* cachep
, unsigned long flags
)
238 struct bfs_inode_info
*bi
= foo
;
240 if ((flags
& (SLAB_CTOR_VERIFY
|SLAB_CTOR_CONSTRUCTOR
)) ==
241 SLAB_CTOR_CONSTRUCTOR
)
242 inode_init_once(&bi
->vfs_inode
);
245 static int init_inodecache(void)
247 bfs_inode_cachep
= kmem_cache_create("bfs_inode_cache",
248 sizeof(struct bfs_inode_info
),
249 0, SLAB_RECLAIM_ACCOUNT
,
251 if (bfs_inode_cachep
== NULL
)
256 static void destroy_inodecache(void)
258 if (kmem_cache_destroy(bfs_inode_cachep
))
259 printk(KERN_INFO
"bfs_inode_cache: not all structures were freed\n");
262 static struct super_operations bfs_sops
= {
263 .alloc_inode
= bfs_alloc_inode
,
264 .destroy_inode
= bfs_destroy_inode
,
265 .read_inode
= bfs_read_inode
,
266 .write_inode
= bfs_write_inode
,
267 .delete_inode
= bfs_delete_inode
,
268 .put_super
= bfs_put_super
,
269 .write_super
= bfs_write_super
,
270 .statfs
= bfs_statfs
,
273 void dump_imap(const char *prefix
, struct super_block
* s
)
277 char *tmpbuf
= (char *)get_zeroed_page(GFP_KERNEL
);
281 for (i
=BFS_SB(s
)->si_lasti
; i
>=0; i
--) {
282 if (i
>PAGE_SIZE
-100) break;
283 if (test_bit(i
, BFS_SB(s
)->si_imap
))
288 printk(KERN_ERR
"BFS-fs: %s: lasti=%08lx <%s>\n", prefix
, BFS_SB(s
)->si_lasti
, tmpbuf
);
289 free_page((unsigned long)tmpbuf
);
293 static int bfs_fill_super(struct super_block
*s
, void *data
, int silent
)
295 struct buffer_head
* bh
;
296 struct bfs_super_block
* bfs_sb
;
297 struct inode
* inode
;
299 struct bfs_sb_info
* info
;
301 info
= kmalloc(sizeof(*info
), GFP_KERNEL
);
305 memset(info
, 0, sizeof(*info
));
307 sb_set_blocksize(s
, BFS_BSIZE
);
312 bfs_sb
= (struct bfs_super_block
*)bh
->b_data
;
313 if (bfs_sb
->s_magic
!= BFS_MAGIC
) {
315 printf("No BFS filesystem on %s (magic=%08x)\n",
316 s
->s_id
, bfs_sb
->s_magic
);
319 if (BFS_UNCLEAN(bfs_sb
, s
) && !silent
)
320 printf("%s is unclean, continuing\n", s
->s_id
);
322 s
->s_magic
= BFS_MAGIC
;
323 info
->si_bfs_sb
= bfs_sb
;
325 info
->si_lasti
= (bfs_sb
->s_start
- BFS_BSIZE
)/sizeof(struct bfs_inode
)
328 imap_len
= info
->si_lasti
/8 + 1;
329 info
->si_imap
= kmalloc(imap_len
, GFP_KERNEL
);
332 memset(info
->si_imap
, 0, imap_len
);
333 for (i
=0; i
<BFS_ROOT_INO
; i
++)
334 set_bit(i
, info
->si_imap
);
337 inode
= iget(s
, BFS_ROOT_INO
);
339 kfree(info
->si_imap
);
342 s
->s_root
= d_alloc_root(inode
);
345 kfree(info
->si_imap
);
349 info
->si_blocks
= (bfs_sb
->s_end
+ 1)>>BFS_BSIZE_BITS
; /* for statfs(2) */
350 info
->si_freeb
= (bfs_sb
->s_end
+ 1 - bfs_sb
->s_start
)>>BFS_BSIZE_BITS
;
352 info
->si_lf_eblk
= 0;
353 info
->si_lf_sblk
= 0;
354 info
->si_lf_ioff
= 0;
355 for (i
=BFS_ROOT_INO
; i
<=info
->si_lasti
; i
++) {
357 if (BFS_I(inode
)->i_dsk_ino
== 0)
360 set_bit(i
, info
->si_imap
);
361 info
->si_freeb
-= inode
->i_blocks
;
362 if (BFS_I(inode
)->i_eblock
> info
->si_lf_eblk
) {
363 info
->si_lf_eblk
= BFS_I(inode
)->i_eblock
;
364 info
->si_lf_sblk
= BFS_I(inode
)->i_sblock
;
365 info
->si_lf_ioff
= BFS_INO2OFF(i
);
370 if (!(s
->s_flags
& MS_RDONLY
)) {
371 mark_buffer_dirty(bh
);
374 dump_imap("read_super", s
);
384 static struct super_block
*bfs_get_sb(struct file_system_type
*fs_type
,
385 int flags
, const char *dev_name
, void *data
)
387 return get_sb_bdev(fs_type
, flags
, dev_name
, data
, bfs_fill_super
);
390 static struct file_system_type bfs_fs_type
= {
391 .owner
= THIS_MODULE
,
393 .get_sb
= bfs_get_sb
,
394 .kill_sb
= kill_block_super
,
395 .fs_flags
= FS_REQUIRES_DEV
,
398 static int __init
init_bfs_fs(void)
400 int err
= init_inodecache();
403 err
= register_filesystem(&bfs_fs_type
);
408 destroy_inodecache();
413 static void __exit
exit_bfs_fs(void)
415 unregister_filesystem(&bfs_fs_type
);
416 destroy_inodecache();
419 module_init(init_bfs_fs
)
420 module_exit(exit_bfs_fs
)