This source file includes following definitions.
- affs_dir_read
- affs_readdir
- affs_dir_truncate
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 #include <asm/segment.h>
17 #include <linux/errno.h>
18 #include <linux/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/mm.h>
24 #include <linux/amigaffs.h>
25
26 static int affs_readdir(struct inode *, struct file *, void *, filldir_t);
27 static int affs_dir_read(struct inode * inode, struct file * filp, char * buf, int count);
28
29 static struct file_operations affs_dir_operations = {
30 NULL,
31 affs_dir_read,
32 NULL,
33 affs_readdir,
34 NULL,
35 NULL,
36 NULL,
37 NULL,
38 NULL,
39 file_fsync
40 };
41
42
43
44
45 struct inode_operations affs_dir_inode_operations = {
46 &affs_dir_operations,
47 affs_create,
48 affs_lookup,
49 affs_link,
50 affs_unlink,
51 affs_symlink,
52 affs_mkdir,
53 affs_rmdir,
54 NULL,
55 affs_rename,
56 NULL,
57 NULL,
58 NULL,
59 NULL,
60 NULL,
61 affs_dir_truncate,
62 NULL
63 };
64
65 static int
66 affs_dir_read(struct inode * inode, struct file * filp, char * buf, int count)
67 {
68 return -EISDIR;
69 }
70
71 static int
72 affs_readdir(struct inode *inode, struct file *filp, void *dirent, filldir_t filldir)
73 {
74 int j, namelen;
75 LONG i;
76 ULONG hash_pos;
77 ULONG chain_pos;
78 unsigned long ino;
79 unsigned long old;
80 int stored;
81 char *name;
82 struct buffer_head *dir_bh;
83 struct buffer_head *fh_bh;
84 struct inode *dir;
85
86 pr_debug("AFFS: readdir(ino=%ld,f_pos=%lu)\n",inode->i_ino,filp->f_pos);
87
88
89 if (!inode || !S_ISDIR(inode->i_mode))
90 return -EBADF;
91
92 stored = 0;
93 dir_bh = NULL;
94 fh_bh = NULL;
95 dir = NULL;
96 old = filp->f_pos & 0x80000000;
97 filp->f_pos &= 0x7FFFFFFF;
98
99 if (filp->f_pos == 0) {
100 filp->private_data = (void *)0;
101 if (filldir(dirent,".",1,filp->f_pos,inode->i_ino) < 0) {
102 return 0;
103 }
104 ++filp->f_pos;
105 stored++;
106 }
107 if (filp->f_pos == 1) {
108 if (filldir(dirent,"..",2,filp->f_pos,affs_parent_ino(inode)) < 0) {
109 filp->f_pos |= 0x80000000;
110 return stored;
111 }
112 filp->f_pos = 2;
113 stored++;
114 }
115
116
117 ino = inode->u.affs_i.i_original ? inode->u.affs_i.i_original : inode->i_ino;
118 if (!(dir = iget(inode->i_sb,ino)))
119 return stored;
120
121 chain_pos = (filp->f_pos - 2) & 0xffff;
122 hash_pos = (filp->f_pos - 2) >> 16;
123 if (chain_pos == 0xffff) {
124 printk("AFFS: more than 65535 entries in chain\n");
125 chain_pos = 0;
126 hash_pos++;
127 filp->f_pos = ((hash_pos << 16) | chain_pos) + 2;
128 }
129 if (!(dir_bh = affs_bread(inode->i_dev,ino,AFFS_I2BSIZE(inode))))
130 goto readdir_done;
131
132 while (!stored || !old) {
133 while (hash_pos < AFFS_I2HSIZE(inode) &&
134 !((struct dir_front *)dir_bh->b_data)->hashtable[hash_pos])
135 hash_pos++;
136 if (hash_pos >= AFFS_I2HSIZE(inode))
137 goto readdir_done;
138
139 i = htonl(((struct dir_front *)dir_bh->b_data)->hashtable[hash_pos]);
140 j = chain_pos;
141
142
143
144 if (filp->private_data && filp->f_version == dir->i_version) {
145 i = (ULONG)filp->private_data;
146 j = 0;
147 pd_debug("AFFS: readdir() left off=%lu\n",i);
148 }
149 filp->f_version = dir->i_version;
150 pd_debug("AFFS: hash_pos=%lu chain_pos=%lu\n", hash_pos, chain_pos);
151 while (i) {
152 if (!(fh_bh = affs_bread(inode->i_dev,i,AFFS_I2BSIZE(inode)))) {
153 printk("AFFS: readdir: Can't get block %d\n",i);
154 goto readdir_done;
155 }
156 ino = i;
157 i = htonl(FILE_END(fh_bh->b_data,inode)->hash_chain);
158 if (j == 0)
159 break;
160 affs_brelse(fh_bh);
161 fh_bh = NULL;
162 j--;
163 }
164 if (fh_bh) {
165 namelen = affs_get_file_name(AFFS_I2BSIZE(inode),fh_bh->b_data,&name);
166 pr_debug("AFFS: readdir(): filldir(..,\"%.*s\",ino=%lu), i=%lu\n",namelen,name,ino,i);
167 filp->private_data = (void *)ino;
168 if (filldir(dirent,name,namelen,filp->f_pos,ino) < 0)
169 goto readdir_done;
170 filp->private_data = (void *)i;
171 affs_brelse(fh_bh);
172 fh_bh = NULL;
173 stored++;
174 }
175 if (i == 0) {
176 hash_pos++;
177 chain_pos = 0;
178 } else
179 chain_pos++;
180 filp->f_pos = ((hash_pos << 16) | chain_pos) + 2;
181 }
182
183 readdir_done:
184 filp->f_pos |= old;
185 affs_brelse(dir_bh);
186 affs_brelse(fh_bh);
187 iput(dir);
188 pr_debug("AFFS: readdir()=%d\n",stored);
189 return stored;
190 }
191
192 void
193 affs_dir_truncate(struct inode *inode)
194 {
195 printk("AFFS: dir_truncate()\n");
196 }