This source file includes following definitions.
- isofs_put_super
- parse_options
- isofs_get_last_session
- isofs_read_super
- isofs_statfs
- isofs_bmap
- isofs_read_inode
- isofs_lookup_grandparent
- leak_check_malloc
- leak_check_free_s
- leak_check_bread
- leak_check_brelse
- init_iso9660_fs
- init_module
- cleanup_module
1
2
3
4
5
6
7
8
9
10
11 #include <linux/module.h>
12
13 #include <linux/stat.h>
14 #include <linux/sched.h>
15 #include <linux/iso_fs.h>
16 #include <linux/kernel.h>
17 #include <linux/major.h>
18 #include <linux/mm.h>
19 #include <linux/string.h>
20 #include <linux/locks.h>
21 #include <linux/malloc.h>
22 #include <linux/errno.h>
23 #include <linux/cdrom.h>
24
25 #include <asm/system.h>
26 #include <asm/segment.h>
27
28 #ifdef LEAK_CHECK
29 static int check_malloc = 0;
30 static int check_bread = 0;
31 #endif
32
33 void isofs_put_super(struct super_block *sb)
34 {
35 lock_super(sb);
36
37 #ifdef LEAK_CHECK
38 printk("Outstanding mallocs:%d, outstanding buffers: %d\n",
39 check_malloc, check_bread);
40 #endif
41 sb->s_dev = 0;
42 unlock_super(sb);
43 MOD_DEC_USE_COUNT;
44 return;
45 }
46
47 static struct super_operations isofs_sops = {
48 isofs_read_inode,
49 NULL,
50 NULL,
51 NULL,
52 isofs_put_super,
53 NULL,
54 isofs_statfs,
55 NULL
56 };
57
58 struct iso9660_options{
59 char map;
60 char rock;
61 char cruft;
62 char unhide;
63 unsigned char check;
64 unsigned char conversion;
65 unsigned int blocksize;
66 mode_t mode;
67 gid_t gid;
68 uid_t uid;
69 };
70
71 static int parse_options(char *options, struct iso9660_options * popt)
72 {
73 char *this_char,*value;
74
75 popt->map = 'n';
76 popt->rock = 'y';
77 popt->cruft = 'n';
78 popt->unhide = 'n';
79 popt->check = 's';
80 popt->conversion = 'b';
81 popt->blocksize = 1024;
82 popt->mode = S_IRUGO;
83 popt->gid = 0;
84 popt->uid = 0;
85 if (!options) return 1;
86 for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
87 if (strncmp(this_char,"norock",6) == 0) {
88 popt->rock = 'n';
89 continue;
90 };
91 if (strncmp(this_char,"unhide",6) == 0) {
92 popt->unhide = 'y';
93 continue;
94 };
95 if (strncmp(this_char,"cruft",5) == 0) {
96 popt->cruft = 'y';
97 continue;
98 };
99 if ((value = strchr(this_char,'=')) != NULL)
100 *value++ = 0;
101 if (!strcmp(this_char,"map") && value) {
102 if (value[0] && !value[1] && strchr("on",*value))
103 popt->map = *value;
104 else if (!strcmp(value,"off")) popt->map = 'o';
105 else if (!strcmp(value,"normal")) popt->map = 'n';
106 else return 0;
107 }
108 else if (!strcmp(this_char,"check") && value) {
109 if (value[0] && !value[1] && strchr("rs",*value))
110 popt->check = *value;
111 else if (!strcmp(value,"relaxed")) popt->check = 'r';
112 else if (!strcmp(value,"strict")) popt->check = 's';
113 else return 0;
114 }
115 else if (!strcmp(this_char,"conv") && value) {
116 if (value[0] && !value[1] && strchr("btma",*value))
117 popt->conversion = *value;
118 else if (!strcmp(value,"binary")) popt->conversion = 'b';
119 else if (!strcmp(value,"text")) popt->conversion = 't';
120 else if (!strcmp(value,"mtext")) popt->conversion = 'm';
121 else if (!strcmp(value,"auto")) popt->conversion = 'a';
122 else return 0;
123 }
124 else if (value &&
125 (!strcmp(this_char,"block") ||
126 !strcmp(this_char,"mode") ||
127 !strcmp(this_char,"uid") ||
128 !strcmp(this_char,"gid"))) {
129 char * vpnt = value;
130 unsigned int ivalue;
131 ivalue = 0;
132 while(*vpnt){
133 if(*vpnt < '0' || *vpnt > '9') break;
134 ivalue = ivalue * 10 + (*vpnt - '0');
135 vpnt++;
136 };
137 if (*vpnt) return 0;
138 switch(*this_char) {
139 case 'b':
140 if ( ivalue != 512
141 && ivalue != 1024
142 && ivalue != 2048) return 0;
143 popt->blocksize = ivalue;
144 break;
145 case 'u':
146 popt->uid = ivalue;
147 break;
148 case 'g':
149 popt->gid = ivalue;
150 break;
151 case 'm':
152 popt->mode = ivalue;
153 break;
154 }
155 }
156 else return 1;
157 }
158 return 1;
159 }
160
161
162
163
164 static unsigned int isofs_get_last_session(kdev_t dev)
165 {
166 struct cdrom_multisession ms_info;
167 unsigned int vol_desc_start;
168 struct inode inode_fake;
169 extern struct file_operations * get_blkfops(unsigned int);
170 int i;
171
172 vol_desc_start=0;
173 if (get_blkfops(MAJOR(dev))->ioctl!=NULL)
174 {
175 inode_fake.i_rdev=dev;
176 ms_info.addr_format=CDROM_LBA;
177 set_fs(KERNEL_DS);
178 i=get_blkfops(MAJOR(dev))->ioctl(&inode_fake,
179 NULL,
180 CDROMMULTISESSION,
181 (unsigned long) &ms_info);
182 set_fs(USER_DS);
183 #if 0
184 printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);
185 if (i==0)
186 {
187 printk("isofs.inode: XA disk: %s\n", ms_info.xa_flag ? "yes":"no");
188 printk("isofs.inode: vol_desc_start = %d\n", ms_info.addr.lba);
189 }
190 #endif 0
191 if ((i==0)&&(ms_info.xa_flag)) vol_desc_start=ms_info.addr.lba;
192 }
193 return vol_desc_start;
194 }
195
196 struct super_block *isofs_read_super(struct super_block *s,void *data,
197 int silent)
198 {
199 struct buffer_head *bh=NULL;
200 int iso_blknum;
201 unsigned int blocksize_bits;
202 int high_sierra;
203 kdev_t dev = s->s_dev;
204 unsigned int vol_desc_start;
205 int orig_zonesize;
206
207 struct iso_volume_descriptor *vdp;
208 struct hs_volume_descriptor *hdp;
209
210 struct iso_primary_descriptor *pri = NULL;
211 struct hs_primary_descriptor *h_pri = NULL;
212
213 struct iso_directory_record *rootp;
214
215 struct iso9660_options opt;
216
217 MOD_INC_USE_COUNT;
218
219 if (!parse_options((char *) data,&opt)) {
220 s->s_dev = 0;
221 MOD_DEC_USE_COUNT;
222 return NULL;
223 }
224
225 #if 0
226 printk("map = %c\n", opt.map);
227 printk("rock = %c\n", opt.rock);
228 printk("check = %c\n", opt.check);
229 printk("cruft = %c\n", opt.cruft);
230 printk("unhide = %c\n", opt.unhide);
231 printk("conversion = %c\n", opt.conversion);
232 printk("blocksize = %d\n", opt.blocksize);
233 printk("gid = %d\n", opt.gid);
234 printk("uid = %d\n", opt.uid);
235 #endif
236
237 blocksize_bits = 0;
238 {
239 int i = opt.blocksize;
240 while (i != 1){
241 blocksize_bits++;
242 i >>=1;
243 };
244 };
245 set_blocksize(dev, opt.blocksize);
246
247 lock_super(s);
248
249 s->u.isofs_sb.s_high_sierra = high_sierra = 0;
250
251 vol_desc_start = isofs_get_last_session(dev);
252
253 for (iso_blknum = vol_desc_start+16; iso_blknum < vol_desc_start+100; iso_blknum++) {
254 #if 0
255 printk("isofs.inode: iso_blknum=%d\n", iso_blknum);
256 #endif 0
257 if (!(bh = bread(dev, iso_blknum << (ISOFS_BLOCK_BITS-blocksize_bits), opt.blocksize))) {
258 s->s_dev = 0;
259 printk("isofs_read_super: bread failed, dev "
260 "%s iso_blknum %d\n",
261 kdevname(dev), iso_blknum);
262 unlock_super(s);
263 MOD_DEC_USE_COUNT;
264 return NULL;
265 }
266
267 vdp = (struct iso_volume_descriptor *)bh->b_data;
268 hdp = (struct hs_volume_descriptor *)bh->b_data;
269
270
271 if (strncmp (hdp->id, HS_STANDARD_ID, sizeof hdp->id) == 0) {
272 if (isonum_711 (hdp->type) != ISO_VD_PRIMARY)
273 goto out;
274 if (isonum_711 (hdp->type) == ISO_VD_END)
275 goto out;
276
277 s->u.isofs_sb.s_high_sierra = 1;
278 high_sierra = 1;
279 opt.rock = 'n';
280 h_pri = (struct hs_primary_descriptor *)vdp;
281 break;
282 };
283
284 if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
285 if (isonum_711 (vdp->type) != ISO_VD_PRIMARY)
286 goto out;
287 if (isonum_711 (vdp->type) == ISO_VD_END)
288 goto out;
289
290 pri = (struct iso_primary_descriptor *)vdp;
291 break;
292 };
293
294 brelse(bh);
295 }
296 if(iso_blknum == vol_desc_start + 100) {
297 if (!silent)
298 printk("Unable to identify CD-ROM format.\n");
299 s->s_dev = 0;
300 unlock_super(s);
301 MOD_DEC_USE_COUNT;
302 return NULL;
303 };
304
305
306 if(high_sierra){
307 rootp = (struct iso_directory_record *) h_pri->root_directory_record;
308 if (isonum_723 (h_pri->volume_set_size) != 1) {
309 printk("Multi-volume disks not (yet) supported.\n");
310 goto out;
311 };
312 s->u.isofs_sb.s_nzones = isonum_733 (h_pri->volume_space_size);
313 s->u.isofs_sb.s_log_zone_size = isonum_723 (h_pri->logical_block_size);
314 s->u.isofs_sb.s_max_size = isonum_733(h_pri->volume_space_size);
315 } else {
316 rootp = (struct iso_directory_record *) pri->root_directory_record;
317 if (isonum_723 (pri->volume_set_size) != 1) {
318 printk("Multi-volume disks not (yet) supported.\n");
319 goto out;
320 };
321 s->u.isofs_sb.s_nzones = isonum_733 (pri->volume_space_size);
322 s->u.isofs_sb.s_log_zone_size = isonum_723 (pri->logical_block_size);
323 s->u.isofs_sb.s_max_size = isonum_733(pri->volume_space_size);
324 }
325
326 s->u.isofs_sb.s_ninodes = 0;
327
328
329
330 orig_zonesize = s -> u.isofs_sb.s_log_zone_size;
331 switch (s -> u.isofs_sb.s_log_zone_size)
332 { case 512: s -> u.isofs_sb.s_log_zone_size = 9; break;
333 case 1024: s -> u.isofs_sb.s_log_zone_size = 10; break;
334 case 2048: s -> u.isofs_sb.s_log_zone_size = 11; break;
335
336 default:
337 printk("Bad logical zone size %ld\n", s -> u.isofs_sb.s_log_zone_size);
338 goto out;
339 }
340
341
342
343 s->u.isofs_sb.s_firstdatazone = ((isonum_733 (rootp->extent) +
344 isonum_711 (rootp->ext_attr_length))
345 << s -> u.isofs_sb.s_log_zone_size);
346 s->s_magic = ISOFS_SUPER_MAGIC;
347
348
349
350
351
352
353 s->s_flags |= MS_RDONLY ;
354
355 brelse(bh);
356
357 printk(KERN_DEBUG "Max size:%ld Log zone size:%ld\n",
358 s->u.isofs_sb.s_max_size,
359 1UL << s->u.isofs_sb.s_log_zone_size);
360 printk(KERN_DEBUG "First datazone:%ld Root inode number %d\n",
361 s->u.isofs_sb.s_firstdatazone >> s -> u.isofs_sb.s_log_zone_size,
362 (isonum_733(rootp->extent) + isonum_711(rootp->ext_attr_length))
363 << s -> u.isofs_sb.s_log_zone_size);
364 if(high_sierra) printk(KERN_DEBUG "Disc in High Sierra format.\n");
365 unlock_super(s);
366
367
368
369
370
371
372
373 if( orig_zonesize < opt.blocksize )
374 {
375 opt.blocksize = orig_zonesize;
376 blocksize_bits = 0;
377 {
378 int i = opt.blocksize;
379 while (i != 1){
380 blocksize_bits++;
381 i >>=1;
382 }
383 }
384 set_blocksize(dev, opt.blocksize);
385 printk(KERN_DEBUG "Forcing new log zone size:%d\n", opt.blocksize);
386 }
387
388 s->s_dev = dev;
389 s->s_op = &isofs_sops;
390 s->u.isofs_sb.s_mapping = opt.map;
391 s->u.isofs_sb.s_rock = (opt.rock == 'y' ? 1 : 0);
392 s->u.isofs_sb.s_name_check = opt.check;
393 s->u.isofs_sb.s_conversion = opt.conversion;
394 s->u.isofs_sb.s_cruft = opt.cruft;
395 s->u.isofs_sb.s_unhide = opt.unhide;
396 s->u.isofs_sb.s_uid = opt.uid;
397 s->u.isofs_sb.s_gid = opt.gid;
398
399
400
401
402 s->u.isofs_sb.s_mode = opt.mode & 0777;
403 s->s_blocksize = opt.blocksize;
404 s->s_blocksize_bits = blocksize_bits;
405 s->s_mounted = iget(s, (isonum_733(rootp->extent) +
406 isonum_711(rootp->ext_attr_length))
407 << s -> u.isofs_sb.s_log_zone_size);
408 unlock_super(s);
409
410 if (!(s->s_mounted)) {
411 s->s_dev = 0;
412 printk("get root inode failed\n");
413 MOD_DEC_USE_COUNT;
414 return NULL;
415 }
416
417 if(!check_disk_change(s->s_dev)) {
418 return s;
419 }
420 out:
421 brelse(bh);
422 s->s_dev = 0;
423 unlock_super(s);
424 MOD_DEC_USE_COUNT;
425 return NULL;
426 }
427
428 void isofs_statfs (struct super_block *sb, struct statfs *buf, int bufsiz)
429 {
430 struct statfs tmp;
431
432 tmp.f_type = ISOFS_SUPER_MAGIC;
433 tmp.f_bsize = sb->s_blocksize;
434 tmp.f_blocks = (sb->u.isofs_sb.s_nzones
435 << (sb->u.isofs_sb.s_log_zone_size - sb->s_blocksize_bits));
436 tmp.f_bfree = 0;
437 tmp.f_bavail = 0;
438 tmp.f_files = sb->u.isofs_sb.s_ninodes;
439 tmp.f_ffree = 0;
440 tmp.f_namelen = NAME_MAX;
441 memcpy_tofs(buf, &tmp, bufsiz);
442 }
443
444 int isofs_bmap(struct inode * inode,int block)
445 {
446
447 if (block<0) {
448 printk("_isofs_bmap: block<0");
449 return 0;
450 }
451 return (inode->u.isofs_i.i_first_extent >> ISOFS_BUFFER_BITS(inode)) + block;
452 }
453
454 void isofs_read_inode(struct inode * inode)
455 {
456 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
457 struct buffer_head * bh;
458 struct iso_directory_record * raw_inode;
459 unsigned char *pnt = NULL;
460 void *cpnt = NULL;
461 int high_sierra;
462 int block;
463 int volume_seq_no ;
464 int i;
465
466 block = inode->i_ino >> ISOFS_BUFFER_BITS(inode);
467 if (!(bh=bread(inode->i_dev,block, bufsize))) {
468 printk("unable to read i-node block");
469 goto fail;
470 }
471
472 pnt = ((unsigned char *) bh->b_data
473 + (inode->i_ino & (bufsize - 1)));
474 raw_inode = ((struct iso_directory_record *) pnt);
475 high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
476
477 if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize){
478 int frag1, offset;
479
480 offset = (inode->i_ino & (bufsize - 1));
481 frag1 = bufsize - offset;
482 cpnt = kmalloc(*pnt,GFP_KERNEL);
483 if (cpnt == NULL) {
484 printk(KERN_INFO "NoMem ISO inode %lu\n",inode->i_ino);
485 brelse(bh);
486 goto fail;
487 }
488 memcpy(cpnt, bh->b_data + offset, frag1);
489 brelse(bh);
490 if (!(bh = bread(inode->i_dev,++block, bufsize))) {
491 kfree(cpnt);
492 printk("unable to read i-node block");
493 goto fail;
494 }
495 offset += *pnt - bufsize;
496 memcpy((char *)cpnt+frag1, bh->b_data, offset);
497 pnt = ((unsigned char *) cpnt);
498 raw_inode = ((struct iso_directory_record *) pnt);
499 }
500
501 if (raw_inode->flags[-high_sierra] & 2) {
502 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
503 inode->i_nlink = 1;
504
505
506
507
508 } else {
509 inode->i_mode = inode->i_sb->u.isofs_sb.s_mode;
510 inode->i_nlink = 1;
511 inode->i_mode |= S_IFREG;
512
513 for(i=0; i< raw_inode->name_len[0]; i++)
514 if(raw_inode->name[i]=='.' || raw_inode->name[i]==';')
515 break;
516 if(i == raw_inode->name_len[0] || raw_inode->name[i] == ';')
517 inode->i_mode |= S_IXUGO;
518 }
519 inode->i_uid = inode->i_sb->u.isofs_sb.s_uid;
520 inode->i_gid = inode->i_sb->u.isofs_sb.s_gid;
521 inode->i_size = isonum_733 (raw_inode->size);
522
523
524
525 if((inode->i_size < 0 || inode->i_size > 800000000) &&
526 inode->i_sb->u.isofs_sb.s_cruft == 'n') {
527 printk("Warning: defective cdrom. Enabling \"cruft\" mount option.\n");
528 inode->i_sb->u.isofs_sb.s_cruft = 'y';
529 }
530
531
532
533
534
535 if(inode->i_sb->u.isofs_sb.s_cruft == 'y' &&
536 inode->i_size & 0xff000000){
537
538 inode->i_size &= 0x00ffffff;
539 }
540
541 if (raw_inode->interleave[0]) {
542 printk("Interleaved files not (yet) supported.\n");
543 inode->i_size = 0;
544 }
545
546
547
548 if(raw_inode->file_unit_size[0] != 0){
549 printk("File unit size != 0 for ISO file (%ld).\n",inode->i_ino);
550 }
551
552
553
554 #ifdef DEBUG
555 if((raw_inode->flags[-high_sierra] & ~2)!= 0){
556 printk("Unusual flag settings for ISO file (%ld %x).\n",
557 inode->i_ino, raw_inode->flags[-high_sierra]);
558 }
559 #endif
560
561 #ifdef DEBUG
562 printk("Get inode %d: %d %d: %d\n",inode->i_ino, block,
563 ((int)pnt) & 0x3ff, inode->i_size);
564 #endif
565
566 inode->i_mtime = inode->i_atime = inode->i_ctime =
567 iso_date(raw_inode->date, high_sierra);
568
569 inode->u.isofs_i.i_first_extent = (isonum_733 (raw_inode->extent) +
570 isonum_711 (raw_inode->ext_attr_length))
571 << inode -> i_sb -> u.isofs_sb.s_log_zone_size;
572
573 inode->u.isofs_i.i_backlink = 0xffffffff;
574 switch (inode->i_sb->u.isofs_sb.s_conversion){
575 case 'a':
576 inode->u.isofs_i.i_file_format = ISOFS_FILE_UNKNOWN;
577 break;
578 case 'b':
579 inode->u.isofs_i.i_file_format = ISOFS_FILE_BINARY;
580 break;
581 case 't':
582 inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT;
583 break;
584 case 'm':
585 inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT_M;
586 break;
587 }
588
589
590
591
592 if (!high_sierra)
593 parse_rock_ridge_inode(raw_inode, inode);
594
595 #ifdef DEBUG
596 printk("Inode: %x extent: %x\n",inode->i_ino, inode->u.isofs_i.i_first_extent);
597 #endif
598 brelse(bh);
599
600 inode->i_op = NULL;
601
602
603 volume_seq_no = isonum_723 (raw_inode->volume_sequence_number) ;
604
605
606
607
608
609
610
611 if (inode->i_sb->u.isofs_sb.s_cruft == 'n' &&
612 (volume_seq_no != 0) && (volume_seq_no != 1)) {
613 printk("Warning: defective cdrom. Enabling \"cruft\" mount option.\n");
614 inode->i_sb->u.isofs_sb.s_cruft = 'y';
615 }
616
617 if (inode->i_sb->u.isofs_sb.s_cruft != 'y' &&
618 (volume_seq_no != 0) && (volume_seq_no != 1)) {
619 printk("Multi volume CD somehow got mounted.\n");
620 } else {
621 if (S_ISREG(inode->i_mode))
622 inode->i_op = &isofs_file_inode_operations;
623 else if (S_ISDIR(inode->i_mode))
624 inode->i_op = &isofs_dir_inode_operations;
625 else if (S_ISLNK(inode->i_mode))
626 inode->i_op = &isofs_symlink_inode_operations;
627 else if (S_ISCHR(inode->i_mode))
628 inode->i_op = &chrdev_inode_operations;
629 else if (S_ISBLK(inode->i_mode))
630 inode->i_op = &blkdev_inode_operations;
631 else if (S_ISFIFO(inode->i_mode))
632 init_fifo(inode);
633 }
634 if (cpnt) {
635 kfree (cpnt);
636 cpnt = NULL;
637 }
638 return;
639 fail:
640
641 inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
642 inode->u.isofs_i.i_first_extent = 0;
643 inode->u.isofs_i.i_backlink = 0xffffffff;
644 inode->i_size = 0;
645 inode->i_nlink = 1;
646 inode->i_uid = inode->i_gid = 0;
647 inode->i_mode = S_IFREG;
648 inode->i_op = NULL;
649 return;
650 }
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671 int isofs_lookup_grandparent(struct inode * parent, int extent)
672 {
673 unsigned long bufsize = ISOFS_BUFFER_SIZE(parent);
674 unsigned char bufbits = ISOFS_BUFFER_BITS(parent);
675 unsigned int block,offset;
676 int parent_dir, inode_number;
677 int old_offset;
678 void * cpnt = NULL;
679 int result;
680 int directory_size;
681 struct buffer_head * bh;
682 struct iso_directory_record * de;
683
684 offset = 0;
685 block = extent << (ISOFS_ZONE_BITS(parent) - bufbits);
686 if (!(bh = bread(parent->i_dev, block, bufsize))) return -1;
687
688 while (1 == 1) {
689 de = (struct iso_directory_record *) (bh->b_data + offset);
690 if (*((unsigned char *) de) == 0)
691 {
692 brelse(bh);
693 printk("Directory .. not found\n");
694 return -1;
695 }
696
697 offset += *((unsigned char *) de);
698
699 if (offset >= bufsize)
700 {
701 printk(".. Directory not in first block"
702 " of directory.\n");
703 brelse(bh);
704 return -1;
705 }
706
707 if (de->name_len[0] == 1 && de->name[0] == 1)
708 {
709 parent_dir = find_rock_ridge_relocation(de, parent);
710 directory_size = isonum_733 (de->size);
711 brelse(bh);
712 break;
713 }
714 }
715 #ifdef DEBUG
716 printk("Parent dir:%x\n",parent_dir);
717 #endif
718
719
720 result = -1;
721
722 offset = 0;
723 block = parent_dir << (ISOFS_ZONE_BITS(parent) - bufbits);
724 if (!block || !(bh = bread(parent->i_dev,block, bufsize)))
725 {
726 return -1;
727 }
728
729 for(;;)
730 {
731 de = (struct iso_directory_record *) (bh->b_data + offset);
732 inode_number = (block << bufbits)+(offset & (bufsize - 1));
733
734
735
736
737
738 if (*((unsigned char *) de) == 0)
739 {
740 brelse(bh);
741 offset = 0;
742 block++;
743 directory_size -= bufsize;
744 if(directory_size < 0) return -1;
745 if((block & 1) && (ISOFS_ZONE_BITS(parent) - bufbits) == 1)
746 {
747 return -1;
748 }
749 if((block & 3) && (ISOFS_ZONE_BITS(parent) - bufbits) == 2)
750 {
751 return -1;
752 }
753 if (!block
754 || !(bh = bread(parent->i_dev,block, bufsize)))
755 {
756 return -1;
757 }
758 continue;
759 }
760
761
762
763
764
765 old_offset = offset;
766 offset += *((unsigned char *) de);
767
768 if (offset >= bufsize)
769 {
770 unsigned int frag1;
771 frag1 = bufsize - old_offset;
772 cpnt = kmalloc(*((unsigned char *) de),GFP_KERNEL);
773 if (!cpnt) return -1;
774 memcpy(cpnt, bh->b_data + old_offset, frag1);
775 de = (struct iso_directory_record *) ((char *)cpnt);
776 brelse(bh);
777 offset -= bufsize;
778 directory_size -= bufsize;
779 if(directory_size < 0)
780 {
781 printk("Directory size < 0\n");
782 return -1;
783 }
784 block++;
785 if(!(bh = bread(parent->i_dev,block,bufsize))) {
786 kfree(cpnt);
787 return -1;
788 };
789 memcpy((char *)cpnt+frag1, bh->b_data, offset);
790 }
791
792 if (find_rock_ridge_relocation(de, parent) == extent){
793 result = inode_number;
794 goto out;
795 }
796
797 if (cpnt) {
798 kfree(cpnt);
799 cpnt = NULL;
800 }
801 }
802
803
804
805
806 out:
807 if (cpnt) {
808 kfree(cpnt);
809 cpnt = NULL;
810 }
811 brelse(bh);
812 #ifdef DEBUG
813 printk("Resultant Inode %d\n",result);
814 #endif
815 return result;
816 }
817
818 #ifdef LEAK_CHECK
819 #undef malloc
820 #undef free_s
821 #undef bread
822 #undef brelse
823
824 void * leak_check_malloc(unsigned int size){
825 void * tmp;
826 check_malloc++;
827 tmp = kmalloc(size, GFP_KERNEL);
828 return tmp;
829 }
830
831 void leak_check_free_s(void * obj, int size){
832 check_malloc--;
833 return kfree_s(obj, size);
834 }
835
836 struct buffer_head * leak_check_bread(int dev, int block, int size){
837 check_bread++;
838 return bread(dev, block, size);
839 }
840
841 void leak_check_brelse(struct buffer_head * bh){
842 check_bread--;
843 return brelse(bh);
844 }
845
846 #endif
847
848 static struct file_system_type iso9660_fs_type = {
849 isofs_read_super, "iso9660", 1, NULL
850 };
851
852 int init_iso9660_fs(void)
853 {
854 return register_filesystem(&iso9660_fs_type);
855 }
856
857 #ifdef MODULE
858 int init_module(void)
859 {
860 int status;
861
862 if ((status = init_iso9660_fs()) == 0)
863 register_symtab(0);
864 return status;
865 }
866
867 void cleanup_module(void)
868 {
869 unregister_filesystem(&iso9660_fs_type);
870 }
871
872 #endif
873