2005-04-17 02:20:36 +04:00
/*
* QNX4 file system , Linux implementation .
*
* Version : 0.2 .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 <linux/buffer_head.h>
2009-06-07 17:47:13 +04:00
# include "qnx4.h"
2005-04-17 02:20:36 +04:00
2013-05-17 23:17:59 +04:00
static int qnx4_readdir ( struct file * file , struct dir_context * ctx )
2005-04-17 02:20:36 +04:00
{
2013-05-17 23:17:59 +04:00
struct inode * inode = file_inode ( file ) ;
2005-04-17 02:20:36 +04:00
unsigned int offset ;
struct buffer_head * bh ;
struct qnx4_inode_entry * de ;
struct qnx4_link_info * le ;
unsigned long blknum ;
int ix , ino ;
int size ;
2009-09-26 22:15:09 +04:00
QNX4DEBUG ( ( KERN_INFO " qnx4_readdir:i_size = %ld \n " , ( long ) inode - > i_size ) ) ;
2013-05-17 23:17:59 +04:00
QNX4DEBUG ( ( KERN_INFO " pos = %ld \n " , ( long ) ctx - > pos ) ) ;
2005-04-17 02:20:36 +04:00
2013-05-17 23:17:59 +04:00
while ( ctx - > pos < inode - > i_size ) {
blknum = qnx4_block_map ( inode , ctx - > pos > > QNX4_BLOCK_SIZE_BITS ) ;
2005-04-17 02:20:36 +04:00
bh = sb_bread ( inode - > i_sb , blknum ) ;
2013-05-17 23:17:59 +04:00
if ( bh = = NULL ) {
2005-04-17 02:20:36 +04:00
printk ( KERN_ERR " qnx4_readdir: bread failed (%ld) \n " , blknum ) ;
2013-05-17 23:17:59 +04:00
return 0 ;
2005-04-17 02:20:36 +04:00
}
2013-05-17 23:17:59 +04:00
ix = ( ctx - > pos > > QNX4_DIR_ENTRY_SIZE_BITS ) % QNX4_INODES_PER_BLOCK ;
for ( ; ix < QNX4_INODES_PER_BLOCK ; ix + + , ctx - > pos + = QNX4_DIR_ENTRY_SIZE ) {
2005-04-17 02:20:36 +04:00
offset = ix * QNX4_DIR_ENTRY_SIZE ;
de = ( struct qnx4_inode_entry * ) ( bh - > b_data + offset ) ;
2013-05-17 23:17:59 +04:00
if ( ! de - > di_fname [ 0 ] )
continue ;
if ( ! ( de - > di_status & ( QNX4_FILE_USED | QNX4_FILE_LINK ) ) )
continue ;
if ( ! ( de - > di_status & QNX4_FILE_LINK ) )
size = QNX4_SHORT_NAME_MAX ;
else
size = QNX4_NAME_MAX ;
size = strnlen ( de - > di_fname , size ) ;
QNX4DEBUG ( ( KERN_INFO " qnx4_readdir:%.*s \n " , size , de - > di_fname ) ) ;
if ( ! ( de - > di_status & QNX4_FILE_LINK ) )
ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1 ;
else {
le = ( struct qnx4_link_info * ) de ;
ino = ( le32_to_cpu ( le - > dl_inode_blk ) - 1 ) *
QNX4_INODES_PER_BLOCK +
le - > dl_inode_ndx ;
}
if ( ! dir_emit ( ctx , de - > di_fname , size , ino , DT_UNKNOWN ) ) {
brelse ( bh ) ;
return 0 ;
2005-04-17 02:20:36 +04:00
}
}
brelse ( bh ) ;
}
return 0 ;
}
2006-03-28 13:56:42 +04:00
const struct file_operations qnx4_dir_operations =
2005-04-17 02:20:36 +04:00
{
2010-05-27 01:44:53 +04:00
. llseek = generic_file_llseek ,
2005-04-17 02:20:36 +04:00
. read = generic_read_dir ,
2013-05-17 23:17:59 +04:00
. iterate = qnx4_readdir ,
2010-05-26 19:53:41 +04:00
. fsync = generic_file_fsync ,
2005-04-17 02:20:36 +04:00
} ;
2007-02-12 11:55:40 +03:00
const struct inode_operations qnx4_dir_inode_operations =
2005-04-17 02:20:36 +04:00
{
. lookup = qnx4_lookup ,
} ;