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 = 1 << ISOFS_BLOCK_BITS;
434 tmp.f_blocks = sb->u.isofs_sb.s_nzones;
435 tmp.f_bfree = 0;
436 tmp.f_bavail = 0;
437 tmp.f_files = sb->u.isofs_sb.s_ninodes;
438 tmp.f_ffree = 0;
439 tmp.f_namelen = NAME_MAX;
440 memcpy_tofs(buf, &tmp, bufsiz);
441 }
442
443 int isofs_bmap(struct inode * inode,int block)
444 {
445
446 if (block<0) {
447 printk("_isofs_bmap: block<0");
448 return 0;
449 }
450 return (inode->u.isofs_i.i_first_extent >> ISOFS_BUFFER_BITS(inode)) + block;
451 }
452
453 void isofs_read_inode(struct inode * inode)
454 {
455 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
456 struct buffer_head * bh;
457 struct iso_directory_record * raw_inode;
458 unsigned char *pnt = NULL;
459 void *cpnt = NULL;
460 int high_sierra;
461 int block;
462 int volume_seq_no ;
463 int i;
464
465 block = inode->i_ino >> ISOFS_BUFFER_BITS(inode);
466 if (!(bh=bread(inode->i_dev,block, bufsize))) {
467 printk("unable to read i-node block");
468 goto fail;
469 }
470
471 pnt = ((unsigned char *) bh->b_data
472 + (inode->i_ino & (bufsize - 1)));
473 raw_inode = ((struct iso_directory_record *) pnt);
474 high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
475
476 if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize){
477 int frag1, offset;
478
479 offset = (inode->i_ino & (bufsize - 1));
480 frag1 = bufsize - offset;
481 cpnt = kmalloc(*pnt,GFP_KERNEL);
482 if (cpnt == NULL) {
483 printk(KERN_INFO "NoMem ISO inode %lu\n",inode->i_ino);
484 brelse(bh);
485 goto fail;
486 }
487 memcpy(cpnt, bh->b_data + offset, frag1);
488 brelse(bh);
489 if (!(bh = bread(inode->i_dev,++block, bufsize))) {
490 kfree(cpnt);
491 printk("unable to read i-node block");
492 goto fail;
493 }
494 offset += *pnt - bufsize;
495 memcpy((char *)cpnt+frag1, bh->b_data, offset);
496 pnt = ((unsigned char *) cpnt);
497 raw_inode = ((struct iso_directory_record *) pnt);
498 }
499
500 if (raw_inode->flags[-high_sierra] & 2) {
501 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
502 inode->i_nlink = 1;
503
504
505
506
507 } else {
508 inode->i_mode = inode->i_sb->u.isofs_sb.s_mode;
509 inode->i_nlink = 1;
510 inode->i_mode |= S_IFREG;
511
512 for(i=0; i< raw_inode->name_len[0]; i++)
513 if(raw_inode->name[i]=='.' || raw_inode->name[i]==';')
514 break;
515 if(i == raw_inode->name_len[0] || raw_inode->name[i] == ';')
516 inode->i_mode |= S_IXUGO;
517 }
518 inode->i_uid = inode->i_sb->u.isofs_sb.s_uid;
519 inode->i_gid = inode->i_sb->u.isofs_sb.s_gid;
520 inode->i_size = isonum_733 (raw_inode->size);
521
522
523
524 if((inode->i_size < 0 || inode->i_size > 800000000) &&
525 inode->i_sb->u.isofs_sb.s_cruft == 'n') {
526 printk("Warning: defective cdrom. Enabling \"cruft\" mount option.\n");
527 inode->i_sb->u.isofs_sb.s_cruft = 'y';
528 }
529
530
531
532
533
534 if(inode->i_sb->u.isofs_sb.s_cruft == 'y' &&
535 inode->i_size & 0xff000000){
536
537 inode->i_size &= 0x00ffffff;
538 }
539
540 if (raw_inode->interleave[0]) {
541 printk("Interleaved files not (yet) supported.\n");
542 inode->i_size = 0;
543 }
544
545
546
547 if(raw_inode->file_unit_size[0] != 0){
548 printk("File unit size != 0 for ISO file (%ld).\n",inode->i_ino);
549 }
550
551
552
553 #ifdef DEBUG
554 if((raw_inode->flags[-high_sierra] & ~2)!= 0){
555 printk("Unusual flag settings for ISO file (%ld %x).\n",
556 inode->i_ino, raw_inode->flags[-high_sierra]);
557 }
558 #endif
559
560 #ifdef DEBUG
561 printk("Get inode %d: %d %d: %d\n",inode->i_ino, block,
562 ((int)pnt) & 0x3ff, inode->i_size);
563 #endif
564
565 inode->i_mtime = inode->i_atime = inode->i_ctime =
566 iso_date(raw_inode->date, high_sierra);
567
568 inode->u.isofs_i.i_first_extent = (isonum_733 (raw_inode->extent) +
569 isonum_711 (raw_inode->ext_attr_length))
570 << inode -> i_sb -> u.isofs_sb.s_log_zone_size;
571
572 inode->u.isofs_i.i_backlink = 0xffffffff;
573 switch (inode->i_sb->u.isofs_sb.s_conversion){
574 case 'a':
575 inode->u.isofs_i.i_file_format = ISOFS_FILE_UNKNOWN;
576 break;
577 case 'b':
578 inode->u.isofs_i.i_file_format = ISOFS_FILE_BINARY;
579 break;
580 case 't':
581 inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT;
582 break;
583 case 'm':
584 inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT_M;
585 break;
586 }
587
588
589
590
591 if (!high_sierra)
592 parse_rock_ridge_inode(raw_inode, inode);
593
594 #ifdef DEBUG
595 printk("Inode: %x extent: %x\n",inode->i_ino, inode->u.isofs_i.i_first_extent);
596 #endif
597 brelse(bh);
598
599 inode->i_op = NULL;
600
601
602 volume_seq_no = isonum_723 (raw_inode->volume_sequence_number) ;
603
604
605
606
607
608
609
610 if (inode->i_sb->u.isofs_sb.s_cruft == 'n' &&
611 (volume_seq_no != 0) && (volume_seq_no != 1)) {
612 printk("Warning: defective cdrom. Enabling \"cruft\" mount option.\n");
613 inode->i_sb->u.isofs_sb.s_cruft = 'y';
614 }
615
616 if (inode->i_sb->u.isofs_sb.s_cruft != 'y' &&
617 (volume_seq_no != 0) && (volume_seq_no != 1)) {
618 printk("Multi volume CD somehow got mounted.\n");
619 } else {
620 if (S_ISREG(inode->i_mode))
621 inode->i_op = &isofs_file_inode_operations;
622 else if (S_ISDIR(inode->i_mode))
623 inode->i_op = &isofs_dir_inode_operations;
624 else if (S_ISLNK(inode->i_mode))
625 inode->i_op = &isofs_symlink_inode_operations;
626 else if (S_ISCHR(inode->i_mode))
627 inode->i_op = &chrdev_inode_operations;
628 else if (S_ISBLK(inode->i_mode))
629 inode->i_op = &blkdev_inode_operations;
630 else if (S_ISFIFO(inode->i_mode))
631 init_fifo(inode);
632 }
633 if (cpnt) {
634 kfree (cpnt);
635 cpnt = NULL;
636 }
637 return;
638 fail:
639
640 inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
641 inode->u.isofs_i.i_first_extent = 0;
642 inode->u.isofs_i.i_backlink = 0xffffffff;
643 inode->i_size = 0;
644 inode->i_nlink = 1;
645 inode->i_uid = inode->i_gid = 0;
646 inode->i_mode = S_IFREG;
647 inode->i_op = NULL;
648 return;
649 }
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670 int isofs_lookup_grandparent(struct inode * parent, int extent)
671 {
672 unsigned long bufsize = ISOFS_BUFFER_SIZE(parent);
673 unsigned char bufbits = ISOFS_BUFFER_BITS(parent);
674 unsigned int block,offset;
675 int parent_dir, inode_number;
676 int old_offset;
677 void * cpnt = NULL;
678 int result;
679 int directory_size;
680 struct buffer_head * bh;
681 struct iso_directory_record * de;
682
683 offset = 0;
684 block = extent << (ISOFS_BLOCK_BITS - bufbits);
685 if (!(bh = bread(parent->i_dev, block, bufsize))) return -1;
686
687 while (1 == 1) {
688 de = (struct iso_directory_record *) (bh->b_data + offset);
689 if (*((unsigned char *) de) == 0)
690 {
691 brelse(bh);
692 return -1;
693 }
694
695 offset += *((unsigned char *) de);
696
697 if (offset >= bufsize)
698 {
699 printk(".. Directory not in first block"
700 " of directory.\n");
701 brelse(bh);
702 return -1;
703 }
704
705 if (de->name_len[0] == 1 && de->name[0] == 1)
706 {
707 parent_dir = find_rock_ridge_relocation(de, parent);
708 directory_size = isonum_733 (de->size);
709 brelse(bh);
710 break;
711 }
712 }
713 #ifdef DEBUG
714 printk("Parent dir:%x\n",parent_dir);
715 #endif
716
717
718 result = -1;
719
720 offset = 0;
721 block = parent_dir << (ISOFS_BLOCK_BITS - bufbits);
722 if (!block || !(bh = bread(parent->i_dev,block, bufsize)))
723 return -1;
724
725 for(;;)
726 {
727 de = (struct iso_directory_record *) (bh->b_data + offset);
728 inode_number = (block << bufbits)+(offset & (bufsize - 1));
729
730
731
732
733
734 if (*((unsigned char *) de) == 0)
735 {
736 brelse(bh);
737 offset = 0;
738 block++;
739 directory_size -= bufsize;
740 if(directory_size < 0) return -1;
741 if((block & 1) && (ISOFS_BLOCK_BITS - bufbits))
742 return -1;
743 if (!block
744 || !(bh = bread(parent->i_dev,block, bufsize)))
745 return -1;
746 continue;
747 }
748
749
750
751
752
753 old_offset = offset;
754 offset += *((unsigned char *) de);
755
756 if (offset >= bufsize)
757 {
758 unsigned int frag1;
759 frag1 = bufsize - old_offset;
760 cpnt = kmalloc(*((unsigned char *) de),GFP_KERNEL);
761 if (!cpnt) return -1;
762 memcpy(cpnt, bh->b_data + old_offset, frag1);
763 de = (struct iso_directory_record *) ((char *)cpnt);
764 brelse(bh);
765 offset -= bufsize;
766 directory_size -= bufsize;
767 if(directory_size < 0) return -1;
768 block++;
769 if(!(bh = bread(parent->i_dev,block,bufsize))) {
770 kfree(cpnt);
771 return -1;
772 };
773 memcpy((char *)cpnt+frag1, bh->b_data, offset);
774 }
775
776 if (find_rock_ridge_relocation(de, parent) == extent){
777 result = inode_number;
778 goto out;
779 }
780
781 if (cpnt) {
782 kfree(cpnt);
783 cpnt = NULL;
784 }
785 }
786
787
788
789
790 out:
791 if (cpnt) {
792 kfree(cpnt);
793 cpnt = NULL;
794 }
795 brelse(bh);
796 #ifdef DEBUG
797 printk("Resultant Inode %d\n",result);
798 #endif
799 return result;
800 }
801
802 #ifdef LEAK_CHECK
803 #undef malloc
804 #undef free_s
805 #undef bread
806 #undef brelse
807
808 void * leak_check_malloc(unsigned int size){
809 void * tmp;
810 check_malloc++;
811 tmp = kmalloc(size, GFP_KERNEL);
812 return tmp;
813 }
814
815 void leak_check_free_s(void * obj, int size){
816 check_malloc--;
817 return kfree_s(obj, size);
818 }
819
820 struct buffer_head * leak_check_bread(int dev, int block, int size){
821 check_bread++;
822 return bread(dev, block, size);
823 }
824
825 void leak_check_brelse(struct buffer_head * bh){
826 check_bread--;
827 return brelse(bh);
828 }
829
830 #endif
831
832 static struct file_system_type iso9660_fs_type = {
833 isofs_read_super, "iso9660", 1, NULL
834 };
835
836 int init_iso9660_fs(void)
837 {
838 return register_filesystem(&iso9660_fs_type);
839 }
840
841 #ifdef MODULE
842 int init_module(void)
843 {
844 int status;
845
846 if ((status = init_iso9660_fs()) == 0)
847 register_symtab(0);
848 return status;
849 }
850
851 void cleanup_module(void)
852 {
853 unregister_filesystem(&iso9660_fs_type);
854 }
855
856 #endif
857