~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/fs/isofs/inode.c

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  *  linux/fs/isofs/inode.c
  3  *
  4  *  (C) 1991  Linus Torvalds - minix filesystem
  5  *      1992, 1993, 1994  Eric Youngdale Modified for ISO 9660 filesystem.
  6  *      1994  Eberhard Moenkeberg - multi session handling.
  7  *      1995  Mark Dobie - allow mounting of some weird VideoCDs and PhotoCDs.
  8  *      1997  Gordon Chaffee - Joliet CDs
  9  *      1998  Eric Lammerts - ISO 9660 Level 3
 10  */
 11 
 12 #include <linux/config.h>
 13 #include <linux/module.h>
 14 
 15 #include <linux/stat.h>
 16 #include <linux/sched.h>
 17 #include <linux/iso_fs.h>
 18 #include <linux/kernel.h>
 19 #include <linux/major.h>
 20 #include <linux/mm.h>
 21 #include <linux/string.h>
 22 #include <linux/locks.h>
 23 #include <linux/malloc.h>
 24 #include <linux/errno.h>
 25 #include <linux/cdrom.h>
 26 #include <linux/init.h>
 27 #include <linux/nls.h>
 28 #include <linux/ctype.h>
 29 #include <linux/smp_lock.h>
 30 
 31 #include <asm/system.h>
 32 #include <asm/uaccess.h>
 33 
 34 /*
 35  * We have no support for "multi volume" CDs, but more and more disks carry
 36  * wrong information within the volume descriptors.
 37  */
 38 #define IGNORE_WRONG_MULTI_VOLUME_SPECS
 39 #define BEQUIET
 40 
 41 #ifdef LEAK_CHECK
 42 static int check_malloc = 0;
 43 static int check_bread = 0;
 44 #endif
 45 
 46 static int isofs_hashi(struct dentry *parent, struct qstr *qstr);
 47 static int isofs_hash(struct dentry *parent, struct qstr *qstr);
 48 static int isofs_dentry_cmpi(struct dentry *dentry, struct qstr *a, struct qstr *b);
 49 static int isofs_dentry_cmp(struct dentry *dentry, struct qstr *a, struct qstr *b);
 50 
 51 #ifdef CONFIG_JOLIET
 52 static int isofs_hashi_ms(struct dentry *parent, struct qstr *qstr);
 53 static int isofs_hash_ms(struct dentry *parent, struct qstr *qstr);
 54 static int isofs_dentry_cmpi_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
 55 static int isofs_dentry_cmp_ms(struct dentry *dentry, struct qstr *a, struct qstr *b);
 56 #endif
 57 
 58 static void isofs_put_super(struct super_block *sb)
 59 {
 60 #ifdef CONFIG_JOLIET
 61         if (sb->u.isofs_sb.s_nls_iocharset) {
 62                 unload_nls(sb->u.isofs_sb.s_nls_iocharset);
 63                 sb->u.isofs_sb.s_nls_iocharset = NULL;
 64         }
 65 #endif
 66 
 67 #ifdef LEAK_CHECK
 68         printk("Outstanding mallocs:%d, outstanding buffers: %d\n",
 69                check_malloc, check_bread);
 70 #endif
 71 
 72         return;
 73 }
 74 
 75 static void isofs_read_inode(struct inode *);
 76 static int isofs_statfs (struct super_block *, struct statfs *);
 77 
 78 static struct super_operations isofs_sops = {
 79         read_inode:     isofs_read_inode,
 80         put_super:      isofs_put_super,
 81         statfs:         isofs_statfs,
 82 };
 83 
 84 static struct dentry_operations isofs_dentry_ops[] = {
 85         {
 86                 d_hash:         isofs_hash,
 87                 d_compare:      isofs_dentry_cmp,
 88         },
 89         {
 90                 d_hash:         isofs_hashi,
 91                 d_compare:      isofs_dentry_cmpi,
 92         },
 93 #ifdef CONFIG_JOLIET
 94         {
 95                 d_hash:         isofs_hash_ms,
 96                 d_compare:      isofs_dentry_cmp_ms,
 97         },
 98         {
 99                 d_hash:         isofs_hashi_ms,
100                 d_compare:      isofs_dentry_cmpi_ms,
101         }
102 #endif
103 };
104 
105 struct iso9660_options{
106         char map;
107         char rock;
108         char joliet;
109         char cruft;
110         char unhide;
111         unsigned char check;
112         unsigned int blocksize;
113         mode_t mode;
114         gid_t gid;
115         uid_t uid;
116         char *iocharset;
117         unsigned char utf8;
118         /* LVE */
119         s32 session;
120         s32 sbsector;
121 };
122 
123 /*
124  * Compute the hash for the isofs name corresponding to the dentry.
125  */
126 static int
127 isofs_hash_common(struct dentry *dentry, struct qstr *qstr, int ms)
128 {
129         const char *name;
130         int len;
131 
132         len = qstr->len;
133         name = qstr->name;
134         if (ms) {
135                 while (len && name[len-1] == '.')
136                         len--;
137         }
138 
139         qstr->hash = full_name_hash(name, len);
140 
141         return 0;
142 }
143 
144 /*
145  * Compute the hash for the isofs name corresponding to the dentry.
146  */
147 static int
148 isofs_hashi_common(struct dentry *dentry, struct qstr *qstr, int ms)
149 {
150         const char *name;
151         int len;
152         char c;
153         unsigned long hash;
154 
155         len = qstr->len;
156         name = qstr->name;
157         if (ms) {
158                 while (len && name[len-1] == '.')
159                         len--;
160         }
161 
162         hash = init_name_hash();
163         while (len--) {
164                 c = tolower(*name++);
165                 hash = partial_name_hash(tolower(c), hash);
166         }
167         qstr->hash = end_name_hash(hash);
168 
169         return 0;
170 }
171 
172 /*
173  * Case insensitive compare of two isofs names.
174  */
175 static int
176 isofs_dentry_cmpi_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms)
177 {
178         int alen, blen;
179 
180         /* A filename cannot end in '.' or we treat it like it has none */
181         alen = a->len;
182         blen = b->len;
183         if (ms) {
184                 while (alen && a->name[alen-1] == '.')
185                         alen--;
186                 while (blen && b->name[blen-1] == '.')
187                         blen--;
188         }
189         if (alen == blen) {
190                 if (strnicmp(a->name, b->name, alen) == 0)
191                         return 0;
192         }
193         return 1;
194 }
195 
196 /*
197  * Case sensitive compare of two isofs names.
198  */
199 static int
200 isofs_dentry_cmp_common(struct dentry *dentry,struct qstr *a,struct qstr *b,int ms)
201 {
202         int alen, blen;
203 
204         /* A filename cannot end in '.' or we treat it like it has none */
205         alen = a->len;
206         blen = b->len;
207         if (ms) {
208                 while (alen && a->name[alen-1] == '.')
209                         alen--;
210                 while (blen && b->name[blen-1] == '.')
211                         blen--;
212         }
213         if (alen == blen) {
214                 if (strncmp(a->name, b->name, alen) == 0)
215                         return 0;
216         }
217         return 1;
218 }
219 
220 static int
221 isofs_hash(struct dentry *dentry, struct qstr *qstr)
222 {
223         return isofs_hash_common(dentry, qstr, 0);
224 }
225 
226 static int
227 isofs_hashi(struct dentry *dentry, struct qstr *qstr)
228 {
229         return isofs_hashi_common(dentry, qstr, 0);
230 }
231 
232 static int
233 isofs_dentry_cmp(struct dentry *dentry,struct qstr *a,struct qstr *b)
234 {
235         return isofs_dentry_cmp_common(dentry, a, b, 0);
236 }
237 
238 static int
239 isofs_dentry_cmpi(struct dentry *dentry,struct qstr *a,struct qstr *b)
240 {
241         return isofs_dentry_cmpi_common(dentry, a, b, 0);
242 }
243 
244 #ifdef CONFIG_JOLIET
245 static int
246 isofs_hash_ms(struct dentry *dentry, struct qstr *qstr)
247 {
248         return isofs_hash_common(dentry, qstr, 1);
249 }
250 
251 static int
252 isofs_hashi_ms(struct dentry *dentry, struct qstr *qstr)
253 {
254         return isofs_hashi_common(dentry, qstr, 1);
255 }
256 
257 static int
258 isofs_dentry_cmp_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
259 {
260         return isofs_dentry_cmp_common(dentry, a, b, 1);
261 }
262 
263 static int
264 isofs_dentry_cmpi_ms(struct dentry *dentry,struct qstr *a,struct qstr *b)
265 {
266         return isofs_dentry_cmpi_common(dentry, a, b, 1);
267 }
268 #endif
269 
270 static int parse_options(char *options, struct iso9660_options * popt)
271 {
272         char *this_char,*value;
273 
274         popt->map = 'n';
275         popt->rock = 'y';
276         popt->joliet = 'y';
277         popt->cruft = 'n';
278         popt->unhide = 'n';
279         popt->check = 'u';              /* unset */
280         popt->blocksize = 1024;
281         popt->mode = S_IRUGO | S_IXUGO; /* r-x for all.  The disc could
282                                            be shared with DOS machines so
283                                            virtually anything could be
284                                            a valid executable. */
285         popt->gid = 0;
286         popt->uid = 0;
287         popt->iocharset = NULL;
288         popt->utf8 = 0;
289         popt->session=-1;
290         popt->sbsector=-1;
291         if (!options) return 1;
292         for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
293                 if (strncmp(this_char,"norock",6) == 0) {
294                   popt->rock = 'n';
295                   continue;
296                 }
297                 if (strncmp(this_char,"nojoliet",8) == 0) {
298                   popt->joliet = 'n';
299                   continue;
300                 }
301                 if (strncmp(this_char,"unhide",6) == 0) {
302                   popt->unhide = 'y';
303                   continue;
304                 }
305                 if (strncmp(this_char,"cruft",5) == 0) {
306                   popt->cruft = 'y';
307                   continue;
308                 }
309                 if (strncmp(this_char,"utf8",4) == 0) {
310                   popt->utf8 = 1;
311                   continue;
312                 }
313                 if ((value = strchr(this_char,'=')) != NULL)
314                         *value++ = 0;
315 
316 #ifdef CONFIG_JOLIET
317                 if (!strcmp(this_char,"iocharset") && value) {
318                         popt->iocharset = value;
319                         while (*value && *value != ',')
320                                 value++;
321                         if (value == popt->iocharset)
322                                 return 0;
323                         *value = 0;
324                 } else
325 #endif
326                 if (!strcmp(this_char,"map") && value) {
327                         if (value[0] && !value[1] && strchr("ano",*value))
328                                 popt->map = *value;
329                         else if (!strcmp(value,"off")) popt->map = 'o';
330                         else if (!strcmp(value,"normal")) popt->map = 'n';
331                         else if (!strcmp(value,"acorn")) popt->map = 'a';
332                         else return 0;
333                 }
334                 if (!strcmp(this_char,"session") && value) {
335                         char * vpnt = value;
336                         unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
337                         if(ivalue < 0 || ivalue >99) return 0;
338                         popt->session=ivalue+1;
339                 }
340                 if (!strcmp(this_char,"sbsector") && value) {
341                         char * vpnt = value;
342                         unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
343                         if(ivalue < 0 || ivalue >660*512) return 0;
344                         popt->sbsector=ivalue;
345                 }
346                 else if (!strcmp(this_char,"check") && value) {
347                         if (value[0] && !value[1] && strchr("rs",*value))
348                                 popt->check = *value;
349                         else if (!strcmp(value,"relaxed")) popt->check = 'r';
350                         else if (!strcmp(value,"strict")) popt->check = 's';
351                         else return 0;
352                 }
353                 else if (!strcmp(this_char,"conv") && value) {
354                         /* no conversion is done anymore;
355                            we still accept the same mount options,
356                            but ignore them */
357                         if (value[0] && !value[1] && strchr("btma",*value)) ;
358                         else if (!strcmp(value,"binary")) ;
359                         else if (!strcmp(value,"text")) ;
360                         else if (!strcmp(value,"mtext")) ;
361                         else if (!strcmp(value,"auto")) ;
362                         else return 0;
363                 }
364                 else if (value &&
365                          (!strcmp(this_char,"block") ||
366                           !strcmp(this_char,"mode") ||
367                           !strcmp(this_char,"uid") ||
368                           !strcmp(this_char,"gid"))) {
369                   char * vpnt = value;
370                   unsigned int ivalue = simple_strtoul(vpnt, &vpnt, 0);
371                   if (*vpnt) return 0;
372                   switch(*this_char) {
373                   case 'b':
374                     if (   ivalue != 512
375                         && ivalue != 1024
376                         && ivalue != 2048) return 0;
377                     popt->blocksize = ivalue;
378                     break;
379                   case 'u':
380                     popt->uid = ivalue;
381                     break;
382                   case 'g':
383                     popt->gid = ivalue;
384                     break;
385                   case 'm':
386                     popt->mode = ivalue;
387                     break;
388                   }
389                 }
390                 else return 1;
391         }
392         return 1;
393 }
394 
395 /*
396  * look if the driver can tell the multi session redirection value
397  *
398  * don't change this if you don't know what you do, please!
399  * Multisession is legal only with XA disks.
400  * A non-XA disk with more than one volume descriptor may do it right, but
401  * usually is written in a nowhere standardized "multi-partition" manner.
402  * Multisession uses absolute addressing (solely the first frame of the whole
403  * track is #0), multi-partition uses relative addressing (each first frame of
404  * each track is #0), and a track is not a session.
405  *
406  * A broken CDwriter software or drive firmware does not set new standards,
407  * at least not if conflicting with the existing ones.
408  *
409  * emoenke@gwdg.de
410  */
411 #define WE_OBEY_THE_WRITTEN_STANDARDS 1
412 
413 static unsigned int isofs_get_last_session(struct super_block *sb,s32 session )
414 {
415         struct cdrom_multisession ms_info;
416         unsigned int vol_desc_start;
417         struct block_device *bdev = sb->s_bdev;
418         int i;
419 
420         vol_desc_start=0;
421         ms_info.addr_format=CDROM_LBA;
422         if(session >= 0 && session <= 99) {
423                 struct cdrom_tocentry Te;
424                 Te.cdte_track=session;
425                 Te.cdte_format=CDROM_LBA;
426                 i = ioctl_by_bdev(bdev, CDROMREADTOCENTRY, (unsigned long) &Te);
427                 if (!i) {
428                         printk(KERN_DEBUG "Session %d start %d type %d\n",
429                                session, Te.cdte_addr.lba,
430                                Te.cdte_ctrl&CDROM_DATA_TRACK);
431                         if ((Te.cdte_ctrl&CDROM_DATA_TRACK) == 4)
432                                 return Te.cdte_addr.lba;
433                 }
434                         
435                 printk(KERN_ERR "Invalid session number or type of track\n");
436         }
437         i = ioctl_by_bdev(bdev, CDROMMULTISESSION, (unsigned long) &ms_info);
438         if(session > 0) printk(KERN_ERR "Invalid session number\n");
439 #if 0
440         printk("isofs.inode: CDROMMULTISESSION: rc=%d\n",i);
441         if (i==0) {
442                 printk("isofs.inode: XA disk: %s\n",ms_info.xa_flag?"yes":"no");
443                 printk("isofs.inode: vol_desc_start = %d\n", ms_info.addr.lba);
444         }
445 #endif
446         if (i==0)
447 #if WE_OBEY_THE_WRITTEN_STANDARDS
448         if (ms_info.xa_flag) /* necessary for a valid ms_info.addr */
449 #endif
450                 vol_desc_start=ms_info.addr.lba;
451         return vol_desc_start;
452 }
453 
454 /*
455  * Initialize the superblock and read the root inode.
456  *
457  * Note: a check_disk_change() has been done immediately prior
458  * to this call, so we don't need to check again.
459  */
460 static struct super_block *isofs_read_super(struct super_block *s, void *data,
461                                             int silent)
462 {
463         kdev_t                          dev = s->s_dev;
464         struct buffer_head            * bh = NULL, *pri_bh = NULL;
465         struct hs_primary_descriptor  * h_pri = NULL;
466         struct iso_primary_descriptor * pri = NULL;
467         struct iso_supplementary_descriptor *sec = NULL;
468         struct iso_directory_record   * rootp;
469         int                             joliet_level = 0;
470         int                             high_sierra;
471         int                             iso_blknum, block;
472         int                             orig_zonesize;
473         int                             table;
474         unsigned int                    blocksize, blocksize_bits;
475         unsigned int                    vol_desc_start;
476         unsigned long                   first_data_zone;
477         struct inode                  * inode;
478         struct iso9660_options          opt;
479 
480         if (!parse_options((char *) data, &opt))
481                 goto out_unlock;
482 
483 #if 0
484         printk("map = %c\n", opt.map);
485         printk("rock = %c\n", opt.rock);
486         printk("joliet = %c\n", opt.joliet);
487         printk("check = %c\n", opt.check);
488         printk("cruft = %c\n", opt.cruft);
489         printk("unhide = %c\n", opt.unhide);
490         printk("blocksize = %d\n", opt.blocksize);
491         printk("gid = %d\n", opt.gid);
492         printk("uid = %d\n", opt.uid);
493         printk("iocharset = %s\n", opt.iocharset);
494 #endif
495 
496         /*
497          * First of all, get the hardware blocksize for this device.
498          * If we don't know what it is, or the hardware blocksize is
499          * larger than the blocksize the user specified, then use
500          * that value.
501          */
502         blocksize = get_hardblocksize(dev);
503         if(blocksize > opt.blocksize) {
504             /*
505              * Force the blocksize we are going to use to be the
506              * hardware blocksize.
507              */
508             opt.blocksize = blocksize;
509         }
510  
511         blocksize_bits = 0;
512         {
513           int i = opt.blocksize;
514           while (i != 1){
515             blocksize_bits++;
516             i >>=1;
517           }
518         }
519 
520         set_blocksize(dev, opt.blocksize);
521 
522         s->u.isofs_sb.s_high_sierra = high_sierra = 0; /* default is iso9660 */
523 
524         vol_desc_start = (opt.sbsector != -1) ?
525                 opt.sbsector : isofs_get_last_session(s,opt.session);
526 
527         for (iso_blknum = vol_desc_start+16;
528              iso_blknum < vol_desc_start+100; iso_blknum++)
529         {
530             struct hs_volume_descriptor   * hdp;
531             struct iso_volume_descriptor  * vdp;
532 
533             block = iso_blknum << (ISOFS_BLOCK_BITS-blocksize_bits);
534             if (!(bh = bread(dev, block, opt.blocksize)))
535                 goto out_no_read;               
536 
537             vdp = (struct iso_volume_descriptor *)bh->b_data;
538             hdp = (struct hs_volume_descriptor *)bh->b_data;
539             
540             /* Due to the overlapping physical location of the descriptors, 
541              * ISO CDs can match hdp->id==HS_STANDARD_ID as well. To ensure 
542              * proper identification in this case, we first check for ISO.
543              */
544             if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
545                 if (isonum_711 (vdp->type) == ISO_VD_END)
546                     break;
547                 if (isonum_711 (vdp->type) == ISO_VD_PRIMARY) {
548                     if (pri == NULL) {
549                         pri = (struct iso_primary_descriptor *)vdp;
550                         /* Save the buffer in case we need it ... */
551                         pri_bh = bh;
552                         bh = NULL;
553                     }
554                 }
555 #ifdef CONFIG_JOLIET
556                 else if (isonum_711 (vdp->type) == ISO_VD_SUPPLEMENTARY) {
557                     sec = (struct iso_supplementary_descriptor *)vdp;
558                     if (sec->escape[0] == 0x25 && sec->escape[1] == 0x2f) {
559                         if (opt.joliet == 'y') {
560                             if (sec->escape[2] == 0x40) {
561                                 joliet_level = 1;
562                             } else if (sec->escape[2] == 0x43) {
563                                 joliet_level = 2;
564                             } else if (sec->escape[2] == 0x45) {
565                                 joliet_level = 3;
566                             }
567                             printk(KERN_DEBUG"ISO 9660 Extensions: Microsoft Joliet Level %d\n",
568                                    joliet_level);
569                         }
570                         goto root_found;
571                     } else {
572                         /* Unknown supplementary volume descriptor */
573                         sec = NULL;
574                     }
575                 }
576 #endif
577             } else {
578                 if (strncmp (hdp->id, HS_STANDARD_ID, sizeof hdp->id) == 0) {
579                     if (isonum_711 (hdp->type) != ISO_VD_PRIMARY)
580                         goto out_freebh;
581                 
582                     s->u.isofs_sb.s_high_sierra = 1;
583                     high_sierra = 1;
584                     opt.rock = 'n';
585                     h_pri = (struct hs_primary_descriptor *)vdp;
586                     goto root_found;
587                 }
588             }
589 
590             /* Just skip any volume descriptors we don't recognize */
591 
592             brelse(bh);
593             bh = NULL;
594         }
595         /*
596          * If we fall through, either no volume descriptor was found,
597          * or else we passed a primary descriptor looking for others.
598          */
599         if (!pri)
600                 goto out_unknown_format;
601         brelse(bh);
602         bh = pri_bh;
603         pri_bh = NULL;
604 
605 root_found:
606 
607         if (joliet_level && (pri == NULL || opt.rock == 'n')) {
608             /* This is the case of Joliet with the norock mount flag.
609              * A disc with both Joliet and Rock Ridge is handled later
610              */
611             pri = (struct iso_primary_descriptor *) sec;
612         }
613 
614         if(high_sierra){
615           rootp = (struct iso_directory_record *) h_pri->root_directory_record;
616 #ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
617           if (isonum_723 (h_pri->volume_set_size) != 1)
618                 goto out_no_support;
619 #endif IGNORE_WRONG_MULTI_VOLUME_SPECS
620           s->u.isofs_sb.s_nzones = isonum_733 (h_pri->volume_space_size);
621           s->u.isofs_sb.s_log_zone_size = isonum_723 (h_pri->logical_block_size);
622           s->u.isofs_sb.s_max_size = isonum_733(h_pri->volume_space_size);
623         } else {
624           rootp = (struct iso_directory_record *) pri->root_directory_record;
625 #ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
626           if (isonum_723 (pri->volume_set_size) != 1)
627                 goto out_no_support;
628 #endif IGNORE_WRONG_MULTI_VOLUME_SPECS
629           s->u.isofs_sb.s_nzones = isonum_733 (pri->volume_space_size);
630           s->u.isofs_sb.s_log_zone_size = isonum_723 (pri->logical_block_size);
631           s->u.isofs_sb.s_max_size = isonum_733(pri->volume_space_size);
632         }
633 
634         s->u.isofs_sb.s_ninodes = 0; /* No way to figure this out easily */
635 
636         orig_zonesize = s -> u.isofs_sb.s_log_zone_size;
637         /*
638          * If the zone size is smaller than the hardware sector size,
639          * this is a fatal error.  This would occur if the disc drive
640          * had sectors that were 2048 bytes, but the filesystem had
641          * blocks that were 512 bytes (which should only very rarely
642          * happen.)
643          */
644         if(blocksize != 0 && orig_zonesize < blocksize)
645                 goto out_bad_size;
646 
647         /* RDE: convert log zone size to bit shift */
648         switch (s -> u.isofs_sb.s_log_zone_size)
649           { case  512: s -> u.isofs_sb.s_log_zone_size =  9; break;
650             case 1024: s -> u.isofs_sb.s_log_zone_size = 10; break;
651             case 2048: s -> u.isofs_sb.s_log_zone_size = 11; break;
652 
653             default:
654                 goto out_bad_zone_size;
655           }
656 
657         s->s_magic = ISOFS_SUPER_MAGIC;
658 
659         /* The CDROM is read-only, has no nodes (devices) on it, and since
660            all of the files appear to be owned by root, we really do not want
661            to allow suid.  (suid or devices will not show up unless we have
662            Rock Ridge extensions) */
663 
664         s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */;
665 
666         /* RDE: data zone now byte offset! */
667 
668         first_data_zone = ((isonum_733 (rootp->extent) +
669                           isonum_711 (rootp->ext_attr_length))
670                          << s -> u.isofs_sb.s_log_zone_size);
671         s->u.isofs_sb.s_firstdatazone = first_data_zone;
672 #ifndef BEQUIET
673         printk(KERN_DEBUG "Max size:%ld   Log zone size:%ld\n",
674                s->u.isofs_sb.s_max_size,
675                1UL << s->u.isofs_sb.s_log_zone_size);
676         printk(KERN_DEBUG "First datazone:%ld   Root inode number:%ld\n",
677                s->u.isofs_sb.s_firstdatazone >> s -> u.isofs_sb.s_log_zone_size,
678                s->u.isofs_sb.s_firstdatazone);
679         if(high_sierra)
680                 printk(KERN_DEBUG "Disc in High Sierra format.\n");
681 #endif
682 
683         /*
684          * If the Joliet level is set, we _may_ decide to use the
685          * secondary descriptor, but can't be sure until after we
686          * read the root inode. But before reading the root inode
687          * we may need to change the device blocksize, and would
688          * rather release the old buffer first. So, we cache the
689          * first_data_zone value from the secondary descriptor.
690          */
691         if (joliet_level) {
692                 pri = (struct iso_primary_descriptor *) sec;
693                 rootp = (struct iso_directory_record *)
694                         pri->root_directory_record;
695                 first_data_zone = ((isonum_733 (rootp->extent) +
696                                 isonum_711 (rootp->ext_attr_length))
697                                  << s -> u.isofs_sb.s_log_zone_size);
698         }
699 
700         /*
701          * We're all done using the volume descriptor, and may need
702          * to change the device blocksize, so release the buffer now.
703          */
704         brelse(pri_bh);
705         brelse(bh);
706 
707         /*
708          * Force the blocksize to 512 for 512 byte sectors.  The file
709          * read primitives really get it wrong in a bad way if we don't
710          * do this.
711          *
712          * Note - we should never be setting the blocksize to something
713          * less than the hardware sector size for the device.  If we
714          * do, we would end up having to read larger buffers and split
715          * out portions to satisfy requests.
716          *
717          * Note2- the idea here is that we want to deal with the optimal
718          * zonesize in the filesystem.  If we have it set to something less,
719          * then we have horrible problems with trying to piece together
720          * bits of adjacent blocks in order to properly read directory
721          * entries.  By forcing the blocksize in this way, we ensure
722          * that we will never be required to do this.
723          */
724         if ( orig_zonesize != opt.blocksize ) {
725                 set_blocksize(dev, orig_zonesize);
726 #ifndef BEQUIET
727                 printk(KERN_DEBUG 
728                         "ISOFS: Forcing new log zone size:%d\n", orig_zonesize);
729 #endif
730         }
731         s->s_blocksize = orig_zonesize;
732         s->s_blocksize_bits = s -> u.isofs_sb.s_log_zone_size;
733 
734         s->u.isofs_sb.s_nls_iocharset = NULL;
735 
736 #ifdef CONFIG_JOLIET
737         if (joliet_level && opt.utf8 == 0) {
738                 char * p = opt.iocharset ? opt.iocharset : "iso8859-1";
739                 s->u.isofs_sb.s_nls_iocharset = load_nls(p);
740                 if (! s->u.isofs_sb.s_nls_iocharset) {
741                         /* Fail only if explicit charset specified */
742                         if (opt.iocharset)
743                                 goto out_freebh;
744                         s->u.isofs_sb.s_nls_iocharset = load_nls_default();
745                 }
746         }
747 #endif
748         s->s_op = &isofs_sops;
749         s->u.isofs_sb.s_mapping = opt.map;
750         s->u.isofs_sb.s_rock = (opt.rock == 'y' ? 2 : 0);
751         s->u.isofs_sb.s_cruft = opt.cruft;
752         s->u.isofs_sb.s_unhide = opt.unhide;
753         s->u.isofs_sb.s_uid = opt.uid;
754         s->u.isofs_sb.s_gid = opt.gid;
755         s->u.isofs_sb.s_utf8 = opt.utf8;
756         /*
757          * It would be incredibly stupid to allow people to mark every file
758          * on the disk as suid, so we merely allow them to set the default
759          * permissions.
760          */
761         s->u.isofs_sb.s_mode = opt.mode & 0777;
762 
763         /*
764          * Read the root inode, which _may_ result in changing
765          * the s_rock flag. Once we have the final s_rock value,
766          * we then decide whether to use the Joliet descriptor.
767          */
768         inode = iget(s, s->u.isofs_sb.s_firstdatazone);
769 
770         /*
771          * If this disk has both Rock Ridge and Joliet on it, then we
772          * want to use Rock Ridge by default.  This can be overridden
773          * by using the norock mount option.  There is still one other
774          * possibility that is not taken into account: a Rock Ridge
775          * CD with Unicode names.  Until someone sees such a beast, it
776          * will not be supported.
777          */
778         if (s->u.isofs_sb.s_rock == 1) {
779                 joliet_level = 0;
780         } else if (joliet_level) {
781                 s->u.isofs_sb.s_rock = 0;
782                 if (s->u.isofs_sb.s_firstdatazone != first_data_zone) {
783                         s->u.isofs_sb.s_firstdatazone = first_data_zone;
784                         printk(KERN_DEBUG 
785                                 "ISOFS: changing to secondary root\n");
786                         iput(inode);
787                         inode = iget(s, s->u.isofs_sb.s_firstdatazone);
788                 }
789         }
790 
791         if (opt.check == 'u') {
792                 /* Only Joliet is case insensitive by default */
793                 if (joliet_level) opt.check = 'r';
794                 else opt.check = 's';
795         }
796         s->u.isofs_sb.s_joliet_level = joliet_level;
797 
798         /* check the root inode */
799         if (!inode)
800                 goto out_no_root;
801         if (!inode->i_op)
802                 goto out_bad_root;
803         /* get the root dentry */
804         s->s_root = d_alloc_root(inode);
805         if (!(s->s_root))
806                 goto out_no_root;
807 
808         table = 0;
809         if (joliet_level) table += 2;
810         if (opt.check == 'r') table++;
811         s->s_root->d_op = &isofs_dentry_ops[table];
812 
813         return s;
814 
815         /*
816          * Display error messages and free resources.
817          */
818 out_bad_root:
819         printk(KERN_WARNING "isofs_read_super: root inode not initialized\n");
820         goto out_iput;
821 out_no_root:
822         printk(KERN_WARNING "isofs_read_super: get root inode failed\n");
823 out_iput:
824         iput(inode);
825 #ifdef CONFIG_JOLIET
826         if (s->u.isofs_sb.s_nls_iocharset)
827                 unload_nls(s->u.isofs_sb.s_nls_iocharset);
828 #endif
829         goto out_unlock;
830 out_no_read:
831         printk(KERN_WARNING "isofs_read_super: "
832                 "bread failed, dev=%s, iso_blknum=%d, block=%d\n",
833                 kdevname(dev), iso_blknum, block);
834         goto out_unlock;
835 out_bad_zone_size:
836         printk(KERN_WARNING "Bad logical zone size %ld\n",
837                 s->u.isofs_sb.s_log_zone_size);
838         goto out_freebh;
839 out_bad_size:
840         printk(KERN_WARNING "Logical zone size(%d) < hardware blocksize(%u)\n",
841                 orig_zonesize, blocksize);
842         goto out_freebh;
843 #ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
844 out_no_support:
845         printk(KERN_WARNING "Multi-volume disks not supported.\n");
846         goto out_freebh;
847 #endif
848 out_unknown_format:
849         if (!silent)
850                 printk(KERN_WARNING "Unable to identify CD-ROM format.\n");
851 
852 out_freebh:
853         brelse(bh);
854 out_unlock:
855         return NULL;
856 }
857 
858 static int isofs_statfs (struct super_block *sb, struct statfs *buf)
859 {
860         buf->f_type = ISOFS_SUPER_MAGIC;
861         buf->f_bsize = sb->s_blocksize;
862         buf->f_blocks = (sb->u.isofs_sb.s_nzones
863                   << (sb->u.isofs_sb.s_log_zone_size - sb->s_blocksize_bits));
864         buf->f_bfree = 0;
865         buf->f_bavail = 0;
866         buf->f_files = sb->u.isofs_sb.s_ninodes;
867         buf->f_ffree = 0;
868         buf->f_namelen = NAME_MAX;
869         return 0;
870 }
871 
872 /* Life is simpler than for other filesystem since we never
873  * have to create a new block, only find an existing one.
874  */
875 static int isofs_get_block(struct inode *inode, long iblock,
876                     struct buffer_head *bh_result, int create)
877 {
878         unsigned long b_off;
879         unsigned offset, sect_size;
880         unsigned int firstext;
881         unsigned long nextino;
882         int i, err;
883 
884         lock_kernel();
885 
886         err = -EROFS;
887         if (create)
888                 goto abort_create_attempted;
889 
890         err = -EIO;
891         if (iblock < 0)
892                 goto abort_negative;
893 
894         b_off = iblock;
895 
896         /* If we are *way* beyond the end of the file, print a message.
897          * Access beyond the end of the file up to the next page boundary
898          * is normal, however because of the way the page cache works.
899          * In this case, we just return 0 so that we can properly fill
900          * the page with useless information without generating any
901          * I/O errors.
902          */
903         if (b_off > ((inode->i_size + PAGE_SIZE - 1) >> ISOFS_BUFFER_BITS(inode)))
904                 goto abort_beyond_end;
905 
906         offset    = 0;
907         firstext  = inode->u.isofs_i.i_first_extent;
908         sect_size = inode->u.isofs_i.i_section_size >> ISOFS_BUFFER_BITS(inode);
909         nextino   = inode->u.isofs_i.i_next_section_ino;
910 
911         i = 0;
912         if (nextino) {
913                 while (b_off >= (offset + sect_size)) {
914                         struct inode *ninode;
915 
916                         offset += sect_size;
917                         if (nextino == 0)
918                                 goto abort;
919                         ninode = iget(inode->i_sb, nextino);
920                         if (!ninode)
921                                 goto abort;
922                         firstext  = ninode->u.isofs_i.i_first_extent;
923                         sect_size = ninode->u.isofs_i.i_section_size;
924                         nextino   = ninode->u.isofs_i.i_next_section_ino;
925                         iput(ninode);
926 
927                         if (++i > 100)
928                                 goto abort_too_many_sections;
929                 }
930         }
931 
932         bh_result->b_dev = inode->i_dev;
933         bh_result->b_blocknr = firstext + b_off - offset;
934         bh_result->b_state |= (1UL << BH_Mapped);
935         err = 0;
936 
937 abort:
938         unlock_kernel();
939         return err;
940 
941 abort_create_attempted:
942         printk("isofs_get_block: Kernel tries to allocate a block\n");
943         goto abort;
944 
945 abort_negative:
946         printk("isofs_get_block: block < 0\n");
947         goto abort;
948 
949 abort_beyond_end:
950         printk("isofs_get_block: block >= EOF (%ld, %ld)\n",
951                iblock, (unsigned long) inode->i_size);
952         goto abort;
953 
954 abort_too_many_sections:
955         printk("isofs_get_block: More than 100 file sections ?!?, aborting...\n");
956         printk("isofs_get_block: ino=%lu block=%ld firstext=%u sect_size=%u nextino=%lu\n",
957                inode->i_ino, iblock, firstext, (unsigned) sect_size, nextino);
958         goto abort;
959 }
960 
961 static int isofs_bmap(struct inode *inode, int block)
962 {
963         struct buffer_head dummy;
964         int error;
965 
966         dummy.b_state = 0;
967         dummy.b_blocknr = -1000;
968         error = isofs_get_block(inode, block, &dummy, 0);
969         if (!error)
970                 return dummy.b_blocknr;
971         return 0;
972 }
973 
974 struct buffer_head *isofs_bread(struct inode *inode, unsigned int bufsize, unsigned int block)
975 {
976         unsigned int blknr = isofs_bmap(inode, block);
977         if (!blknr)
978                 return NULL;
979         return bread(inode->i_dev, blknr, bufsize);
980 }
981 
982 static int isofs_readpage(struct file *file, struct page *page)
983 {
984         return block_read_full_page(page,isofs_get_block);
985 }
986 
987 static int _isofs_bmap(struct address_space *mapping, long block)
988 {
989         return generic_block_bmap(mapping,block,isofs_get_block);
990 }
991 
992 static struct address_space_operations isofs_aops = {
993         readpage: isofs_readpage,
994         sync_page: block_sync_page,
995         bmap: _isofs_bmap
996 };
997 
998 static inline void test_and_set_uid(uid_t *p, uid_t value)
999 {
1000         if(value) {
1001                 *p = value;
1002         }
1003 }
1004 
1005 static inline void test_and_set_gid(gid_t *p, gid_t value)
1006 {
1007         if(value) {
1008                 *p = value;
1009         }
1010 }
1011 
1012 static int isofs_read_level3_size(struct inode * inode)
1013 {
1014         unsigned long f_pos = inode->i_ino;
1015         unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
1016         int high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
1017         struct buffer_head * bh = NULL;
1018         unsigned long block, offset;
1019         int i = 0;
1020         int more_entries = 0;
1021         struct iso_directory_record * tmpde = NULL;
1022 
1023         inode->i_size = 0;
1024         inode->u.isofs_i.i_next_section_ino = 0;
1025 
1026         block = f_pos >> ISOFS_BUFFER_BITS(inode);
1027         offset = f_pos & (bufsize-1);
1028 
1029         do {
1030                 struct iso_directory_record * de;
1031                 unsigned int de_len;
1032 
1033                 if (!bh) {
1034                         bh = bread(inode->i_dev, block, bufsize);
1035                         if (!bh)
1036                                 goto out_noread;
1037                 }
1038                 de = (struct iso_directory_record *) (bh->b_data + offset);
1039                 de_len = *(unsigned char *) de;
1040 
1041                 if (de_len == 0) {
1042                         brelse(bh);
1043                         bh = NULL;
1044                         f_pos = (f_pos + ISOFS_BLOCK_SIZE) & ~(ISOFS_BLOCK_SIZE - 1);
1045                         block = f_pos >> ISOFS_BUFFER_BITS(inode);
1046                         offset = 0;
1047                         continue;
1048                 }
1049 
1050                 offset += de_len;
1051 
1052                 /* Make sure we have a full directory entry */
1053                 if (offset >= bufsize) {
1054                         int slop = bufsize - offset + de_len;
1055                         if (!tmpde) {
1056                                 tmpde = kmalloc(256, GFP_KERNEL);
1057                                 if (!tmpde)
1058                                         goto out_nomem;
1059                         }
1060                         memcpy(tmpde, de, slop);
1061                         offset &= bufsize - 1;
1062                         block++;
1063                         brelse(bh);
1064                         bh = NULL;
1065                         if (offset) {
1066                                 bh = bread(inode->i_dev, block, bufsize);
1067                                 if (!bh)
1068                                         goto out_noread;
1069                                 memcpy((void *) tmpde + slop, bh->b_data, offset);
1070                         }
1071                         de = tmpde;
1072                 }
1073 
1074                 inode->i_size += isonum_733(de->size);
1075                 if (i == 1)
1076                         inode->u.isofs_i.i_next_section_ino = f_pos;
1077 
1078                 more_entries = de->flags[-high_sierra] & 0x80;
1079 
1080                 f_pos += de_len;
1081                 i++;
1082                 if(i > 100)
1083                         goto out_toomany;
1084         } while(more_entries);
1085 out:
1086         if (tmpde)
1087                 kfree(tmpde);
1088         if (bh)
1089                 brelse(bh);
1090         return 0;
1091 
1092 out_nomem:
1093         if (bh)
1094                 brelse(bh);
1095         return -ENOMEM;
1096 
1097 out_noread:
1098         printk(KERN_INFO "ISOFS: unable to read i-node block %lu\n", block);
1099         if (tmpde)
1100                 kfree(tmpde);
1101         return -EIO;
1102 
1103 out_toomany:
1104         printk(KERN_INFO "isofs_read_level3_size: "
1105                 "More than 100 file sections ?!?, aborting...\n"
1106                 "isofs_read_level3_size: inode=%lu ino=%lu\n",
1107                 inode->i_ino, f_pos);
1108         goto out;
1109 }
1110 
1111 static void isofs_read_inode(struct inode * inode)
1112 {
1113         struct super_block *sb = inode->i_sb;
1114         unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
1115         int block = inode->i_ino >> ISOFS_BUFFER_BITS(inode);
1116         int high_sierra = sb->u.isofs_sb.s_high_sierra;
1117         struct buffer_head * bh = NULL;
1118         struct iso_directory_record * de;
1119         struct iso_directory_record * tmpde = NULL;
1120         unsigned int de_len;
1121         unsigned long offset;
1122         int volume_seq_no, i;
1123 
1124         bh = bread(inode->i_dev, block, bufsize);
1125         if (!bh)
1126                 goto out_badread;
1127 
1128         offset = (inode->i_ino & (bufsize - 1));
1129         de = (struct iso_directory_record *) (bh->b_data + offset);
1130         de_len = *(unsigned char *) de;
1131 
1132         if (offset + de_len > bufsize) {
1133                 int frag1 = bufsize - offset;
1134 
1135                 tmpde = kmalloc(de_len, GFP_KERNEL);
1136                 if (tmpde == NULL) {
1137                         printk(KERN_INFO "isofs_read_inode: out of memory\n");
1138                         goto fail;
1139                 }
1140                 memcpy(tmpde, bh->b_data + offset, frag1);
1141                 brelse(bh);
1142                 bh = bread(inode->i_dev, ++block, bufsize);
1143                 if (!bh)
1144                         goto out_badread;
1145                 memcpy((char *)tmpde+frag1, bh->b_data, de_len - frag1);
1146                 de = tmpde;
1147         }
1148 
1149         if (de->flags[-high_sierra] & 2) {
1150                 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
1151                 inode->i_nlink = 1; /* Set to 1.  We know there are 2, but
1152                                        the find utility tries to optimize
1153                                        if it is 2, and it screws up.  It is
1154                                        easier to give 1 which tells find to
1155                                        do it the hard way. */
1156         } else {
1157                 /* Everybody gets to read the file. */
1158                 inode->i_mode = inode->i_sb->u.isofs_sb.s_mode;
1159                 inode->i_nlink = 1;
1160                 inode->i_mode |= S_IFREG;
1161                 /* If there are no periods in the name,
1162                  * then set the execute permission bit
1163                  */
1164                 for(i=0; i< de->name_len[0]; i++)
1165                         if(de->name[i]=='.' || de->name[i]==';')
1166                                 break;
1167                 if(i == de->name_len[0] || de->name[i] == ';')
1168                         inode->i_mode |= S_IXUGO; /* execute permission */
1169         }
1170         inode->i_uid = inode->i_sb->u.isofs_sb.s_uid;
1171         inode->i_gid = inode->i_sb->u.isofs_sb.s_gid;
1172         inode->i_blocks = inode->i_blksize = 0;
1173 
1174 
1175         inode->u.isofs_i.i_section_size = isonum_733 (de->size);
1176         if(de->flags[-high_sierra] & 0x80) {
1177                 if(isofs_read_level3_size(inode)) goto fail;
1178         } else {
1179                 inode->i_size = isonum_733 (de->size);
1180         }
1181 
1182         /* There are defective discs out there - we do this to protect
1183            ourselves.  A cdrom will never contain more than 800Mb 
1184            .. but a DVD may be up to 1Gig (Ulrich Habel) */
1185 
1186         if ((inode->i_size < 0 || inode->i_size > 1073741824) &&
1187             inode->i_sb->u.isofs_sb.s_cruft == 'n') {
1188                 printk(KERN_WARNING "Warning: defective CD-ROM.  "
1189                        "Enabling \"cruft\" mount option.\n");
1190                 inode->i_sb->u.isofs_sb.s_cruft = 'y';
1191         }
1192 
1193         /*
1194          * Some dipshit decided to store some other bit of information
1195          * in the high byte of the file length.  Catch this and holler.
1196          * WARNING: this will make it impossible for a file to be > 16MB
1197          * on the CDROM.
1198          */
1199 
1200         if (inode->i_sb->u.isofs_sb.s_cruft == 'y' &&
1201             inode->i_size & 0xff000000) {
1202                 inode->i_size &= 0x00ffffff;
1203         }
1204 
1205         if (de->interleave[0]) {
1206                 printk("Interleaved files not (yet) supported.\n");
1207                 inode->i_size = 0;
1208         }
1209 
1210         /* I have no idea what file_unit_size is used for, so
1211            we will flag it for now */
1212         if (de->file_unit_size[0] != 0) {
1213                 printk("File unit size != 0 for ISO file (%ld).\n",
1214                        inode->i_ino);
1215         }
1216 
1217         /* I have no idea what other flag bits are used for, so
1218            we will flag it for now */
1219 #ifdef DEBUG
1220         if((de->flags[-high_sierra] & ~2)!= 0){
1221                 printk("Unusual flag settings for ISO file (%ld %x).\n",
1222                        inode->i_ino, de->flags[-high_sierra]);
1223         }
1224 #endif
1225 
1226         inode->i_mtime = inode->i_atime = inode->i_ctime =
1227                 iso_date(de->date, high_sierra);
1228 
1229         inode->u.isofs_i.i_first_extent = (isonum_733 (de->extent) +
1230                                            isonum_711 (de->ext_attr_length));
1231 
1232         /*
1233          * Now test for possible Rock Ridge extensions which will override
1234          * some of these numbers in the inode structure.
1235          */
1236 
1237         if (!high_sierra) {
1238                 parse_rock_ridge_inode(de, inode);
1239                 /* if we want uid/gid set, override the rock ridge setting */
1240                 test_and_set_uid(&inode->i_uid, inode->i_sb->u.isofs_sb.s_uid);
1241                 test_and_set_gid(&inode->i_gid, inode->i_sb->u.isofs_sb.s_gid);
1242         }
1243 
1244         /* get the volume sequence number */
1245         volume_seq_no = isonum_723 (de->volume_sequence_number) ;
1246 
1247         /*
1248          * Disable checking if we see any volume number other than 0 or 1.
1249          * We could use the cruft option, but that has multiple purposes, one
1250          * of which is limiting the file size to 16Mb.  Thus we silently allow
1251          * volume numbers of 0 to go through without complaining.
1252          */
1253         if (inode->i_sb->u.isofs_sb.s_cruft == 'n' &&
1254             (volume_seq_no != 0) && (volume_seq_no != 1)) {
1255                 printk(KERN_WARNING "Warning: defective CD-ROM "
1256                        "(volume sequence number %d). "
1257                        "Enabling \"cruft\" mount option.\n", volume_seq_no);
1258                 inode->i_sb->u.isofs_sb.s_cruft = 'y';
1259         }
1260 
1261         /* Install the inode operations vector */
1262 #ifndef IGNORE_WRONG_MULTI_VOLUME_SPECS
1263         if (inode->i_sb->u.isofs_sb.s_cruft != 'y' &&
1264             (volume_seq_no != 0) && (volume_seq_no != 1)) {
1265                 printk(KERN_WARNING "Multi-volume CD somehow got mounted.\n");
1266         } else
1267 #endif /*IGNORE_WRONG_MULTI_VOLUME_SPECS */
1268         {
1269                 if (S_ISREG(inode->i_mode)) {
1270                         inode->i_fop = &generic_ro_fops;
1271                         inode->i_data.a_ops = &isofs_aops;
1272                 } else if (S_ISDIR(inode->i_mode)) {
1273                         inode->i_op = &isofs_dir_inode_operations;
1274                         inode->i_fop = &isofs_dir_operations;
1275                 } else if (S_ISLNK(inode->i_mode)) {
1276                         inode->i_op = &page_symlink_inode_operations;
1277                         inode->i_data.a_ops = &isofs_symlink_aops;
1278                 } else
1279                         /* XXX - parse_rock_ridge_inode() had already set i_rdev. */
1280                         init_special_inode(inode, inode->i_mode,
1281                                            kdev_t_to_nr(inode->i_rdev));
1282         }
1283  out:
1284         if (tmpde)
1285                 kfree(tmpde);
1286         if (bh)
1287                 brelse(bh);
1288         return;
1289 
1290  out_badread:
1291         printk(KERN_WARNING "ISOFS: unable to read i-node block\n");
1292  fail:
1293         make_bad_inode(inode);
1294         goto out;
1295 }
1296 
1297 #ifdef LEAK_CHECK
1298 #undef malloc
1299 #undef free_s
1300 #undef bread
1301 #undef brelse
1302 
1303 void * leak_check_malloc(unsigned int size){
1304   void * tmp;
1305   check_malloc++;
1306   tmp = kmalloc(size, GFP_KERNEL);
1307   return tmp;
1308 }
1309 
1310 void leak_check_free_s(void * obj, int size){
1311   check_malloc--;
1312   return kfree(obj);
1313 }
1314 
1315 struct buffer_head * leak_check_bread(int dev, int block, int size){
1316   check_bread++;
1317   return bread(dev, block, size);
1318 }
1319 
1320 void leak_check_brelse(struct buffer_head * bh){
1321   check_bread--;
1322   return brelse(bh);
1323 }
1324 
1325 #endif
1326 
1327 static DECLARE_FSTYPE_DEV(iso9660_fs_type, "iso9660", isofs_read_super);
1328 
1329 static int __init init_iso9660_fs(void)
1330 {
1331         return register_filesystem(&iso9660_fs_type);
1332 }
1333 
1334 static void __exit exit_iso9660_fs(void)
1335 {
1336         unregister_filesystem(&iso9660_fs_type);
1337 }
1338 
1339 EXPORT_NO_SYMBOLS;
1340 
1341 module_init(init_iso9660_fs)
1342 module_exit(exit_iso9660_fs)
1343 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.