This source file includes following definitions.
- affs_find_next_hash_entry
- affs_get_file_name
- affs_fix_hash_pred
- affs_fix_link_pred
- affs_checksum_block
- affs_fix_checksum
- secs_to_datestamp
- prot_to_mode
- mode_to_prot
1
2
3
4
5
6
7
8
9
10 #include <linux/stat.h>
11 #include <linux/sched.h>
12 #include <linux/affs_fs.h>
13 #include <linux/string.h>
14 #include <linux/locks.h>
15 #include <linux/mm.h>
16 #include <linux/amigaffs.h>
17
18 extern struct timezone sys_tz;
19
20
21
22
23
24
25
26
27
28
29
30
31 int
32 affs_find_next_hash_entry(int hsize, void *dir_data, ULONG *hash_pos)
33 {
34 struct dir_front *dir_front = dir_data;
35 ULONG i;
36
37 for (i = *hash_pos; i < hsize; i++)
38 if (dir_front->hashtable[i] != 0)
39 break;
40 if (i >= hsize)
41 return 0;
42 *hash_pos = i;
43 return htonl(dir_front->hashtable[i]);
44 }
45
46
47
48
49 int
50 affs_get_file_name(int bsize, void *fh_data, char **name)
51 {
52 struct file_end *file_end;
53
54 file_end = GET_END_PTR(struct file_end, fh_data, bsize);
55 if (file_end->file_name[0] == 0
56 || file_end->file_name[0] > 30) {
57 printk ("affs_get_file_name: OOPS! bad filename\n");
58 printk (" file_end->file_name[0] = %d\n",
59 file_end->file_name[0]);
60 *name = "***BAD_FILE***";
61 return 14;
62 }
63 *name = (char *) &file_end->file_name[1];
64 return file_end->file_name[0];
65 }
66
67
68
69 int
70 affs_fix_hash_pred(struct inode *startino, int startoffset, LONG key, LONG newkey)
71 {
72 struct buffer_head *bh = NULL;
73 ULONG nextkey;
74 LONG ptype, stype;
75 int retval;
76
77 nextkey = startino->i_ino;
78 retval = -ENOENT;
79 lock_super(startino->i_sb);
80 while (1) {
81 pr_debug("AFFS: fix_hash_pred(): next key=%d, offset=%d\n", nextkey, startoffset);
82 if (nextkey == 0)
83 break;
84 if (!(bh = affs_bread(startino->i_dev,nextkey,AFFS_I2BSIZE(startino))))
85 break;
86 if (affs_checksum_block(AFFS_I2BSIZE(startino),bh->b_data,&ptype,&stype)
87 || ptype != T_SHORT || (stype != ST_FILE && stype != ST_USERDIR &&
88 stype != ST_LINKFILE && stype != ST_LINKDIR &&
89 stype != ST_ROOT && stype != ST_SOFTLINK)) {
90 printk("AFFS: bad block found in link chain (ptype=%d, stype=%d)\n",
91 ptype,stype);
92 affs_brelse(bh);
93 break;
94 }
95 nextkey = htonl(((ULONG *)bh->b_data)[startoffset]);
96 if (nextkey == key) {
97 ((ULONG *)bh->b_data)[startoffset] = newkey;
98 affs_fix_checksum(AFFS_I2BSIZE(startino),bh->b_data,5);
99 mark_buffer_dirty(bh,1);
100 affs_brelse(bh);
101 retval = 0;
102 break;
103 }
104 affs_brelse(bh);
105 startoffset = AFFS_I2BSIZE(startino) / 4 - 4;
106 }
107 unlock_super(startino->i_sb);
108
109 return retval;
110 }
111
112
113
114 int
115 affs_fix_link_pred(struct inode *startino, LONG key, LONG newkey)
116 {
117 struct buffer_head *bh = NULL;
118 ULONG nextkey;
119 ULONG offset;
120 LONG etype = 0;
121 LONG ptype, stype;
122 int retval;
123
124 offset = AFFS_I2BSIZE(startino) / 4 - 10;
125 nextkey = startino->i_ino;
126 retval = -ENOENT;
127 lock_super(startino->i_sb);
128 while (1) {
129 if (nextkey == 0)
130 break;
131 pr_debug("AFFS: find_link_pred(): next key=%d\n", nextkey));
132 if (!(bh = affs_bread(startino->i_dev,nextkey,AFFS_I2BSIZE(startino))))
133 break;
134 if (affs_checksum_block(AFFS_I2BSIZE(startino),bh->b_data,&ptype,&stype)
135 || ptype != T_SHORT) {
136 affs_brelse(bh);
137 break;
138 }
139 if (!etype) {
140 if (stype != ST_FILE && stype != ST_USERDIR) {
141 affs_brelse(bh);
142 break;
143 }
144 if (stype == ST_FILE)
145 etype = ST_LINKFILE;
146 else
147 etype = ST_LINKDIR;
148 } else if (stype != etype) {
149 affs_brelse(bh);
150 retval = -EPERM;
151 break;
152 }
153 nextkey = htonl(((ULONG *)bh->b_data)[offset]);
154 if (nextkey == key) {
155 FILE_END(bh->b_data,startino)->link_chain = newkey;
156 affs_fix_checksum(AFFS_I2BSIZE(startino),bh->b_data,5);
157 mark_buffer_dirty(bh,1);
158 affs_brelse(bh);
159 retval = 0;
160 break;
161 }
162 affs_brelse(bh);
163 }
164 unlock_super(startino->i_sb);
165 return retval;
166 }
167
168
169
170
171
172
173
174
175 ULONG
176 affs_checksum_block(int bsize, void *data, LONG *ptype, LONG *stype)
177 {
178 ULONG sum;
179 ULONG *p;
180
181 bsize /= 4;
182 if (ptype)
183 *ptype = htonl(((LONG *)data)[0]);
184 if (stype)
185 *stype = htonl(((LONG *)data)[bsize - 1]);
186
187 sum = 0;
188 p = data;
189 while (bsize--)
190 sum += htonl(*p++);
191 return sum;
192 }
193
194 void
195 affs_fix_checksum(int bsize, void *data, int cspos)
196 {
197 ULONG ocs;
198 ULONG cs;
199
200 cs = affs_checksum_block(bsize,data,NULL,NULL);
201 ocs = htonl (((ULONG *)data)[cspos]);
202 ocs -= cs;
203 ((ULONG *)data)[cspos] = htonl(ocs);
204 }
205
206 void
207 secs_to_datestamp(int secs, struct DateStamp *ds)
208 {
209 ULONG days;
210 ULONG minute;
211
212 secs -= sys_tz.tz_minuteswest * 60 +((8 * 365 + 2) * 24 * 60 * 60);
213 if (secs < 0)
214 secs = 0;
215 days = secs / 86400;
216 secs -= days * 86400;
217 minute = secs / 60;
218 secs -= minute * 60;
219
220 ds->ds_Days = htonl(days);
221 ds->ds_Minute = htonl(minute);
222 ds->ds_Tick = htonl(secs * 50);
223 }
224
225 int
226 prot_to_mode(ULONG prot)
227 {
228 int mode = 0;
229
230 if (AFFS_UMAYWRITE(prot))
231 mode |= S_IWUSR;
232 if (AFFS_UMAYREAD(prot))
233 mode |= S_IRUSR;
234 if (AFFS_UMAYEXECUTE(prot))
235 mode |= S_IXUSR;
236 if (AFFS_GMAYWRITE(prot))
237 mode |= S_IWGRP;
238 if (AFFS_GMAYREAD(prot))
239 mode |= S_IRGRP;
240 if (AFFS_GMAYEXECUTE(prot))
241 mode |= S_IXGRP;
242 if (AFFS_OMAYWRITE(prot))
243 mode |= S_IWOTH;
244 if (AFFS_OMAYREAD(prot))
245 mode |= S_IROTH;
246 if (AFFS_OMAYEXECUTE(prot))
247 mode |= S_IXOTH;
248
249 return mode;
250 }
251
252 ULONG
253 mode_to_prot(int mode)
254 {
255 ULONG prot = 0;
256
257 if (mode & S_IXUSR)
258 prot |= FIBF_SCRIPT;
259 if (mode & S_IRUSR)
260 prot |= FIBF_READ;
261 if (mode & S_IWUSR)
262 prot |= FIBF_WRITE | FIBF_DELETE;
263 if (mode & S_IRGRP)
264 prot |= FIBF_GRP_READ;
265 if (mode & S_IWGRP)
266 prot |= FIBF_GRP_WRITE;
267 if (mode & S_IROTH)
268 prot |= FIBF_OTR_READ;
269 if (mode & S_IWOTH)
270 prot |= FIBF_OTR_WRITE;
271
272 return prot;
273 }