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