1
2
3
4
5
6
7
8
9
10
11
12
13
14#include <linux/init.h>
15#include <linux/module.h>
16
17#include <linux/slab.h>
18#include <linux/nls.h>
19#include <linux/ctype.h>
20#include <linux/smp_lock.h>
21#include <linux/statfs.h>
22#include <linux/cdrom.h>
23#include <linux/parser.h>
24
25#include "isofs.h"
26#include "zisofs.h"
27
28#define BEQUIET
29
30static int isofs_hashi(struct dentry *parent, struct qstr *qstr);
31static int isofs_hash(struct dentry *parent, struct qstr *qstr);
32static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
33static int isofs_dentry_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
34
35#ifdef CONFIG_JOLIET
36static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr);
37static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr);
38static int isofs_dentry_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
39static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
40#endif
41
42static void isofs_put_super(struct super_block *sb)
43{
44 struct isofs_sb_info *sbi = ISOFS_SB(sb);
45#ifdef CONFIG_JOLIET
46 if (sbi->s_nls_iocharset) {
47 unload_nls(sbi->s_nls_iocharset);
48 sbi->s_nls_iocharset = NULL;
49 }
50#endif
51
52 kfree(sbi);
53 sb->s_fs_info = NULL;
54 return;
55}
56
57static void isofs_read_inode(struct inode *);
58static int isofs_statfs (struct dentry *, struct kstatfs *);
59
60static kmem_cache_t *isofs_inode_cachep;
61
62static struct inode *isofs_alloc_inode(struct super_block *sb)
63{
64 struct iso_inode_info *ei;
65 ei = kmem_cache_alloc(isofs_inode_cachep, SLAB_KERNEL);
66 if (!ei)
67 return NULL;
68 return &ei->vfs_inode;
69}
70
71static void isofs_destroy_inode(struct inode *inode)
72{
73 kmem_cache_free(isofs_inode_cachep, ISOFS_I(inode));
74}
75
76static void init_once(void *foo, kmem_cache_t * cachep, unsigned long flags)
77{
78 struct iso_inode_info *ei = foo;
79
80 if ((flags & (SLAB_CTOR_VERIFY|SLAB_CTOR_CONSTRUCTOR)) ==
81 SLAB_CTOR_CONSTRUCTOR)
82 inode_init_once(&ei->vfs_inode);
83}
84
85static int init_inodecache(void)
86{
87 isofs_inode_cachep = kmem_cache_create("isofs_inode_cache",
88 sizeof(struct iso_inode_info),
89 0, (SLAB_RECLAIM_ACCOUNT|
90 SLAB_MEM_SPREAD),
91 init_once, NULL);
92 if (isofs_inode_cachep == NULL)
93 return -ENOMEM;
94 return 0;
95}
96
97static void destroy_inodecache(void)
98{
99 if (kmem_cache_destroy(isofs_inode_cachep))
100 printk(KERN_INFO "iso_inode_cache: not all structures were "
101 "freed\n");
102}
103
104static int isofs_remount(struct super_block *sb, int *flags, char *data)
105{
106
107 *flags |= MS_RDONLY;
108 return 0;
109}
110
111static struct super_operations isofs_sops = {
112 .alloc_inode = isofs_alloc_inode,
113 .destroy_inode = isofs_destroy_inode,
114 .read_inode = isofs_read_inode,
115 .put_super = isofs_put_super,
116 .statfs = isofs_statfs,
117 .remount_fs = isofs_remount,
118};
119
120
121static struct dentry_operations isofs_dentry_ops[] = {
122 {
123 .d_hash = isofs_hash,
124 .d_compare = isofs_dentry_cmp,
125 },
126 {
127 .d_hash = isofs_hashi,
128 .d_compare = isofs_dentry_cmpi,
129 },
130#ifdef CONFIG_JOLIET
131 {
132 .d_hash = isofs_hash_ms,
133 .d_compare = isofs_dentry_cmp_ms,
134 },
135 {
136 .d_hash = isofs_hashi_ms,
137 .d_compare = isofs_dentry_cmpi_ms,
138 },
139#endif
140};
141
142struct iso9660_options{
143 char map;
144 char rock;
145 char joliet;
146 char cruft;
147 char hide;
148 char showassoc;
149 char nocompress;
150 unsigned char check;
151 unsigned int blocksize;
152 mode_t mode;
153 gid_t gid;
154 uid_t uid;
155 char *iocharset;
156 unsigned char utf8;
157
158 s32 session;
159 s32 sbsector;
160};
161
162
163
164
165static int
166isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms)
167{
168 const char *name;
169 int len;
170
171 len = qstr->len;
172 name = qstr->name;
173 if (ms) {
174 while (len && name[len-1] == '.')
175 len--;
176 }
177
178 qstr->hash = full_name_hash(name, len);
179
180 return 0;
181}
182
183
184
185
186static int
187isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms)
188{
189 const char *name;
190 int len;
191 char c;
192 unsigned long hash;
193
194 len = qstr->len;
195 name = qstr->name;
196 if (ms) {
197 while (len && name[len-1] == '.')
198 len--;
199 }
200
201 hash = init_name_hash();
202 while (len--) {
203 c = tolower(*name++);
204 hash = partial_name_hash(tolower(c), hash);
205 }
206 qstr->hash = end_name_hash(hash);
207
208 return 0;
209}
210
211
212
213
214static int isofs_dentry_cmpi_common(struct dentry *dentry, struct qstr *a,
215 struct qstr *b, int ms)
216{
217 int alen, blen;
218
219
220 alen = a->len;
221 blen = b->len;
222 if (ms) {
223 while (alen && a->name[alen-1] == '.')
224 alen--;
225 while (blen && b->name[blen-1] == '.')
226 blen--;
227 }
228 if (alen == blen) {
229 if (strnicmp(a->name, b->name, alen) == 0)
230 return 0;
231 }
232 return 1;
233}
234
235
236
237
238static int isofs_dentry_cmp_common(struct dentry *dentry, struct qstr *a,
239 struct qstr *b, int ms)
240{
241 int alen, blen;
242
243
244 alen = a->len;
245 blen = b->len;
246 if (ms) {
247 while (alen && a->name[alen-1] == '.')
248 alen--;
249 while (blen && b->name[blen-1] == '.')
250 blen--;
251 }
252 if (alen == blen) {
253 if (strncmp(a->name, b->name, alen) == 0)
254 return 0;
255 }
256 return 1;
257}
258
259static int
260isofs_hash(struct dentry *dentry, struct qstr *qstr)
261{
262 return isofs_hash_common(dentry, qstr, 0);
263}
264
265static int
266isofs_hashi(struct dentry *dentry, struct qstr *qstr)
267{
268 return isofs_hashi_common(dentry, qstr, 0);
269}
270
271static int
272isofs_dentry_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b)
273{
274 return isofs_dentry_cmp_common(dentry, a, b, 0);
275}
276
277static int
278isofs_dentry_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b)
279{
280 return isofs_dentry_cmpi_common(dentry, a, b, 0);
281}
282
283#ifdef CONFIG_JOLIET
284static int
285isofs_hash_ms(struct dentry *dentry, struct qstr *qstr)
286{
287 return isofs_hash_common(dentry, qstr, 1);
288}
289
290static int
291isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr)
292{
293 return isofs_hashi_common(dentry, qstr, 1);
294}
295
296static int
297isofs_dentry_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
298{
299 return isofs_dentry_cmp_common(dentry, a, b, 1);
300}
301
302static int
303isofs_dentry_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
304{
305 return isofs_dentry_cmpi_common(dentry, a, b, 1);
306}
307#endif
308
309enum {
310 Opt_block, Opt_check_r, Opt_check_s, Opt_cruft, Opt_gid, Opt_ignore,
311 Opt_iocharset, Opt_map_a, Opt_map_n, Opt_map_o, Opt_mode, Opt_nojoliet,
312 Opt_norock, Opt_sb, Opt_session, Opt_uid, Opt_unhide, Opt_utf8, Opt_err,
313 Opt_nocompress, Opt_hide, Opt_showassoc,
314};
315
316static match_table_t tokens = {
317 {Opt_norock, "norock"},
318 {Opt_nojoliet, "nojoliet"},
319 {Opt_unhide, "unhide"},
320 {Opt_hide, "hide"},
321 {Opt_showassoc, "showassoc"},
322 {Opt_cruft, "cruft"},
323 {Opt_utf8, "utf8"},
324 {Opt_iocharset, "iocharset=%s"},
325 {Opt_map_a, "map=acorn"},
326 {Opt_map_a, "map=a"},
327 {Opt_map_n, "map=normal"},
328 {Opt_map_n, "map=n"},
329 {Opt_map_o, "map=off"},
330 {Opt_map_o, "map=o"},
331 {Opt_session, "session=%u"},
332 {Opt_sb, "sbsector=%u"},
333 {Opt_check_r, "check=relaxed"},
334 {Opt_check_r, "check=r"},
335 {Opt_check_s, "check=strict"},
336 {Opt_check_s, "check=s"},
337 {Opt_uid, "uid=%u"},
338 {Opt_gid, "gid=%u"},
339 {Opt_mode, "mode=%u"},
340 {Opt_block, "block=%u"},
341 {Opt_ignore, "conv=binary"},
342 {Opt_ignore, "conv=b"},
343 {Opt_ignore, "conv=text"},
344 {Opt_ignore, "conv=t"},
345 {Opt_ignore, "conv=mtext"},
346 {Opt_ignore, "conv=m"},
347 {Opt_ignore, "conv=auto"},
348 {Opt_ignore, "conv=a"},
349 {Opt_nocompress, "nocompress"},
350 {Opt_err, NULL}
351};
352
353static int parse_options(char *options, struct iso9660_options *popt)
354{
355 char *p;
356 int option;
357
358 popt->map = 'n';
359 popt->rock = 'y';
360 popt->joliet = 'y';
361 popt->cruft = 'n';
362 popt->hide = 'n';
363 popt->showassoc = 'n';
364 popt->check = 'u';
365 popt->nocompress = 0;
366 popt->blocksize = 1024;
367 popt->mode = S_IRUGO | S_IXUGO;
368
369
370
371 popt->gid = 0;
372 popt->uid = 0;
373 popt->iocharset = NULL;
374 popt->utf8 = 0;
375 popt->session=-1;
376 popt->sbsector=-1;
377 if (!options)
378 return 1;
379
380 while ((p = strsep(&options, ",")) != NULL) {
381 int token;
382 substring_t args[MAX_OPT_ARGS];
383 unsigned n;
384
385 if (!*p)
386 continue;
387
388 token = match_token(p, tokens, args);
389 switch (token) {
390 case Opt_norock:
391 popt->rock = 'n';
392 break;
393 case Opt_nojoliet:
394 popt->joliet = 'n';
395 break;
396 case Opt_hide:
397 popt->hide = 'y';
398 break;
399 case Opt_unhide:
400 case Opt_showassoc:
401 popt->showassoc = 'y';
402 break;
403 case Opt_cruft:
404 popt->cruft = 'y';
405 break;
406 case Opt_utf8:
407 popt->utf8 = 1;
408 break;
409#ifdef CONFIG_JOLIET
410 case Opt_iocharset:
411 popt->iocharset = match_strdup(&args[0]);
412 break;
413#endif
414 case Opt_map_a:
415 popt->map = 'a';
416 break;
417 case Opt_map_o:
418 popt->map = 'o';
419 break;
420 case Opt_map_n:
421 popt->map = 'n';
422 break;
423 case Opt_session:
424 if (match_int(&args[0], &option))
425 return 0;
426 n = option;
427 if (n > 99)
428 return 0;
429 popt->session = n + 1;
430 break;
431 case Opt_sb:
432 if (match_int(&args[0], &option))
433 return 0;
434 popt->sbsector = option;
435 break;
436 case Opt_check_r:
437 popt->check = 'r';
438 break;
439 case Opt_check_s:
440 popt->check = 's';
441 break;
442 case Opt_ignore:
443 break;
444 case Opt_uid:
445 if (match_int(&args[0], &option))
446 return 0;
447 popt->uid = option;
448 break;
449 case Opt_gid:
450 if (match_int(&args[0], &option))
451 return 0;
452 popt->gid = option;
453 break;
454 case Opt_mode:
455 if (match_int(&args[0], &option))
456 return 0;
457 popt->mode = option;
458 break;
459 case Opt_block:
460 if (match_int(&args[0], &option))
461 return 0;
462 n = option;
463 if (n != 512 && n != 1024 && n != 2048)
464 return 0;
465 popt->blocksize = n;
466 break;
467 case Opt_nocompress:
468 popt->nocompress = 1;
469 break;
470 default:
471 return 0;
472 }
473 }
474 return 1;
475}
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493#define WE_OBEY_THE_WRITTEN_STANDARDS 1
494
495static unsigned int isofs_get_last_session(struct super_block *sb, s32 session)
496{
497 struct cdrom_multisession ms_info;
498 unsigned int vol_desc_start;
499 struct block_device *bdev = sb->s_bdev;
500 int i;
501
502 vol_desc_start=0;
503 ms_info.addr_format=CDROM_LBA;
504 if(session >= 0 && session <= 99) {
505 struct cdrom_tocentry Te;
506 Te.cdte_track=session;
507 Te.cdte_format=CDROM_LBA;
508 i = ioctl_by_bdev(bdev, CDROMREADTOCENTRY, (unsigned long) &Te);
509 if (!i) {
510 printk(KERN_DEBUG "Session %d start %d type %d\n",
511 session, Te.cdte_addr.lba,
512 Te.cdte_ctrl&CDROM_DATA_TRACK);
513 if ((Te.cdte_ctrl&CDROM_DATA_TRACK) == 4)
514 return Te.cdte_addr.lba;
515 }
516
517 printk(KERN_ERR "Invalid session number or type of track\n");
518 }
519 i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info);
520 if (session > 0)
521 printk(KERN_ERR "Invalid session number\n");
522#if 0
523 printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);
524 if (i==0) {
525 printk("isofs.inode: XA disk: %s\n",ms_info.xa_flag?"yes":"no");
526 printk("isofs.inode: vol_desc_start = %d\n", ms_info.addr.lba);
527 }
528#endif
529 if (i==0)
530#if WE_OBEY_THE_WRITTEN_STANDARDS
531 if (ms_info.xa_flag)
532#endif
533 vol_desc_start=ms_info.addr.lba;
534 return vol_desc_start;
535}
536
537
538
539
540
541
542
543static int isofs_fill_super(struct super_block *s, void *data, int silent)
544{
545 struct buffer_head * bh = NULL, *pri_bh = NULL;
546 struct hs_primary_descriptor * h_pri = NULL;
547 struct iso_primary_descriptor * pri = NULL;
548 struct iso_supplementary_descriptor *sec = NULL;
549 struct iso_directory_record * rootp;
550 int joliet_level = 0;
551 int iso_blknum, block;
552 int orig_zonesize;
553 int table;
554 unsigned int vol_desc_start;
555 unsigned long first_data_zone;
556 struct inode * inode;
557 struct iso9660_options opt;
558 struct isofs_sb_info * sbi;
559
560 sbi = kmalloc(sizeof(*sbi), GFP_KERNEL);
561 if (!sbi)
562 return -ENOMEM;
563 s->s_fs_info = sbi;
564 memset(sbi, 0, sizeof(*sbi));
565
566 if (!parse_options((char *)data, &opt))
567 goto out_freesbi;
568
569
570
571
572
573
574
575
576
577
578 opt.blocksize = sb_min_blocksize(s, opt.blocksize);
579
580 sbi->s_high_sierra = 0;
581
582 vol_desc_start = (opt.sbsector != -1) ?
583 opt.sbsector : isofs_get_last_session(s,opt.session);
584
585 for (iso_blknum = vol_desc_start+16;
586 iso_blknum < vol_desc_start+100; iso_blknum++)
587 {
588 struct hs_volume_descriptor * hdp;
589 struct iso_volume_descriptor * vdp;
590
591 block = iso_blknum << (ISOFS_BLOCK_BITS - s->s_blocksize_bits);
592 if (!(bh = sb_bread(s, block)))
593 goto out_no_read;
594
595 vdp = (struct iso_volume_descriptor *)bh->b_data;
596 hdp = (struct hs_volume_descriptor *)bh->b_data;
597
598
599
600
601
602 if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
603 if (isonum_711 (vdp->type) == ISO_VD_END)
604 break;
605 if (isonum_711 (vdp->type) == ISO_VD_PRIMARY) {
606 if (pri == NULL) {
607 pri = (struct iso_primary_descriptor *)vdp;
608
609 pri_bh = bh;
610 bh = NULL;
611 }
612 }
613#ifdef CONFIG_JOLIET
614 else if (isonum_711 (vdp->type) == ISO_VD_SUPPLEMENTARY) {
615 sec = (struct iso_supplementary_descriptor *)vdp;
616 if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) {
617 if (opt.joliet == 'y') {
618 if (sec->escape[2] == 0x40) {
619 joliet_level = 1;
620 } else if (sec->escape[2] == 0x43) {
621 joliet_level = 2;
622 } else if (sec->escape[2] == 0x45) {
623 joliet_level = 3;
624 }
625 printk(KERN_DEBUG"ISO 9660 Extensions: Microsoft Joliet Level %d\n",
626 joliet_level);
627 }
628 goto root_found;
629 } else {
630
631 sec = NULL;
632 }
633 }
634#endif
635 } else {
636 if (strncmp (hdp->id, HS_STANDARD_ID, sizeof hdp->id) == 0) {
637 if (isonum_711 (hdp->type) != ISO_VD_PRIMARY)
638 goto out_freebh;
639
640 sbi->s_high_sierra = 1;
641 opt.rock = 'n';
642 h_pri = (struct hs_primary_descriptor *)vdp;
643 goto root_found;
644 }
645 }
646
647
648
649 brelse(bh);
650 bh = NULL;
651 }
652
653
654
655
656 if (!pri)
657 goto out_unknown_format;
658 brelse(bh);
659 bh = pri_bh;
660 pri_bh = NULL;
661
662root_found:
663
664 if (joliet_level && (pri == NULL || opt.rock == 'n')) {
665
666
667
668 pri = (struct iso_primary_descriptor *) sec;
669 }
670
671 if(sbi->s_high_sierra){
672 rootp = (struct iso_directory_record *) h_pri->root_directory_record;
673 sbi->s_nzones = isonum_733 (h_pri->volume_space_size);
674 sbi->s_log_zone_size = isonum_723 (h_pri->logical_block_size);
675 sbi->s_max_size = isonum_733(h_pri->volume_space_size);
676 } else {
677 if (!pri)
678 goto out_freebh;
679 rootp = (struct iso_directory_record *) pri->root_directory_record;
680 sbi->s_nzones = isonum_733 (pri->volume_space_size);
681 sbi->s_log_zone_size = isonum_723 (pri->logical_block_size);
682 sbi->s_max_size = isonum_733(pri->volume_space_size);
683 }
684
685 sbi->s_ninodes = 0;
686
687 orig_zonesize = sbi->s_log_zone_size;
688
689
690
691
692
693
694
695 if(orig_zonesize < opt.blocksize)
696 goto out_bad_size;
697
698
699 switch (sbi->s_log_zone_size)
700 { case 512: sbi->s_log_zone_size = 9; break;
701 case 1024: sbi->s_log_zone_size = 10; break;
702 case 2048: sbi->s_log_zone_size = 11; break;
703
704 default:
705 goto out_bad_zone_size;
706 }
707
708 s->s_magic = ISOFS_SUPER_MAGIC;
709 s->s_maxbytes = 0xffffffff;
710
711
712
713
714
715
716 s->s_flags |= MS_RDONLY ;
717
718
719
720
721 first_data_zone = isonum_733 (rootp->extent) +
722 isonum_711 (rootp->ext_attr_length);
723 sbi->s_firstdatazone = first_data_zone;
724#ifndef BEQUIET
725 printk(KERN_DEBUG "Max size:%ld Log zone size:%ld\n",
726 sbi->s_max_size,
727 1UL << sbi->s_log_zone_size);
728 printk(KERN_DEBUG "First datazone:%ld\n", sbi->s_firstdatazone);
729 if(sbi->s_high_sierra)
730 printk(KERN_DEBUG "Disc in High Sierra format.\n");
731#endif
732
733
734
735
736
737
738
739
740
741 if (joliet_level) {
742 pri = (struct iso_primary_descriptor *) sec;
743 rootp = (struct iso_directory_record *)
744 pri->root_directory_record;
745 first_data_zone = isonum_733 (rootp->extent) +
746 isonum_711 (rootp->ext_attr_length);
747 }
748
749
750
751
752
753 brelse(pri_bh);
754 brelse(bh);
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773 sb_set_blocksize(s, orig_zonesize);
774
775 sbi->s_nls_iocharset = NULL;
776
777#ifdef CONFIG_JOLIET
778 if (joliet_level && opt.utf8 == 0) {
779 char * p = opt.iocharset ? opt.iocharset : CONFIG_NLS_DEFAULT;
780 sbi->s_nls_iocharset = load_nls(p);
781 if (! sbi->s_nls_iocharset) {
782
783 if (opt.iocharset)
784 goto out_freesbi;
785 sbi->s_nls_iocharset = load_nls_default();
786 }
787 }
788#endif
789 s->s_op = &isofs_sops;
790 s->s_export_op = &isofs_export_ops;
791 sbi->s_mapping = opt.map;
792 sbi->s_rock = (opt.rock == 'y' ? 2 : 0);
793 sbi->s_rock_offset = -1;
794 sbi->s_cruft = opt.cruft;
795 sbi->s_hide = opt.hide;
796 sbi->s_showassoc = opt.showassoc;
797 sbi->s_uid = opt.uid;
798 sbi->s_gid = opt.gid;
799 sbi->s_utf8 = opt.utf8;
800 sbi->s_nocompress = opt.nocompress;
801
802
803
804
805
806 sbi->s_mode = opt.mode & 0777;
807
808
809
810
811
812
813 inode = isofs_iget(s, sbi->s_firstdatazone, 0);
814
815
816
817
818
819
820
821
822
823 if (sbi->s_rock == 1) {
824 joliet_level = 0;
825 } else if (joliet_level) {
826 sbi->s_rock = 0;
827 if (sbi->s_firstdatazone != first_data_zone) {
828 sbi->s_firstdatazone = first_data_zone;
829 printk(KERN_DEBUG
830 "ISOFS: changing to secondary root\n");
831 iput(inode);
832 inode = isofs_iget(s, sbi->s_firstdatazone, 0);
833 }
834 }
835
836 if (opt.check == 'u') {
837
838 if (joliet_level) opt.check = 'r';
839 else opt.check = 's';
840 }
841 sbi->s_joliet_level = joliet_level;
842
843
844 if (!inode)
845 goto out_no_root;
846 if (!inode->i_op)
847 goto out_bad_root;
848
849 s->s_root = d_alloc_root(inode);
850 if (!(s->s_root))
851 goto out_no_root;
852
853 table = 0;
854 if (joliet_level) table += 2;
855 if (opt.check == 'r') table++;
856 s->s_root->d_op = &isofs_dentry_ops[table];
857
858 kfree(opt.iocharset);
859
860 return 0;
861
862
863
864
865out_bad_root:
866 printk(KERN_WARNING "isofs_fill_super: root inode not initialized\n");
867 goto out_iput;
868out_no_root:
869 printk(KERN_WARNING "isofs_fill_super: get root inode failed\n");
870out_iput:
871 iput(inode);
872#ifdef CONFIG_JOLIET
873 if (sbi->s_nls_iocharset)
874 unload_nls(sbi->s_nls_iocharset);
875#endif
876 goto out_freesbi;
877out_no_read:
878 printk(KERN_WARNING "isofs_fill_super: "
879 "bread failed, dev=%s, iso_blknum=%d, block=%d\n",
880 s->s_id, iso_blknum, block);
881 goto out_freesbi;
882out_bad_zone_size:
883 printk(KERN_WARNING "Bad logical zone size %ld\n",
884 sbi->s_log_zone_size);
885 goto out_freebh;
886out_bad_size:
887 printk(KERN_WARNING "Logical zone size(%d) < hardware blocksize(%u)\n",
888 orig_zonesize, opt.blocksize);
889 goto out_freebh;
890out_unknown_format:
891 if (!silent)
892 printk(KERN_WARNING "Unable to identify CD-ROM format.\n");
893
894out_freebh:
895 brelse(bh);
896out_freesbi:
897 kfree(opt.iocharset);
898 kfree(sbi);
899 s->s_fs_info = NULL;
900 return -EINVAL;
901}
902
903static int isofs_statfs (struct dentry *dentry, struct kstatfs *buf)
904{
905 struct super_block *sb = dentry->d_sb;
906
907 buf->f_type = ISOFS_SUPER_MAGIC;
908 buf->f_bsize = sb->s_blocksize;
909 buf->f_blocks = (ISOFS_SB(sb)->s_nzones
910 << (ISOFS_SB(sb)->s_log_zone_size - sb->s_blocksize_bits));
911 buf->f_bfree = 0;
912 buf->f_bavail = 0;
913 buf->f_files = ISOFS_SB(sb)->s_ninodes;
914 buf->f_ffree = 0;
915 buf->f_namelen = NAME_MAX;
916 return 0;
917}
918
919
920
921
922
923
924int isofs_get_blocks(struct inode *inode, sector_t iblock_s,
925 struct buffer_head **bh, unsigned long nblocks)
926{
927 unsigned long b_off;
928 unsigned offset, sect_size;
929 unsigned int firstext;
930 unsigned long nextblk, nextoff;
931 long iblock = (long)iblock_s;
932 int section, rv;
933 struct iso_inode_info *ei = ISOFS_I(inode);
934
935 lock_kernel();
936
937 rv = 0;
938 if (iblock < 0 || iblock != iblock_s) {
939 printk("isofs_get_blocks: block number too large\n");
940 goto abort;
941 }
942
943 b_off = iblock;
944
945 offset = 0;
946 firstext = ei->i_first_extent;
947 sect_size = ei->i_section_size >> ISOFS_BUFFER_BITS(inode);
948 nextblk = ei->i_next_section_block;
949 nextoff = ei->i_next_section_offset;
950 section = 0;
951
952 while ( nblocks ) {
953
954
955
956
957
958
959
960 if (b_off > ((inode->i_size + PAGE_CACHE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode))) {
961 printk("isofs_get_blocks: block >= EOF (%ld, %ld)\n",
962 iblock, (unsigned long) inode->i_size);
963 goto abort;
964 }
965
966 if (nextblk) {
967 while (b_off >= (offset + sect_size)) {
968 struct inode *ninode;
969
970 offset += sect_size;
971 if (nextblk == 0)
972 goto abort;
973 ninode = isofs_iget(inode->i_sb, nextblk, nextoff);
974 if (!ninode)
975 goto abort;
976 firstext = ISOFS_I(ninode)->i_first_extent;
977 sect_size = ISOFS_I(ninode)->i_section_size >> ISOFS_BUFFER_BITS(ninode);
978 nextblk = ISOFS_I(ninode)->i_next_section_block;
979 nextoff = ISOFS_I(ninode)->i_next_section_offset;
980 iput(ninode);
981
982 if (++section > 100) {
983 printk("isofs_get_blocks: More than 100 file sections ?!?, aborting...\n");
984 printk("isofs_get_blocks: block=%ld firstext=%u sect_size=%u "
985 "nextblk=%lu nextoff=%lu\n",
986 iblock, firstext, (unsigned) sect_size,
987 nextblk, nextoff);
988 goto abort;
989 }
990 }
991 }
992
993 if ( *bh ) {
994 map_bh(*bh, inode->i_sb, firstext + b_off - offset);
995 } else {
996 *bh = sb_getblk(inode->i_sb, firstext+b_off-offset);
997 if ( !*bh )
998 goto abort;
999 }
1000 bh++;
1001 b_off++;
1002 nblocks--;
1003 rv++;
1004 }
1005
1006abort:
1007 unlock_kernel();
1008 return rv;
1009}
1010
1011
1012
1013
1014static int isofs_get_block(struct inode *inode, sector_t iblock,
1015 struct buffer_head *bh_result, int create)
1016{
1017 if (create) {
1018 printk("isofs_get_block: Kernel tries to allocate a block\n");
1019 return -EROFS;
1020 }
1021
1022 return isofs_get_blocks(inode, iblock, &bh_result, 1) ? 0 : -EIO;
1023}
1024
1025static int isofs_bmap(struct inode *inode, sector_t block)
1026{
1027 struct buffer_head dummy;
1028 int error;
1029
1030 dummy.b_state = 0;
1031 dummy.b_blocknr = -1000;
1032 error = isofs_get_block(inode, block, &dummy, 0);
1033 if (!error)
1034 return dummy.b_blocknr;
1035 return 0;
1036}
1037
1038struct buffer_head *isofs_bread(struct inode *inode, sector_t block)
1039{
1040 sector_t blknr = isofs_bmap(inode, block);
1041 if (!blknr)
1042 return NULL;
1043 return sb_bread(inode->i_sb, blknr);
1044}
1045
1046static int isofs_readpage(struct file *file, struct page *page)
1047{
1048 return block_read_full_page(page,isofs_get_block);
1049}
1050
1051static sector_t _isofs_bmap(struct address_space *mapping, sector_t block)
1052{
1053 return generic_block_bmap(mapping,block,isofs_get_block);
1054}
1055
1056static const struct address_space_operations isofs_aops = {
1057 .readpage = isofs_readpage,
1058 .sync_page = block_sync_page,
1059 .bmap = _isofs_bmap
1060};
1061
1062static inline void test_and_set_uid(uid_t *p, uid_t value)
1063{
1064 if (value)
1065 *p = value;
1066}
1067
1068static inline void test_and_set_gid(gid_t *p, gid_t value)
1069{
1070 if (value)
1071 *p = value;
1072}
1073
1074static int isofs_read_level3_size(struct inode *inode)
1075{
1076 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
1077 int high_sierra = ISOFS_SB(inode->i_sb)->s_high_sierra;
1078 struct buffer_head * bh = NULL;
1079 unsigned long block, offset, block_saved, offset_saved;
1080 int i = 0;
1081 int more_entries = 0;
1082 struct iso_directory_record * tmpde = NULL;
1083 struct iso_inode_info *ei = ISOFS_I(inode);
1084
1085 inode->i_size = 0;
1086
1087
1088
1089
1090 ei->i_next_section_block = 0;
1091 ei->i_next_section_offset = 0;
1092
1093 block = ei->i_iget5_block;
1094 offset = ei->i_iget5_offset;
1095
1096 do {
1097 struct iso_directory_record * de;
1098 unsigned int de_len;
1099
1100 if (!bh) {
1101 bh = sb_bread(inode->i_sb, block);
1102 if (!bh)
1103 goto out_noread;
1104 }
1105 de = (struct iso_directory_record *) (bh->b_data + offset);
1106 de_len = *(unsigned char *) de;
1107
1108 if (de_len == 0) {
1109 brelse(bh);
1110 bh = NULL;
1111 ++block;
1112 offset = 0;
1113 continue;
1114 }
1115
1116 block_saved = block;
1117 offset_saved = offset;
1118 offset += de_len;
1119
1120
1121 if (offset >= bufsize) {
1122 int slop = bufsize - offset + de_len;
1123 if (!tmpde) {
1124 tmpde = kmalloc(256, GFP_KERNEL);
1125 if (!tmpde)
1126 goto out_nomem;
1127 }
1128 memcpy(tmpde, de, slop);
1129 offset &= bufsize - 1;
1130 block++;
1131 brelse(bh);
1132 bh = NULL;
1133 if (offset) {
1134 bh = sb_bread(inode->i_sb, block);
1135 if (!bh)
1136 goto out_noread;
1137 memcpy((void *)tmpde+slop, bh->b_data, offset);
1138 }
1139 de = tmpde;
1140 }
1141
1142 inode->i_size += isonum_733(de->size);
1143 if (i == 1) {
1144 ei->i_next_section_block = block_saved;
1145 ei->i_next_section_offset = offset_saved;
1146 }
1147
1148 more_entries = de->flags[-high_sierra] & 0x80;
1149
1150 i++;
1151 if (i > 100)
1152 goto out_toomany;
1153 } while (more_entries);
1154out:
1155 kfree(tmpde);
1156 if (bh)
1157 brelse(bh);
1158 return 0;
1159
1160out_nomem:
1161 if (bh)
1162 brelse(bh);
1163 return -ENOMEM;
1164
1165out_noread:
1166 printk(KERN_INFO "ISOFS: unable to read i-node block %lu\n", block);
1167 kfree(tmpde);
1168 return -EIO;
1169
1170out_toomany:
1171 printk(KERN_INFO "isofs_read_level3_size: "
1172 "More than 100 file sections ?!?, aborting...\n"
1173 "isofs_read_level3_size: inode=%lu\n",
1174 inode->i_ino);
1175 goto out;
1176}
1177
1178static void isofs_read_inode(struct inode *inode)
1179{
1180 struct super_block *sb = inode->i_sb;
1181 struct isofs_sb_info *sbi = ISOFS_SB(sb);
1182 unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
1183 unsigned long block;
1184 int high_sierra = sbi->s_high_sierra;
1185 struct buffer_head * bh = NULL;
1186 struct iso_directory_record * de;
1187 struct iso_directory_record * tmpde = NULL;
1188 unsigned int de_len;
1189 unsigned long offset;
1190 struct iso_inode_info *ei = ISOFS_I(inode);
1191
1192 block = ei->i_iget5_block;
1193 bh = sb_bread(inode->i_sb, block);
1194 if (!bh)
1195 goto out_badread;
1196
1197 offset = ei->i_iget5_offset;
1198
1199 de = (struct iso_directory_record *) (bh->b_data + offset);
1200 de_len = *(unsigned char *) de;
1201
1202 if (offset + de_len > bufsize) {
1203 int frag1 = bufsize - offset;
1204
1205 tmpde = kmalloc(de_len, GFP_KERNEL);
1206 if (tmpde == NULL) {
1207 printk(KERN_INFO "isofs_read_inode: out of memory\n");
1208 goto fail;
1209 }
1210 memcpy(tmpde, bh->b_data + offset, frag1);
1211 brelse(bh);
1212 bh = sb_bread(inode->i_sb, ++block);
1213 if (!bh)
1214 goto out_badread;
1215 memcpy((char *)tmpde+frag1, bh->b_data, de_len - frag1);
1216 de = tmpde;
1217 }
1218
1219 inode->i_ino = isofs_get_ino(ei->i_iget5_block,
1220 ei->i_iget5_offset,
1221 ISOFS_BUFFER_BITS(inode));
1222
1223
1224 ei->i_file_format = isofs_file_normal;
1225
1226 if (de->flags[-high_sierra] & 2) {
1227 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
1228 inode->i_nlink = 1;
1229
1230
1231
1232
1233 } else {
1234
1235 inode->i_mode = sbi->s_mode;
1236 inode->i_nlink = 1;
1237 inode->i_mode |= S_IFREG;
1238 }
1239 inode->i_uid = sbi->s_uid;
1240 inode->i_gid = sbi->s_gid;
1241 inode->i_blocks = inode->i_blksize = 0;
1242
1243 ei->i_format_parm[0] = 0;
1244 ei->i_format_parm[1] = 0;
1245 ei->i_format_parm[2] = 0;
1246
1247 ei->i_section_size = isonum_733 (de->size);
1248 if (de->flags[-high_sierra] & 0x80) {
1249 if(isofs_read_level3_size(inode)) goto fail;
1250 } else {
1251 ei->i_next_section_block = 0;
1252 ei->i_next_section_offset = 0;
1253 inode->i_size = isonum_733 (de->size);
1254 }
1255
1256
1257
1258
1259
1260
1261
1262 if (sbi->s_cruft == 'y')
1263 inode->i_size &= 0x00ffffff;
1264
1265 if (de->interleave[0]) {
1266 printk("Interleaved files not (yet) supported.\n");
1267 inode->i_size = 0;
1268 }
1269
1270
1271
1272 if (de->file_unit_size[0] != 0) {
1273 printk("File unit size != 0 for ISO file (%ld).\n",
1274 inode->i_ino);
1275 }
1276
1277
1278
1279#ifdef DEBUG
1280 if((de->flags[-high_sierra] & ~2)!= 0){
1281 printk("Unusual flag settings for ISO file (%ld %x).\n",
1282 inode->i_ino, de->flags[-high_sierra]);
1283 }
1284#endif
1285
1286 inode->i_mtime.tv_sec =
1287 inode->i_atime.tv_sec =
1288 inode->i_ctime.tv_sec = iso_date(de->date, high_sierra);
1289 inode->i_mtime.tv_nsec =
1290 inode->i_atime.tv_nsec =
1291 inode->i_ctime.tv_nsec = 0;
1292
1293 ei->i_first_extent = (isonum_733 (de->extent) +
1294 isonum_711 (de->ext_attr_length));
1295
1296
1297 inode->i_blksize = PAGE_CACHE_SIZE;
1298 inode->i_blocks = (inode->i_size + 511) >> 9;
1299
1300
1301
1302
1303
1304
1305 if (!high_sierra) {
1306 parse_rock_ridge_inode(de, inode);
1307
1308 test_and_set_uid(&inode->i_uid, sbi->s_uid);
1309 test_and_set_gid(&inode->i_gid, sbi->s_gid);
1310 }
1311
1312
1313 if (S_ISREG(inode->i_mode)) {
1314 inode->i_fop = &generic_ro_fops;
1315 switch ( ei->i_file_format ) {
1316#ifdef CONFIG_ZISOFS
1317 case isofs_file_compressed:
1318 inode->i_data.a_ops = &zisofs_aops;
1319 break;
1320#endif
1321 default:
1322 inode->i_data.a_ops = &isofs_aops;
1323 break;
1324 }
1325 } else if (S_ISDIR(inode->i_mode)) {
1326 inode->i_op = &isofs_dir_inode_operations;
1327 inode->i_fop = &isofs_dir_operations;
1328 } else if (S_ISLNK(inode->i_mode)) {
1329 inode->i_op = &page_symlink_inode_operations;
1330 inode->i_data.a_ops = &isofs_symlink_aops;
1331 } else
1332
1333 init_special_inode(inode, inode->i_mode, inode->i_rdev);
1334
1335out:
1336 kfree(tmpde);
1337 if (bh)
1338 brelse(bh);
1339 return;
1340
1341out_badread:
1342 printk(KERN_WARNING "ISOFS: unable to read i-node block\n");
1343fail:
1344 make_bad_inode(inode);
1345 goto out;
1346}
1347
1348struct isofs_iget5_callback_data {
1349 unsigned long block;
1350 unsigned long offset;
1351};
1352
1353static int isofs_iget5_test(struct inode *ino, void *data)
1354{
1355 struct iso_inode_info *i = ISOFS_I(ino);
1356 struct isofs_iget5_callback_data *d =
1357 (struct isofs_iget5_callback_data*)data;
1358 return (i->i_iget5_block == d->block)
1359 && (i->i_iget5_offset == d->offset);
1360}
1361
1362static int isofs_iget5_set(struct inode *ino, void *data)
1363{
1364 struct iso_inode_info *i = ISOFS_I(ino);
1365 struct isofs_iget5_callback_data *d =
1366 (struct isofs_iget5_callback_data*)data;
1367 i->i_iget5_block = d->block;
1368 i->i_iget5_offset = d->offset;
1369 return 0;
1370}
1371
1372
1373
1374
1375
1376struct inode *isofs_iget(struct super_block *sb,
1377 unsigned long block,
1378 unsigned long offset)
1379{
1380 unsigned long hashval;
1381 struct inode *inode;
1382 struct isofs_iget5_callback_data data;
1383
1384 if (offset >= 1ul << sb->s_blocksize_bits)
1385 return NULL;
1386
1387 data.block = block;
1388 data.offset = offset;
1389
1390 hashval = (block << sb->s_blocksize_bits) | offset;
1391
1392 inode = iget5_locked(sb, hashval, &isofs_iget5_test,
1393 &isofs_iget5_set, &data);
1394
1395 if (inode && (inode->i_state & I_NEW)) {
1396 sb->s_op->read_inode(inode);
1397 unlock_new_inode(inode);
1398 }
1399
1400 return inode;
1401}
1402
1403static int isofs_get_sb(struct file_system_type *fs_type,
1404 int flags, const char *dev_name, void *data, struct vfsmount *mnt)
1405{
1406 return get_sb_bdev(fs_type, flags, dev_name, data, isofs_fill_super,
1407 mnt);
1408}
1409
1410static struct file_system_type iso9660_fs_type = {
1411 .owner = THIS_MODULE,
1412 .name = "iso9660",
1413 .get_sb = isofs_get_sb,
1414 .kill_sb = kill_block_super,
1415 .fs_flags = FS_REQUIRES_DEV,
1416};
1417
1418static int __init init_iso9660_fs(void)
1419{
1420 int err = init_inodecache();
1421 if (err)
1422 goto out;
1423#ifdef CONFIG_ZISOFS
1424 err = zisofs_init();
1425 if (err)
1426 goto out1;
1427#endif
1428 err = register_filesystem(&iso9660_fs_type);
1429 if (err)
1430 goto out2;
1431 return 0;
1432out2:
1433#ifdef CONFIG_ZISOFS
1434 zisofs_cleanup();
1435out1:
1436#endif
1437 destroy_inodecache();
1438out:
1439 return err;
1440}
1441
1442static void __exit exit_iso9660_fs(void)
1443{
1444 unregister_filesystem(&iso9660_fs_type);
1445#ifdef CONFIG_ZISOFS
1446 zisofs_cleanup();
1447#endif
1448 destroy_inodecache();
1449}
1450
1451module_init(init_iso9660_fs)
1452module_exit(exit_iso9660_fs)
1453MODULE_LICENSE("GPL");
1454
1455MODULE_ALIAS("iso9660");
1456