2 * QNX4 file system, Linux implementation.
6 * Using parts of the xiafs filesystem.
10 * 01-06-1998 by Richard Frowijn : first release.
11 * 20-06-1998 by Frank Denis : Linux 2.1.99+ support, boot signature, misc.
12 * 30-06-1998 by Frank Denis : first step to write inodes.
15 #include <linux/config.h>
16 #include <linux/module.h>
17 #include <linux/types.h>
18 #include <linux/errno.h>
19 #include <linux/malloc.h>
20 #include <linux/qnx4_fs.h>
22 #include <linux/locks.h>
23 #include <linux/init.h>
25 #include <asm/uaccess.h>
27 #define QNX4_VERSION 4
28 #define QNX4_BMNAME ".bitmap"
29 #define CHECK_BOOT_SIGNATURE 0
31 static struct super_operations qnx4_sops
;
33 #ifdef CONFIG_QNX4FS_RW
35 int qnx4_sync_inode(struct inode
*inode
)
39 struct buffer_head
*bh
;
41 bh
= qnx4_update_inode(inode
);
42 if (bh
&& buffer_dirty(bh
))
44 ll_rw_block(WRITE
, 1, &bh
);
46 if (buffer_req(bh
) && !buffer_uptodate(bh
))
48 printk ("IO error syncing qnx4 inode [%s:%08lx]\n",
49 kdevname(inode
->i_dev
), inode
->i_ino
);
61 static void qnx4_delete_inode(struct inode
*inode
)
63 QNX4DEBUG(("qnx4: deleting inode [%lu]\n", (unsigned long) inode
->i_ino
));
66 qnx4_free_inode(inode
);
69 static void qnx4_write_super(struct super_block
*sb
)
71 QNX4DEBUG(("qnx4: write_super\n"));
75 static void qnx4_put_inode(struct inode
*inode
)
77 if (inode
->i_nlink
!= 0) {
83 static void qnx4_write_inode(struct inode
*inode
)
85 struct qnx4_inode_entry
*raw_inode
;
87 struct buffer_head
*bh
;
90 QNX4DEBUG(("qnx4: write inode 1.\n"));
91 if (inode
->i_nlink
== 0) {
95 printk("qnx4: bad inode number on dev %s: %d is out of range\n",
96 kdevname(inode
->i_dev
), ino
);
99 QNX4DEBUG(("qnx4: write inode 2.\n"));
100 block
= ino
/ QNX4_INODES_PER_BLOCK
;
101 if (!(bh
= bread(inode
->i_dev
, block
, QNX4_BLOCK_SIZE
))) {
102 printk("qnx4: major problem: unable to read inode from dev "
103 "%s\n", kdevname(inode
->i_dev
));
106 raw_inode
= ((struct qnx4_inode_entry
*) bh
->b_data
) +
107 (ino
% QNX4_INODES_PER_BLOCK
);
108 raw_inode
->di_mode
= inode
->i_mode
;
109 raw_inode
->di_uid
= inode
->i_uid
;
110 raw_inode
->di_gid
= inode
->i_gid
;
111 raw_inode
->di_nlink
= inode
->i_nlink
;
112 raw_inode
->di_size
= inode
->i_size
;
113 raw_inode
->di_mtime
= inode
->i_mtime
;
114 raw_inode
->di_atime
= inode
->i_atime
;
115 raw_inode
->di_ctime
= inode
->i_ctime
;
116 raw_inode
->di_first_xtnt
.xtnt_size
= inode
->i_blocks
;
117 mark_buffer_dirty(bh
, 1);
123 static struct super_block
*qnx4_read_super(struct super_block
*, void *, int);
124 static void qnx4_put_super(struct super_block
*sb
);
125 static void qnx4_read_inode(struct inode
*);
126 static int qnx4_remount(struct super_block
*sb
, int *flags
, char *data
);
127 static int qnx4_statfs(struct super_block
*, struct statfs
*, int);
129 static struct super_operations qnx4_sops
=
132 #ifdef CONFIG_QNX4FS_RW
137 #ifdef CONFIG_QNX4FS_RW
140 NULL
, /* notify_change */
142 NULL
, /* put_inode */
143 NULL
, /* delete_inode */
144 NULL
, /* notify_change */
147 #ifdef CONFIG_QNX4FS_RW
154 NULL
/* clear_inode */
157 static int qnx4_remount(struct super_block
*sb
, int *flags
, char *data
)
159 struct qnx4_sb_info
*qs
;
162 qs
->Version
= QNX4_VERSION
;
163 if (*flags
& MS_RDONLY
) {
166 mark_buffer_dirty(qs
->sb_buf
, 1);
171 struct buffer_head
*inode_getblk(struct inode
*inode
, int nr
,
176 struct buffer_head
*result
= NULL
;
182 result
= getblk(inode
->i_dev
, tmp
, QNX4_BLOCK_SIZE
);
193 tmp
= qnx4_new_block(inode
->i_sb
);
197 result
= getblk(inode
->i_dev
, tmp
, QNX4_BLOCK_SIZE
);
199 qnx4_free_block(inode
->i_sb
, tmp
);
205 inode
->i_ctime
= CURRENT_TIME
;
206 mark_inode_dirty(inode
);
210 struct buffer_head
*qnx4_bread(struct inode
*inode
, int block
, int create
)
212 struct buffer_head
*bh
;
214 bh
= inode_getblk(inode
, block
, create
);
215 if (!bh
|| buffer_uptodate(bh
)) {
218 ll_rw_block(READ
, 1, &bh
);
220 if (buffer_uptodate(bh
)) {
228 static int qnx4_statfs(struct super_block
*sb
,
229 struct statfs
*buf
, int bufsize
)
233 memset(&tmp
, 0, sizeof tmp
);
234 tmp
.f_type
= sb
->s_magic
;
235 tmp
.f_bsize
= sb
->s_blocksize
;
236 tmp
.f_blocks
= le32_to_cpu(sb
->u
.qnx4_sb
.BitMap
->di_size
) * 8;
237 tmp
.f_bfree
= qnx4_count_free_blocks(sb
);
238 tmp
.f_bavail
= tmp
.f_bfree
;
239 tmp
.f_files
= 0x00; /* change this !!! */
240 tmp
.f_ffree
= qnx4_count_free_inodes(sb
);
241 tmp
.f_namelen
= QNX4_NAME_MAX
;
243 return copy_to_user(buf
, &tmp
, bufsize
) ? -EFAULT
: 0;
247 * Check the root directory of the filesystem to make sure
248 * it really _is_ a qnx4 filesystem, and to check the size
249 * of the directory entry.
251 static const char *qnx4_checkroot(struct super_block
*s
)
253 struct buffer_head
*bh
;
254 struct qnx4_inode_entry
*rootdir
;
260 return "no qnx4 filesystem (null superblock).";
262 if (*(s
->u
.qnx4_sb
.sb
->RootDir
.di_fname
) != '/') {
263 return "no qnx4 filesystem (no root dir).";
265 QNX4DEBUG(("QNX4 filesystem found on dev %s.\n", kdevname(s
->s_dev
)));
266 rd
= s
->u
.qnx4_sb
.sb
->RootDir
.di_first_xtnt
.xtnt_blk
- 1;
267 rl
= s
->u
.qnx4_sb
.sb
->RootDir
.di_first_xtnt
.xtnt_size
;
268 for (j
= 0; j
< rl
; j
++) {
269 bh
= bread(s
->s_dev
, rd
+ j
, QNX4_BLOCK_SIZE
); /* root dir, first block */
271 return "unable to read root entry.";
273 for (i
= 0; i
< QNX4_INODES_PER_BLOCK
; i
++) {
274 rootdir
= (struct qnx4_inode_entry
*) (bh
->b_data
+ i
* QNX4_DIR_ENTRY_SIZE
);
275 if (rootdir
->di_fname
!= NULL
) {
276 QNX4DEBUG(("Rootdir entry found : [%s]\n", rootdir
->di_fname
));
277 if (!strncmp(rootdir
->di_fname
, QNX4_BMNAME
, sizeof QNX4_BMNAME
)) {
279 s
->u
.qnx4_sb
.BitMap
= rootdir
; /* keep bitmap inode known */
290 return "bitmap file not found.";
296 static struct super_block
*qnx4_read_super(struct super_block
*s
,
297 void *data
, int silent
)
299 struct buffer_head
*bh
;
300 kdev_t dev
= s
->s_dev
;
301 #if CHECK_BOOT_SIGNATURE
308 set_blocksize(dev
, QNX4_BLOCK_SIZE
);
309 s
->s_blocksize
= QNX4_BLOCK_SIZE
;
310 s
->s_blocksize_bits
= 9;
313 #if CHECK_BOOT_SIGNATURE
314 bh
= bread(dev
, 0, QNX4_BLOCK_SIZE
);
316 printk("qnx4: unable to read the boot sector\n");
319 tmpc
= (char *) bh
->b_data
;
320 if (tmpc
[4] != 'Q' || tmpc
[5] != 'N' || tmpc
[6] != 'X' ||
321 tmpc
[7] != '4' || tmpc
[8] != 'F' || tmpc
[9] != 'S') {
322 printk("qnx4: wrong fsid in boot sector.\n");
327 bh
= bread(dev
, 1, QNX4_BLOCK_SIZE
);
329 printk("qnx4: unable to read the superblock\n");
332 s
->s_op
= &qnx4_sops
;
333 s
->s_magic
= QNX4_SUPER_MAGIC
;
334 #ifndef CONFIG_QNX4FS_RW
335 s
->s_flags
|= MS_RDONLY
; /* Yup, read-only yet */
337 s
->u
.qnx4_sb
.sb_buf
= bh
;
338 s
->u
.qnx4_sb
.sb
= (struct qnx4_super_block
*) bh
->b_data
;
340 d_alloc_root(iget(s
, QNX4_ROOT_INO
* QNX4_INODES_PER_BLOCK
), NULL
);
341 if (s
->s_root
== NULL
) {
342 printk("qnx4: get inode failed\n");
345 errmsg
= qnx4_checkroot(s
);
346 if (errmsg
!= NULL
) {
347 printk("qnx4: %s\n", errmsg
);
366 static void qnx4_put_super(struct super_block
*sb
)
372 static void qnx4_read_inode(struct inode
*inode
)
374 struct buffer_head
*bh
;
375 struct qnx4_inode_entry
*raw_inode
;
382 QNX4DEBUG(("Reading inode : [%d]\n", ino
));
384 printk("qnx4: bad inode number on dev %s: %d is out of range\n",
385 kdevname(inode
->i_dev
), ino
);
388 block
= ino
/ QNX4_INODES_PER_BLOCK
;
390 if (!(bh
= bread(inode
->i_dev
, block
, QNX4_BLOCK_SIZE
))) {
391 printk("qnx4: major problem: unable to read inode from dev "
392 "%s\n", kdevname(inode
->i_dev
));
395 raw_inode
= ((struct qnx4_inode_entry
*) bh
->b_data
) +
396 (ino
% QNX4_INODES_PER_BLOCK
);
398 inode
->i_mode
= raw_inode
->di_mode
;
399 inode
->i_uid
= raw_inode
->di_uid
;
400 inode
->i_gid
= raw_inode
->di_gid
;
401 inode
->i_nlink
= raw_inode
->di_nlink
;
402 inode
->i_size
= raw_inode
->di_size
;
403 inode
->i_mtime
= raw_inode
->di_mtime
;
404 inode
->i_atime
= raw_inode
->di_atime
;
405 inode
->i_ctime
= raw_inode
->di_ctime
;
406 inode
->i_blocks
= raw_inode
->di_first_xtnt
.xtnt_size
;
407 inode
->i_blksize
= QNX4_DIR_ENTRY_SIZE
;
409 memcpy(&inode
->u
.qnx4_i
, (struct qnx4_inode_info
*) raw_inode
, QNX4_DIR_ENTRY_SIZE
);
410 inode
->i_op
= &qnx4_file_inode_operations
;
411 if (S_ISREG(inode
->i_mode
))
412 inode
->i_op
= &qnx4_file_inode_operations
;
413 else if (S_ISDIR(inode
->i_mode
))
414 inode
->i_op
= &qnx4_dir_inode_operations
;
415 else if (S_ISLNK(inode
->i_mode
))
416 inode
->i_op
= &qnx4_symlink_inode_operations
;
418 /* HUH??? Where is device number? Oh, well... */
419 init_special_inode(inode
, inode
->i_mode
, 0);
424 static struct file_system_type qnx4_fs_type
=
432 __initfunc(int init_qnx4_fs(void))
434 printk("QNX4 filesystem v0.2 registered.\n");
435 return register_filesystem(&qnx4_fs_type
);
441 int init_module(void)
443 return init_qnx4_fs();
446 void cleanup_module(void)
448 unregister_filesystem(&qnx4_fs_type
);