0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/buffer_head.h>
0016 #include "qnx4.h"
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045 union qnx4_directory_entry {
0046 struct {
0047 const char de_name[48];
0048 u8 de_pad[15];
0049 u8 de_status;
0050 };
0051 struct qnx4_inode_entry inode;
0052 struct qnx4_link_info link;
0053 };
0054
0055 static int qnx4_readdir(struct file *file, struct dir_context *ctx)
0056 {
0057 struct inode *inode = file_inode(file);
0058 unsigned int offset;
0059 struct buffer_head *bh;
0060 unsigned long blknum;
0061 int ix, ino;
0062 int size;
0063
0064 QNX4DEBUG((KERN_INFO "qnx4_readdir:i_size = %ld\n", (long) inode->i_size));
0065 QNX4DEBUG((KERN_INFO "pos = %ld\n", (long) ctx->pos));
0066
0067 while (ctx->pos < inode->i_size) {
0068 blknum = qnx4_block_map(inode, ctx->pos >> QNX4_BLOCK_SIZE_BITS);
0069 bh = sb_bread(inode->i_sb, blknum);
0070 if (bh == NULL) {
0071 printk(KERN_ERR "qnx4_readdir: bread failed (%ld)\n", blknum);
0072 return 0;
0073 }
0074 ix = (ctx->pos >> QNX4_DIR_ENTRY_SIZE_BITS) % QNX4_INODES_PER_BLOCK;
0075 for (; ix < QNX4_INODES_PER_BLOCK; ix++, ctx->pos += QNX4_DIR_ENTRY_SIZE) {
0076 union qnx4_directory_entry *de;
0077
0078 offset = ix * QNX4_DIR_ENTRY_SIZE;
0079 de = (union qnx4_directory_entry *) (bh->b_data + offset);
0080
0081 if (!de->de_name[0])
0082 continue;
0083 if (!(de->de_status & (QNX4_FILE_USED|QNX4_FILE_LINK)))
0084 continue;
0085 if (!(de->de_status & QNX4_FILE_LINK)) {
0086 size = sizeof(de->inode.di_fname);
0087 ino = blknum * QNX4_INODES_PER_BLOCK + ix - 1;
0088 } else {
0089 size = sizeof(de->link.dl_fname);
0090 ino = ( le32_to_cpu(de->link.dl_inode_blk) - 1 ) *
0091 QNX4_INODES_PER_BLOCK +
0092 de->link.dl_inode_ndx;
0093 }
0094 size = strnlen(de->de_name, size);
0095 QNX4DEBUG((KERN_INFO "qnx4_readdir:%.*s\n", size, name));
0096 if (!dir_emit(ctx, de->de_name, size, ino, DT_UNKNOWN)) {
0097 brelse(bh);
0098 return 0;
0099 }
0100 }
0101 brelse(bh);
0102 }
0103 return 0;
0104 }
0105
0106 const struct file_operations qnx4_dir_operations =
0107 {
0108 .llseek = generic_file_llseek,
0109 .read = generic_read_dir,
0110 .iterate_shared = qnx4_readdir,
0111 .fsync = generic_file_fsync,
0112 };
0113
0114 const struct inode_operations qnx4_dir_inode_operations =
0115 {
0116 .lookup = qnx4_lookup,
0117 };