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 <linux/writeback.h>
19 #include <asm/uaccess.h>
22 MODULE_AUTHOR("Tigran Aivazian <tigran@aivazian.fsnet.co.uk>");
23 MODULE_DESCRIPTION("SCO UnixWare BFS filesystem for Linux");
24 MODULE_LICENSE("GPL");
29 #define dprintf(x...) printf(x)
34 static void bfs_write_super(struct super_block
*s
);
35 void dump_imap(const char *prefix
, struct super_block
*s
);
37 struct inode
*bfs_iget(struct super_block
*sb
, unsigned long ino
)
41 struct buffer_head
*bh
;
44 inode
= iget_locked(sb
, ino
);
46 return ERR_PTR(-ENOMEM
);
47 if (!(inode
->i_state
& I_NEW
))
50 if ((ino
< BFS_ROOT_INO
) || (ino
> BFS_SB(inode
->i_sb
)->si_lasti
)) {
51 printf("Bad inode number %s:%08lx\n", inode
->i_sb
->s_id
, ino
);
55 block
= (ino
- BFS_ROOT_INO
) / BFS_INODES_PER_BLOCK
+ 1;
56 bh
= sb_bread(inode
->i_sb
, block
);
58 printf("Unable to read inode %s:%08lx\n", inode
->i_sb
->s_id
,
63 off
= (ino
- BFS_ROOT_INO
) % BFS_INODES_PER_BLOCK
;
64 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
66 inode
->i_mode
= 0x0000FFFF & le32_to_cpu(di
->i_mode
);
67 if (le32_to_cpu(di
->i_vtype
) == BFS_VDIR
) {
68 inode
->i_mode
|= S_IFDIR
;
69 inode
->i_op
= &bfs_dir_inops
;
70 inode
->i_fop
= &bfs_dir_operations
;
71 } else if (le32_to_cpu(di
->i_vtype
) == BFS_VREG
) {
72 inode
->i_mode
|= S_IFREG
;
73 inode
->i_op
= &bfs_file_inops
;
74 inode
->i_fop
= &bfs_file_operations
;
75 inode
->i_mapping
->a_ops
= &bfs_aops
;
78 BFS_I(inode
)->i_sblock
= le32_to_cpu(di
->i_sblock
);
79 BFS_I(inode
)->i_eblock
= le32_to_cpu(di
->i_eblock
);
80 BFS_I(inode
)->i_dsk_ino
= le16_to_cpu(di
->i_ino
);
81 inode
->i_uid
= le32_to_cpu(di
->i_uid
);
82 inode
->i_gid
= le32_to_cpu(di
->i_gid
);
83 inode
->i_nlink
= le32_to_cpu(di
->i_nlink
);
84 inode
->i_size
= BFS_FILESIZE(di
);
85 inode
->i_blocks
= BFS_FILEBLOCKS(di
);
86 inode
->i_atime
.tv_sec
= le32_to_cpu(di
->i_atime
);
87 inode
->i_mtime
.tv_sec
= le32_to_cpu(di
->i_mtime
);
88 inode
->i_ctime
.tv_sec
= le32_to_cpu(di
->i_ctime
);
89 inode
->i_atime
.tv_nsec
= 0;
90 inode
->i_mtime
.tv_nsec
= 0;
91 inode
->i_ctime
.tv_nsec
= 0;
94 unlock_new_inode(inode
);
102 static int bfs_write_inode(struct inode
*inode
, struct writeback_control
*wbc
)
104 struct bfs_sb_info
*info
= BFS_SB(inode
->i_sb
);
105 unsigned int ino
= (u16
)inode
->i_ino
;
106 unsigned long i_sblock
;
107 struct bfs_inode
*di
;
108 struct buffer_head
*bh
;
112 dprintf("ino=%08x\n", ino
);
114 if ((ino
< BFS_ROOT_INO
) || (ino
> BFS_SB(inode
->i_sb
)->si_lasti
)) {
115 printf("Bad inode number %s:%08x\n", inode
->i_sb
->s_id
, ino
);
119 mutex_lock(&info
->bfs_lock
);
120 block
= (ino
- BFS_ROOT_INO
) / BFS_INODES_PER_BLOCK
+ 1;
121 bh
= sb_bread(inode
->i_sb
, block
);
123 printf("Unable to read inode %s:%08x\n",
124 inode
->i_sb
->s_id
, ino
);
125 mutex_unlock(&info
->bfs_lock
);
129 off
= (ino
- BFS_ROOT_INO
) % BFS_INODES_PER_BLOCK
;
130 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
132 if (ino
== BFS_ROOT_INO
)
133 di
->i_vtype
= cpu_to_le32(BFS_VDIR
);
135 di
->i_vtype
= cpu_to_le32(BFS_VREG
);
137 di
->i_ino
= cpu_to_le16(ino
);
138 di
->i_mode
= cpu_to_le32(inode
->i_mode
);
139 di
->i_uid
= cpu_to_le32(inode
->i_uid
);
140 di
->i_gid
= cpu_to_le32(inode
->i_gid
);
141 di
->i_nlink
= cpu_to_le32(inode
->i_nlink
);
142 di
->i_atime
= cpu_to_le32(inode
->i_atime
.tv_sec
);
143 di
->i_mtime
= cpu_to_le32(inode
->i_mtime
.tv_sec
);
144 di
->i_ctime
= cpu_to_le32(inode
->i_ctime
.tv_sec
);
145 i_sblock
= BFS_I(inode
)->i_sblock
;
146 di
->i_sblock
= cpu_to_le32(i_sblock
);
147 di
->i_eblock
= cpu_to_le32(BFS_I(inode
)->i_eblock
);
148 di
->i_eoffset
= cpu_to_le32(i_sblock
* BFS_BSIZE
+ inode
->i_size
- 1);
150 mark_buffer_dirty(bh
);
151 if (wbc
->sync_mode
== WB_SYNC_ALL
) {
152 sync_dirty_buffer(bh
);
153 if (buffer_req(bh
) && !buffer_uptodate(bh
))
157 mutex_unlock(&info
->bfs_lock
);
161 static void bfs_delete_inode(struct inode
*inode
)
163 unsigned long ino
= inode
->i_ino
;
164 struct bfs_inode
*di
;
165 struct buffer_head
*bh
;
167 struct super_block
*s
= inode
->i_sb
;
168 struct bfs_sb_info
*info
= BFS_SB(s
);
169 struct bfs_inode_info
*bi
= BFS_I(inode
);
171 dprintf("ino=%08lx\n", ino
);
173 truncate_inode_pages(&inode
->i_data
, 0);
175 if ((ino
< BFS_ROOT_INO
) || (ino
> info
->si_lasti
)) {
176 printf("invalid ino=%08lx\n", ino
);
181 inode
->i_atime
= inode
->i_mtime
= inode
->i_ctime
= CURRENT_TIME_SEC
;
182 mutex_lock(&info
->bfs_lock
);
183 mark_inode_dirty(inode
);
185 block
= (ino
- BFS_ROOT_INO
) / BFS_INODES_PER_BLOCK
+ 1;
186 bh
= sb_bread(s
, block
);
188 printf("Unable to read inode %s:%08lx\n",
189 inode
->i_sb
->s_id
, ino
);
190 mutex_unlock(&info
->bfs_lock
);
193 off
= (ino
- BFS_ROOT_INO
) % BFS_INODES_PER_BLOCK
;
194 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
195 memset((void *)di
, 0, sizeof(struct bfs_inode
));
196 mark_buffer_dirty(bh
);
201 info
->si_freeb
+= bi
->i_eblock
+ 1 - bi
->i_sblock
;
203 clear_bit(ino
, info
->si_imap
);
204 dump_imap("delete_inode", s
);
208 * If this was the last file, make the previous block
209 * "last block of the last file" even if there is no
210 * real file there, saves us 1 gap.
212 if (info
->si_lf_eblk
== bi
->i_eblock
) {
213 info
->si_lf_eblk
= bi
->i_sblock
- 1;
214 mark_buffer_dirty(info
->si_sbh
);
216 mutex_unlock(&info
->bfs_lock
);
220 static int bfs_sync_fs(struct super_block
*sb
, int wait
)
222 struct bfs_sb_info
*info
= BFS_SB(sb
);
224 mutex_lock(&info
->bfs_lock
);
225 mark_buffer_dirty(info
->si_sbh
);
227 mutex_unlock(&info
->bfs_lock
);
232 static void bfs_write_super(struct super_block
*sb
)
234 if (!(sb
->s_flags
& MS_RDONLY
))
240 static void bfs_put_super(struct super_block
*s
)
242 struct bfs_sb_info
*info
= BFS_SB(s
);
252 brelse(info
->si_sbh
);
253 mutex_destroy(&info
->bfs_lock
);
254 kfree(info
->si_imap
);
261 static int bfs_statfs(struct dentry
*dentry
, struct kstatfs
*buf
)
263 struct super_block
*s
= dentry
->d_sb
;
264 struct bfs_sb_info
*info
= BFS_SB(s
);
265 u64 id
= huge_encode_dev(s
->s_bdev
->bd_dev
);
266 buf
->f_type
= BFS_MAGIC
;
267 buf
->f_bsize
= s
->s_blocksize
;
268 buf
->f_blocks
= info
->si_blocks
;
269 buf
->f_bfree
= buf
->f_bavail
= info
->si_freeb
;
270 buf
->f_files
= info
->si_lasti
+ 1 - BFS_ROOT_INO
;
271 buf
->f_ffree
= info
->si_freei
;
272 buf
->f_fsid
.val
[0] = (u32
)id
;
273 buf
->f_fsid
.val
[1] = (u32
)(id
>> 32);
274 buf
->f_namelen
= BFS_NAMELEN
;
278 static struct kmem_cache
*bfs_inode_cachep
;
280 static struct inode
*bfs_alloc_inode(struct super_block
*sb
)
282 struct bfs_inode_info
*bi
;
283 bi
= kmem_cache_alloc(bfs_inode_cachep
, GFP_KERNEL
);
286 return &bi
->vfs_inode
;
289 static void bfs_destroy_inode(struct inode
*inode
)
291 kmem_cache_free(bfs_inode_cachep
, BFS_I(inode
));
294 static void init_once(void *foo
)
296 struct bfs_inode_info
*bi
= foo
;
298 inode_init_once(&bi
->vfs_inode
);
301 static int init_inodecache(void)
303 bfs_inode_cachep
= kmem_cache_create("bfs_inode_cache",
304 sizeof(struct bfs_inode_info
),
305 0, (SLAB_RECLAIM_ACCOUNT
|
308 if (bfs_inode_cachep
== NULL
)
313 static void destroy_inodecache(void)
315 kmem_cache_destroy(bfs_inode_cachep
);
318 static const struct super_operations bfs_sops
= {
319 .alloc_inode
= bfs_alloc_inode
,
320 .destroy_inode
= bfs_destroy_inode
,
321 .write_inode
= bfs_write_inode
,
322 .delete_inode
= bfs_delete_inode
,
323 .put_super
= bfs_put_super
,
324 .write_super
= bfs_write_super
,
325 .sync_fs
= bfs_sync_fs
,
326 .statfs
= bfs_statfs
,
329 void dump_imap(const char *prefix
, struct super_block
*s
)
333 char *tmpbuf
= (char *)get_zeroed_page(GFP_KERNEL
);
337 for (i
= BFS_SB(s
)->si_lasti
; i
>= 0; i
--) {
338 if (i
> PAGE_SIZE
- 100) break;
339 if (test_bit(i
, BFS_SB(s
)->si_imap
))
344 printf("BFS-fs: %s: lasti=%08lx <%s>\n",
345 prefix
, BFS_SB(s
)->si_lasti
, tmpbuf
);
346 free_page((unsigned long)tmpbuf
);
350 static int bfs_fill_super(struct super_block
*s
, void *data
, int silent
)
352 struct buffer_head
*bh
;
353 struct bfs_super_block
*bfs_sb
;
355 unsigned i
, imap_len
;
356 struct bfs_sb_info
*info
;
358 unsigned long i_sblock
, i_eblock
, i_eoff
, s_size
;
360 info
= kzalloc(sizeof(*info
), GFP_KERNEL
);
363 mutex_init(&info
->bfs_lock
);
366 sb_set_blocksize(s
, BFS_BSIZE
);
368 info
->si_sbh
= sb_bread(s
, 0);
371 bfs_sb
= (struct bfs_super_block
*)info
->si_sbh
->b_data
;
372 if (le32_to_cpu(bfs_sb
->s_magic
) != BFS_MAGIC
) {
374 printf("No BFS filesystem on %s (magic=%08x)\n",
375 s
->s_id
, le32_to_cpu(bfs_sb
->s_magic
));
378 if (BFS_UNCLEAN(bfs_sb
, s
) && !silent
)
379 printf("%s is unclean, continuing\n", s
->s_id
);
381 s
->s_magic
= BFS_MAGIC
;
383 if (le32_to_cpu(bfs_sb
->s_start
) > le32_to_cpu(bfs_sb
->s_end
)) {
384 printf("Superblock is corrupted\n");
388 info
->si_lasti
= (le32_to_cpu(bfs_sb
->s_start
) - BFS_BSIZE
) /
389 sizeof(struct bfs_inode
)
391 imap_len
= (info
->si_lasti
/ 8) + 1;
392 info
->si_imap
= kzalloc(imap_len
, GFP_KERNEL
);
395 for (i
= 0; i
< BFS_ROOT_INO
; i
++)
396 set_bit(i
, info
->si_imap
);
399 inode
= bfs_iget(s
, BFS_ROOT_INO
);
401 ret
= PTR_ERR(inode
);
404 s
->s_root
= d_alloc_root(inode
);
411 info
->si_blocks
= (le32_to_cpu(bfs_sb
->s_end
) + 1) >> BFS_BSIZE_BITS
;
412 info
->si_freeb
= (le32_to_cpu(bfs_sb
->s_end
) + 1
413 - le32_to_cpu(bfs_sb
->s_start
)) >> BFS_BSIZE_BITS
;
415 info
->si_lf_eblk
= 0;
417 /* can we read the last block? */
418 bh
= sb_bread(s
, info
->si_blocks
- 1);
420 printf("Last block not available: %lu\n", info
->si_blocks
- 1);
427 for (i
= BFS_ROOT_INO
; i
<= info
->si_lasti
; i
++) {
428 struct bfs_inode
*di
;
429 int block
= (i
- BFS_ROOT_INO
) / BFS_INODES_PER_BLOCK
+ 1;
430 int off
= (i
- BFS_ROOT_INO
) % BFS_INODES_PER_BLOCK
;
431 unsigned long eblock
;
435 bh
= sb_bread(s
, block
);
441 di
= (struct bfs_inode
*)bh
->b_data
+ off
;
443 /* test if filesystem is not corrupted */
445 i_eoff
= le32_to_cpu(di
->i_eoffset
);
446 i_sblock
= le32_to_cpu(di
->i_sblock
);
447 i_eblock
= le32_to_cpu(di
->i_eblock
);
448 s_size
= le32_to_cpu(bfs_sb
->s_end
);
450 if (i_sblock
> info
->si_blocks
||
451 i_eblock
> info
->si_blocks
||
452 i_sblock
> i_eblock
||
454 i_sblock
* BFS_BSIZE
> i_eoff
) {
456 printf("Inode 0x%08x corrupted\n", i
);
467 set_bit(i
, info
->si_imap
);
468 info
->si_freeb
-= BFS_FILEBLOCKS(di
);
470 eblock
= le32_to_cpu(di
->i_eblock
);
471 if (eblock
> info
->si_lf_eblk
)
472 info
->si_lf_eblk
= eblock
;
475 if (!(s
->s_flags
& MS_RDONLY
)) {
476 mark_buffer_dirty(info
->si_sbh
);
479 dump_imap("read_super", s
);
486 kfree(info
->si_imap
);
488 brelse(info
->si_sbh
);
490 mutex_destroy(&info
->bfs_lock
);
496 static int bfs_get_sb(struct file_system_type
*fs_type
,
497 int flags
, const char *dev_name
, void *data
, struct vfsmount
*mnt
)
499 return get_sb_bdev(fs_type
, flags
, dev_name
, data
, bfs_fill_super
, mnt
);
502 static struct file_system_type bfs_fs_type
= {
503 .owner
= THIS_MODULE
,
505 .get_sb
= bfs_get_sb
,
506 .kill_sb
= kill_block_super
,
507 .fs_flags
= FS_REQUIRES_DEV
,
510 static int __init
init_bfs_fs(void)
512 int err
= init_inodecache();
515 err
= register_filesystem(&bfs_fs_type
);
520 destroy_inodecache();
525 static void __exit
exit_bfs_fs(void)
527 unregister_filesystem(&bfs_fs_type
);
528 destroy_inodecache();
531 module_init(init_bfs_fs
)
532 module_exit(exit_bfs_fs
)