This source file includes following definitions.
- ufs_readdir
1
2
3
4
5
6
7
8
9
10
11
12
13 #include <linux/fs.h>
14
15
16 extern int ufs_lookup (struct inode *, const char *, int, struct inode **);
17 extern int ufs_bmap (struct inode *, int);
18 extern void ufs_print_inode (struct inode *);
19
20
21
22
23 static int
24 ufs_readdir (struct inode * inode, struct file * filp, void * dirent,
25 filldir_t filldir)
26 {
27 int error = 0;
28 unsigned long offset, lblk, blk;
29 int i, stored;
30 struct buffer_head * bh;
31 struct direct * de;
32 struct super_block * sb;
33
34 if (!inode || !S_ISDIR(inode->i_mode))
35 return -EBADF;
36 sb = inode->i_sb;
37
38 if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
39 printk("ufs_readdir: ino %lu f_pos %lu\n",
40 inode->i_ino, (unsigned long) filp->f_pos);
41 ufs_print_inode(inode);
42 }
43
44 stored = 0;
45 bh = NULL;
46 offset = filp->f_pos & (sb->s_blocksize - 1);
47
48 while (!error && !stored && filp->f_pos < inode->i_size) {
49 lblk = (filp->f_pos) >> sb->s_blocksize_bits;
50 blk = ufs_bmap(inode, lblk);
51
52 blk = ufs_bmap(inode, lblk);
53 bh = bread (sb->s_dev, blk, sb->s_blocksize);
54 if (!bh) {
55
56 printk("ufs_readdir: dir inode %lu has a hole at offset %lu\n",
57 inode->i_ino, (unsigned long int)filp->f_pos);
58 filp->f_pos += sb->s_blocksize - offset;
59 continue;
60 }
61
62 revalidate:
63
64
65
66
67 if (filp->f_version != inode->i_version) {
68 for (i = 0; i < sb->s_blocksize && i < offset; ) {
69 de = (struct direct *)
70 (bh->b_data + i);
71
72
73
74
75
76
77 if (de->d_reclen < 1)
78 break;
79 i += de->d_reclen;
80 }
81 offset = i;
82 filp->f_pos = (filp->f_pos & ~(sb->s_blocksize - 1))
83 | offset;
84 filp->f_version = inode->i_version;
85 }
86
87 while (!error && filp->f_pos < inode->i_size
88 && offset < sb->s_blocksize) {
89 de = (struct direct *) (bh->b_data + offset);
90
91 if ((de->d_reclen == 0) || (de->d_namlen == 0)) {
92 filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1)) + sb->s_blocksize;
93 brelse(bh);
94 return stored;
95 }
96 #if 0
97 if (!ext2_check_dir_entry ("ext2_readdir", inode, de,
98 bh, offset)) {
99
100
101 filp->f_pos = (filp->f_pos & (sb->s_blocksize - 1))
102 + sb->s_blocksize;
103 brelse (bh);
104 return stored;
105 }
106 #endif
107 offset += de->d_reclen;
108 if (de->d_ino) {
109
110
111
112
113
114
115 unsigned long version;
116 dcache_add(inode, de->d_name, de->d_namlen,
117 de->d_ino);
118 version = inode->i_version;
119 if (inode->i_sb->u.ufs_sb.s_flags & UFS_DEBUG) {
120 printk("ufs_readdir: filldir(%s,%u)\n",
121 de->d_name, de->d_ino);
122 }
123 error = filldir(dirent, de->d_name, de->d_namlen, filp->f_pos, de->d_ino);
124 if (error)
125 break;
126 if (version != inode->i_version)
127 goto revalidate;
128 stored ++;
129 }
130 filp->f_pos += de->d_reclen;
131 }
132 offset = 0;
133 brelse (bh);
134 }
135 #if 0
136 if (!IS_RDONLY(inode)) {
137 inode->i_atime = CURRENT_TIME;
138 inode->i_dirt = 1;
139 }
140 #endif
141 return 0;
142 }
143
144 static struct file_operations ufs_dir_operations = {
145 NULL,
146 NULL,
147 NULL,
148 ufs_readdir,
149 NULL,
150 NULL,
151 NULL,
152 NULL,
153 NULL,
154 file_fsync,
155 NULL,
156 NULL,
157 NULL,
158 };
159
160 struct inode_operations ufs_dir_inode_operations = {
161 &ufs_dir_operations,
162 NULL,
163 ufs_lookup,
164 NULL,
165 NULL,
166 NULL,
167 NULL,
168 NULL,
169 NULL,
170 NULL,
171 NULL,
172 NULL,
173 NULL,
174 NULL,
175 NULL,
176 NULL,
177 NULL,
178 NULL,
179 };
180
181
182
183
184
185
186
187
188
189