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