This source file includes following definitions.
- affs_readdir
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/errno.h>
14
15 #include <asm/segment.h>
16
17 #include <linux/fs.h>
18 #include <linux/affs_fs.h>
19 #include <linux/kernel.h>
20 #include <linux/affs_fs.h>
21 #include <linux/stat.h>
22 #include <linux/string.h>
23 #include <linux/sched.h>
24
25 static int affs_readdir(struct inode *, struct file *, void *, filldir_t);
26
27 struct file_operations affs_dir_operations = {
28 NULL,
29 NULL,
30 NULL,
31 affs_readdir,
32 NULL,
33 NULL,
34 NULL,
35 NULL,
36 NULL,
37 NULL
38 };
39
40
41
42
43 struct inode_operations affs_dir_inode_operations = {
44 &affs_dir_operations,
45 NULL,
46 affs_lookup,
47 NULL,
48 NULL,
49 NULL,
50 NULL,
51 NULL,
52 NULL,
53 NULL,
54 NULL,
55 NULL,
56 NULL,
57 NULL,
58 NULL
59 };
60
61
62
63
64
65
66
67 static int affs_readdir(struct inode * inode, struct file * filp,
68 void * dirent, filldir_t filldir)
69 {
70 int i, j, chain_pos, hash_pos, reclen, ino;
71 char *name;
72 struct buffer_head *dir_bh;
73 struct buffer_head *fh_bh;
74 void *dir_data;
75 void *fh_data;
76
77 #ifdef DEBUG
78 printk ("AFFS: readdir: inode=%d f_pos=%d\n",
79 inode->i_ino, filp->f_pos);
80 #endif
81
82 if (!inode || !S_ISDIR(inode->i_mode))
83 return -EBADF;
84
85 while ((unsigned long)filp->f_pos < 2) {
86 if (filp->f_pos == 0) {
87 if (filldir (dirent, ".", 1, filp->f_pos, inode->i_ino) < 0)
88 return 0;
89 } else {
90 i = affs_parent_ino (inode);
91 if (filldir (dirent, "..", 2, filp->f_pos, i) < 0)
92 return 0;
93 }
94 filp->f_pos++;
95 }
96
97 chain_pos = (filp->f_pos - 2) & 0xffff;
98 if (chain_pos == 0xffff)
99 return 0;
100 hash_pos = (filp->f_pos - 2) >> 16;
101 #ifdef DEBUG
102 printk ("AFFS: hash_pos=%d chain_pos=%d\n", hash_pos, chain_pos);
103 #endif
104 if (!(dir_bh = affs_pread(inode, inode->i_ino, &dir_data)))
105 return 0;
106
107
108
109 i = affs_find_next_hash_entry (AFFS_I2BSIZE (inode), dir_data,
110 &hash_pos);
111 j = chain_pos;
112 for (;;) {
113 if (i <= 0) {
114 #ifdef DEBUG
115 printk ("AFFS: bad f_pos in readdir\n");
116 #endif
117 brelse (dir_bh);
118 return 0;
119 }
120 ino = i;
121 if (!(fh_bh = affs_pread (inode, i, &fh_data))) {
122 brelse (dir_bh);
123 return 0;
124 }
125 i = affs_get_fh_hash_link (AFFS_I2BSIZE (inode), fh_data);
126 if (j == 0) {
127 j = 1;
128 if (i <= 0) {
129 hash_pos++;
130 i = affs_find_next_hash_entry (AFFS_I2BSIZE (inode),
131 dir_data, &hash_pos);
132 if (i <= 0)
133 chain_pos = 0xffff;
134 else
135 chain_pos = 0;
136 } else
137 chain_pos++;
138 reclen = affs_get_file_name (AFFS_I2BSIZE (inode),
139 fh_data, &name);
140 if (filldir (dirent, name, reclen, filp->f_pos, ino) < 0) {
141 brelse (fh_bh);
142 brelse (dir_bh);
143 return 0;
144 }
145 filp->f_pos = ((hash_pos << 16) | chain_pos) + 2;
146 }
147 brelse (fh_bh);
148 j--;
149 }
150 }