This source file includes following definitions.
- umsdos_readdir_kmem
- umsdos_file_read_kmem
- umsdos_file_write_kmem
- umsdos_emd_dir_write
- umsdos_emd_dir_read
- umsdos_emd_dir_lookup
- umsdos_emd_dir_readentry
- umsdos_writeentry
- umsdos_fillbuf
- umsdos_find
- umsdos_newentry
- umsdos_newhidden
- umsdos_delentry
- umsdos_isempty
- umsdos_findentry
1
2
3
4
5
6
7
8 #ifdef MODULE
9 #include <linux/module.h>
10 #endif
11
12 #include <linux/types.h>
13 #include <linux/fcntl.h>
14 #include <linux/kernel.h>
15 #include <asm/segment.h>
16 #include <linux/sched.h>
17 #include <linux/errno.h>
18 #include <linux/string.h>
19 #include <linux/msdos_fs.h>
20 #include <linux/umsdos_fs.h>
21
22 #define PRINTK(x)
23 #define Printk(x) printk x
24
25 int umsdos_readdir_kmem(
26 struct inode *inode,
27 struct file *filp,
28 struct dirent *dirent,
29 int count)
30 {
31 int ret;
32 int old_fs = get_fs();
33 set_fs (KERNEL_DS);
34 ret = msdos_readdir(inode,filp,dirent,count);
35 set_fs (old_fs);
36 return ret;
37 }
38
39
40
41 int umsdos_file_read_kmem(
42 struct inode *inode,
43 struct file *filp,
44 char *buf,
45 int count)
46 {
47 int ret;
48 int old_fs = get_fs();
49 set_fs (KERNEL_DS);
50 ret = msdos_file_read(inode,filp,buf,count);
51 set_fs (old_fs);
52 return ret;
53 }
54
55
56
57 int umsdos_file_write_kmem(
58 struct inode *inode,
59 struct file *filp,
60 char *buf,
61 int count)
62 {
63 int ret;
64 int old_fs = get_fs();
65 set_fs (KERNEL_DS);
66 ret = msdos_file_write(inode,filp,buf,count);
67 set_fs (old_fs);
68 return ret;
69 }
70
71
72
73
74
75
76
77
78 int umsdos_emd_dir_write (
79 struct inode *emd_dir,
80 struct file *filp,
81 char *buf,
82 int count)
83 {
84 int written;
85 filp->f_flags = 0;
86 written = umsdos_file_write_kmem (emd_dir,filp,buf,count);
87 return written != count ? -EIO : 0;
88 }
89
90
91
92
93
94 int umsdos_emd_dir_read (
95 struct inode *emd_dir,
96 struct file *filp,
97 char *buf,
98 int count)
99 {
100 int ret = 0;
101 int sizeread;
102 filp->f_flags = 0;
103 sizeread = umsdos_file_read_kmem (emd_dir,filp,buf,count);
104 if (sizeread != count){
105 printk ("UMSDOS: problem with EMD file. Can't read\n");
106 ret = -EIO;
107 }
108 return ret;
109
110 }
111
112
113
114
115
116 struct inode *umsdos_emd_dir_lookup(struct inode *dir, int creat)
117 {
118 struct inode *ret = NULL;
119 if (dir->u.umsdos_i.i_emd_dir != 0){
120 ret = iget (dir->i_sb,dir->u.umsdos_i.i_emd_dir);
121 PRINTK (("deja trouve %d %x [%d] "
122 ,dir->u.umsdos_i.i_emd_dir,ret,ret->i_count));
123 }else{
124 umsdos_real_lookup (dir,UMSDOS_EMD_FILE,UMSDOS_EMD_NAMELEN,&ret);
125 PRINTK (("emd_dir_lookup "));
126 if (ret != NULL){
127 PRINTK (("Find --linux "));
128 dir->u.umsdos_i.i_emd_dir = ret->i_ino;
129 }else if (creat){
130 int code;
131 PRINTK (("avant create "));
132 dir->i_count++;
133 code = msdos_create (dir,UMSDOS_EMD_FILE,UMSDOS_EMD_NAMELEN
134 ,S_IFREG|0777,&ret);
135 PRINTK (("Creat EMD code %d ret %x ",code,ret));
136 if (ret != NULL){
137 dir->u.umsdos_i.i_emd_dir = ret->i_ino;
138 }else{
139 printk ("UMSDOS: Can't create EMD file\n");
140 }
141 }
142 }
143 if (ret != NULL){
144
145 ret->u.umsdos_i.i_emd_owner = 0xffffffff;
146 }
147 return ret;
148 }
149
150
151
152
153
154
155 int umsdos_emd_dir_readentry (
156 struct inode *emd_dir,
157 struct file *filp,
158 struct umsdos_dirent *entry)
159 {
160 int ret = umsdos_emd_dir_read(emd_dir,filp,(char*)entry,UMSDOS_REC_SIZE);
161 if (ret == 0){
162
163 int recsize = umsdos_evalrecsize (entry->name_len);
164 if (recsize > UMSDOS_REC_SIZE){
165 ret = umsdos_emd_dir_read(emd_dir,filp
166 ,((char*)entry)+UMSDOS_REC_SIZE,recsize - UMSDOS_REC_SIZE);
167
168 }
169 }
170 return ret;
171 }
172
173
174
175
176 int umsdos_writeentry (
177 struct inode *dir,
178 struct inode *emd_dir,
179 struct umsdos_info *info,
180 int free_entry)
181 {
182 int ret = 0;
183 struct file filp;
184 struct umsdos_dirent *entry = &info->entry;
185 struct umsdos_dirent entry0;
186 if (free_entry){
187
188
189
190
191
192
193 memset (&entry0,0,sizeof(entry0));
194 entry = &entry0;
195 }else if (entry->name_len > 0){
196 memset (entry->name+entry->name_len,'\0'
197 ,sizeof(entry->name)-entry->name_len);
198
199
200
201
202
203
204 memset (entry->spare,0,sizeof(entry->spare));
205 }
206 filp.f_pos = info->f_pos;
207 filp.f_reada = 0;
208 ret = umsdos_emd_dir_write(emd_dir,&filp,(char*)entry,info->recsize);
209 if (ret != 0){
210 printk ("UMSDOS: problem with EMD file. Can't write\n");
211 }else{
212 dir->i_ctime = dir->i_mtime = CURRENT_TIME;
213 dir->i_dirt = 1;
214 }
215 return ret;
216 }
217
218 #define CHUNK_SIZE (8*UMSDOS_REC_SIZE)
219 struct find_buffer{
220 char buffer[CHUNK_SIZE];
221 int pos;
222 int size;
223 struct file filp;
224 };
225
226
227
228
229
230
231
232 static int umsdos_fillbuf (
233 struct inode *inode,
234 struct find_buffer *buf)
235 {
236 int ret = -ENOENT;
237 int mustmove = buf->size - buf->pos;
238 int mustread;
239 int remain;
240 if (mustmove > 0){
241 memcpy (buf->buffer,buf->buffer+buf->pos,mustmove);
242 }
243 buf->pos = 0;
244 mustread = CHUNK_SIZE - mustmove;
245 remain = inode->i_size - buf->filp.f_pos;
246 if (remain < mustread) mustread = remain;
247 if (mustread > 0){
248 ret = umsdos_emd_dir_read (inode,&buf->filp,buf->buffer+mustmove
249 ,mustread);
250 if (ret == 0) buf->size = mustmove + mustread;
251 }else if (mustmove){
252 buf->size = mustmove;
253 ret = 0;
254 }
255 return ret;
256 }
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279 static int umsdos_find (
280 struct inode *dir,
281 struct umsdos_info *info,
282
283 struct inode **pt_emd_dir)
284
285 {
286
287
288
289
290
291 int ret = -ENOENT;
292 struct inode *emd_dir = umsdos_emd_dir_lookup(dir,1);
293 if (emd_dir != NULL){
294 struct umsdos_dirent *entry = &info->entry;
295 int recsize = info->recsize;
296 struct {
297 off_t posok;
298 int found;
299 off_t one;
300 int onesize;
301 }empty;
302
303 struct find_buffer buf;
304 buf.pos = 0;
305 buf.size = 0;
306 buf.filp.f_pos = 0;
307 buf.filp.f_reada = 1;
308 empty.found = 0;
309 empty.posok = emd_dir->i_size;
310 empty.onesize = 0;
311 while (1){
312 struct umsdos_dirent *rentry = (struct umsdos_dirent*)
313 (buf.buffer + buf.pos);
314 int file_pos = buf.filp.f_pos - buf.size + buf.pos;
315 if (buf.pos == buf.size){
316 ret = umsdos_fillbuf (emd_dir,&buf);
317 if (ret < 0){
318
319 info->f_pos = empty.posok;
320 break;
321 }
322 }else if (rentry->name_len == 0){
323
324
325 if (entry->name_len == 0){
326 info->f_pos = file_pos;
327 ret = 0;
328 break;
329 }else if (!empty.found){
330 if (empty.onesize == 0){
331
332 empty.one = file_pos;
333 }
334
335 empty.onesize += UMSDOS_REC_SIZE;
336 if (empty.onesize == recsize){
337
338 empty.posok = empty.one;
339 empty.found = 1;
340 }
341 }
342 buf.pos += UMSDOS_REC_SIZE;
343 }else{
344 int entry_size = umsdos_evalrecsize(rentry->name_len);
345 if (buf.pos+entry_size > buf.size){
346 ret = umsdos_fillbuf (emd_dir,&buf);
347 if (ret < 0){
348
349 info->f_pos = empty.posok;
350 break;
351 }
352 }else{
353 empty.onesize = 0;
354 if (entry->name_len == rentry->name_len
355 && memcmp(entry->name,rentry->name,rentry->name_len)
356 ==0){
357 info->f_pos = file_pos;
358 *entry = *rentry;
359 ret = 0;
360 break;
361 }else{
362 buf.pos += entry_size;
363 }
364 }
365 }
366 }
367 umsdos_manglename(info);
368 }
369 *pt_emd_dir = emd_dir;
370 return ret;
371 }
372
373
374
375
376
377
378
379 int umsdos_newentry (
380 struct inode *dir,
381 struct umsdos_info *info)
382 {
383 struct inode *emd_dir;
384 int ret = umsdos_find (dir,info,&emd_dir);
385 if (ret == 0){
386 ret = -EEXIST;
387 }else if (ret == -ENOENT){
388 ret = umsdos_writeentry(dir,emd_dir,info,0);
389 PRINTK (("umsdos_newentry EDM ret = %d\n",ret));
390 }
391 iput (emd_dir);
392 return ret;
393 }
394
395
396
397
398 int umsdos_newhidden (
399 struct inode *dir,
400 struct umsdos_info *info)
401 {
402 struct inode *emd_dir;
403 int ret;
404 umsdos_parse ("..LINK",6,info);
405 info->entry.name_len = 0;
406 ret = umsdos_find (dir,info,&emd_dir);
407 iput (emd_dir);
408 if (ret == -ENOENT || ret == 0){
409
410
411
412
413
414 info->entry.name_len = sprintf (info->entry.name,"..LINK%ld"
415 ,info->f_pos);
416 ret = 0;
417 }
418 return ret;
419 }
420
421
422
423
424
425
426 int umsdos_delentry (
427 struct inode *dir,
428 struct umsdos_info *info,
429 int isdir)
430 {
431 struct inode *emd_dir;
432 int ret = umsdos_find (dir,info,&emd_dir);
433 if (ret == 0){
434 if (info->entry.name_len != 0){
435 if ((isdir != 0) != (S_ISDIR(info->entry.mode) != 0)){
436 if (S_ISDIR(info->entry.mode)){
437 ret = -EISDIR;
438 }else{
439 ret = -ENOTDIR;
440 }
441 }else{
442 ret = umsdos_writeentry(dir,emd_dir,info,1);
443 }
444 }
445 }
446 iput(emd_dir);
447 return ret;
448 }
449
450
451
452
453
454
455
456
457 int umsdos_isempty (struct inode *dir)
458 {
459 int ret = 2;
460 struct inode *emd_dir = umsdos_emd_dir_lookup(dir,0);
461
462 if (emd_dir != NULL){
463 struct file filp;
464
465 filp.f_pos = 0;
466 filp.f_reada = 1;
467 filp.f_flags = O_RDONLY;
468 ret = 1;
469 while (filp.f_pos < emd_dir->i_size){
470 struct umsdos_dirent entry;
471 if (umsdos_emd_dir_readentry(emd_dir,&filp,&entry)!=0){
472 ret = 0;
473 break;
474 }else if (entry.name_len != 0){
475 ret = 0;
476 break;
477 }
478 }
479 iput (emd_dir);
480 }
481 return ret;
482 }
483
484
485
486
487
488 int umsdos_findentry (
489 struct inode *dir,
490 struct umsdos_info *info,
491 int expect)
492
493
494 {
495 struct inode *emd_dir;
496 int ret = umsdos_find (dir,info,&emd_dir);
497 if (ret == 0){
498 if (expect != 0){
499 if (S_ISDIR(info->entry.mode)){
500 if (expect != 2) ret = -EISDIR;
501 }else if (expect == 2){
502 ret = -ENOTDIR;
503 }
504 }
505 }
506 iput (emd_dir);
507 return ret;
508 }
509