/* * QNX4 file system, Linux implementation. * * Version : 0.1 * * Using parts of the xiafs filesystem. * * History : * * 28-05-1998 by Richard Frowijn : first release. * 20-06-1998 by Frank Denis : Linux 2.1.99+ & dcache support. */ #include #include #include #include #include #include #include static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir); static int qnx4_readdir(struct file *filp, void *dirent, filldir_t filldir) { struct inode *inode = filp->f_dentry->d_inode; unsigned int offset; struct buffer_head *bh; struct qnx4_inode_entry *de; long blknum; int i; int size; blknum = inode->u.qnx4_i.i_first_xtnt.xtnt_blk - 1 + ((filp->f_pos >> 6) >> 3); QNX4DEBUG(("qnx4_readdir:i_size = %ld\n", (long) inode->i_size)); QNX4DEBUG(("filp->f_pos = %ld\n", (long) filp->f_pos)); QNX4DEBUG(("BlkNum = %ld\n", (long) blknum)); while (filp->f_pos < inode->i_size) { bh = bread(inode->i_dev, blknum, QNX4_BLOCK_SIZE); if(bh==NULL) { printk(KERN_ERR "qnx4_readdir: bread failed (%ld)\n", blknum); break; } i = (filp->f_pos - (((filp->f_pos >> 6) >> 3) << 9)) & 0x3f; while (i < QNX4_INODES_PER_BLOCK) { offset = i * QNX4_DIR_ENTRY_SIZE; de = (struct qnx4_inode_entry *) (bh->b_data + offset); size = strlen(de->di_fname); if (size) { QNX4DEBUG(("qnx4_readdir:%s\n", de->di_fname)); if ((de->di_mode) || (de->di_status == QNX4_FILE_LINK)) { if (de->di_status) { if (filldir(dirent, de->di_fname, size, filp->f_pos, de->di_first_xtnt.xtnt_blk) < 0) { brelse(bh); return 0; } } } } i++; filp->f_pos += QNX4_DIR_ENTRY_SIZE; } brelse(bh); blknum++; } UPDATE_ATIME(inode); return 0; } static struct file_operations qnx4_dir_operations = { NULL, /* lseek - default */ NULL, /* read */ NULL, /* write - bad */ qnx4_readdir, /* readdir */ NULL, /* poll - default */ NULL, /* ioctl - default */ NULL, /* mmap */ NULL, /* no special open code */ NULL, /* no special flush code */ NULL, /* no special release code */ file_fsync, /* default fsync */ NULL, /* default fasync */ NULL, /* default check_media_change */ NULL, /* default revalidate */ }; struct inode_operations qnx4_dir_inode_operations = { &qnx4_dir_operations, #ifdef CONFIG_QNX4FS_RW qnx4_create, #else NULL, /* create */ #endif qnx4_lookup, NULL, /* link */ #ifdef CONFIG_QNX4FS_RW qnx4_unlink, /* unlink */ #else NULL, #endif NULL, /* symlink */ NULL, /* mkdir */ #ifdef CONFIG_QNX4FS_RW qnx4_rmdir, /* rmdir */ #else NULL, #endif NULL, /* mknod */ NULL, /* rename */ NULL, /* readlink */ NULL, /* follow_link */ NULL, /* get_block */ NULL, /* readpage */ NULL, /* writepage */ NULL, /* flushpage */ NULL, /* truncate */ NULL, /* permission */ NULL, /* smap */ NULL /* revalidate */ };