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