root/fs/isofs/inode.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. isofs_put_super
  2. parse_options
  3. isofs_read_super
  4. isofs_statfs
  5. isofs_bmap
  6. isofs_read_inode
  7. isofs_lookup_grandparent
  8. leak_check_malloc
  9. leak_check_free_s
  10. leak_check_bread
  11. leak_check_brelse

   1 /*
   2  *  linux/fs/isofs/inode.c
   3  * 
   4  *  (C) 1992, 1993, 1994  Eric Youngdale Modified for ISO9660 filesystem.
   5  *
   6  *  (C) 1991  Linus Torvalds - minix filesystem
   7  */
   8 
   9 #include <linux/stat.h>
  10 #include <linux/sched.h>
  11 #include <linux/iso_fs.h>
  12 #include <linux/kernel.h>
  13 #include <linux/major.h>
  14 #include <linux/mm.h>
  15 #include <linux/string.h>
  16 #include <linux/locks.h>
  17 #include <linux/malloc.h>
  18 #include <linux/errno.h>
  19 
  20 #include <asm/system.h>
  21 #include <asm/segment.h>
  22 
  23 #ifdef LEAK_CHECK
  24 static int check_malloc = 0;
  25 static int check_bread = 0;
  26 #endif
  27 
  28 void isofs_put_super(struct super_block *sb)
     /* [previous][next][first][last][top][bottom][index][help] */
  29 {
  30         lock_super(sb);
  31 
  32 #ifdef LEAK_CHECK
  33         printk("Outstanding mallocs:%d, outstanding buffers: %d\n", 
  34                check_malloc, check_bread);
  35 #endif
  36         sb->s_dev = 0;
  37         unlock_super(sb);
  38         return;
  39 }
  40 
  41 static struct super_operations isofs_sops = { 
  42         isofs_read_inode,
  43         NULL,                   /* notify_change */
  44         NULL,                   /* write_inode */
  45         NULL,                   /* put_inode */
  46         isofs_put_super,
  47         NULL,                   /* write_super */
  48         isofs_statfs,
  49         NULL
  50 };
  51 
  52 struct iso9660_options{
  53   char map;
  54   char rock;
  55   char cruft;
  56   unsigned char conversion;
  57   unsigned int blocksize;
  58   gid_t gid;
  59   uid_t uid;
  60 };
  61 
  62 static int parse_options(char *options, struct iso9660_options * popt)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64         char *this_char,*value;
  65 
  66         popt->map = 'n';
  67         popt->rock = 'y';
  68         popt->cruft = 'n';
  69         popt->conversion = 'a';
  70         popt->blocksize = 1024;
  71         popt->gid = 0;
  72         popt->uid = 0;
  73         if (!options) return 1;
  74         for (this_char = strtok(options,","); this_char; this_char = strtok(NULL,",")) {
  75                 if (strncmp(this_char,"norock",6) == 0) {
  76                   popt->rock = 'n';
  77                   continue;
  78                 };
  79                 if (strncmp(this_char,"cruft",5) == 0) {
  80                   popt->cruft = 'y';
  81                   continue;
  82                 };
  83                 if ((value = strchr(this_char,'=')) != NULL)
  84                         *value++ = 0;
  85                 if (!strcmp(this_char,"map") && value) {
  86                         if (value[0] && !value[1] && strchr("on",*value))
  87                                 popt->map = *value;
  88                         else if (!strcmp(value,"off")) popt->map = 'o';
  89                         else if (!strcmp(value,"normal")) popt->map = 'n';
  90                         else return 0;
  91                 }
  92                 else if (!strcmp(this_char,"conv") && value) {
  93                         if (value[0] && !value[1] && strchr("bta",*value))
  94                                 popt->conversion = *value;
  95                         else if (!strcmp(value,"binary")) popt->conversion = 'b';
  96                         else if (!strcmp(value,"text")) popt->conversion = 't';
  97                         else if (!strcmp(value,"mtext")) popt->conversion = 'm';
  98                         else if (!strcmp(value,"auto")) popt->conversion = 'a';
  99                         else return 0;
 100                 }
 101                 else if (value && 
 102                          (!strcmp(this_char,"block") ||
 103                           !strcmp(this_char,"uid") ||
 104                           !strcmp(this_char,"gid"))) {
 105                   char * vpnt = value;
 106                   unsigned int ivalue;
 107                   ivalue = 0;
 108                   while(*vpnt){
 109                     if(*vpnt <  '0' || *vpnt > '9') break;
 110                     ivalue = ivalue * 10 + (*vpnt - '0');
 111                     vpnt++;
 112                   };
 113                   if (*vpnt) return 0;
 114                   switch(*this_char) {
 115                   case 'b':
 116                     if (ivalue != 1024 && ivalue != 2048) return 0;
 117                     popt->blocksize = ivalue;
 118                     break;
 119                   case 'g':
 120                     popt->uid = ivalue;
 121                     break;
 122                   case 'u':
 123                     popt->gid = ivalue;
 124                     break;
 125                   }
 126                 }
 127                 else return 0;
 128         }
 129         return 1;
 130 }
 131 
 132 struct super_block *isofs_read_super(struct super_block *s,void *data,
     /* [previous][next][first][last][top][bottom][index][help] */
 133                                      int silent)
 134 {
 135         struct buffer_head *bh;
 136         int iso_blknum;
 137         unsigned int blocksize_bits;
 138         int high_sierra;
 139         int dev=s->s_dev;
 140         struct iso_volume_descriptor *vdp;
 141         struct hs_volume_descriptor *hdp;
 142 
 143         struct iso_primary_descriptor *pri = NULL;
 144         struct hs_primary_descriptor *h_pri = NULL;
 145 
 146         struct iso_directory_record *rootp;
 147 
 148         struct iso9660_options opt;
 149 
 150         if (!parse_options((char *) data,&opt)) {
 151                 s->s_dev = 0;
 152                 return NULL;
 153         }
 154 
 155 #if 0
 156         printk("map = %c\n", opt.map);
 157         printk("rock = %c\n", opt.rock);
 158         printk("cruft = %c\n", opt.cruft);
 159         printk("conversion = %c\n", opt.conversion);
 160         printk("blocksize = %d\n", opt.blocksize);
 161         printk("gid = %d\n", opt.gid);
 162         printk("uid = %d\n", opt.uid);
 163 #endif
 164         
 165         blocksize_bits = 0;
 166         {
 167           int i = opt.blocksize;
 168           while (i != 1){
 169             blocksize_bits++;
 170             i >>=1;
 171           };
 172         };
 173         set_blocksize(dev, opt.blocksize);
 174 
 175         lock_super(s);
 176 
 177         s->u.isofs_sb.s_high_sierra = high_sierra = 0; /* default is iso9660 */
 178 
 179         for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
 180                 if (!(bh = bread(dev, iso_blknum << (ISOFS_BLOCK_BITS-blocksize_bits), opt.blocksize))) {
 181                         s->s_dev=0;
 182                         printk("isofs_read_super: bread failed, dev 0x%x iso_blknum %d\n",
 183                                dev, iso_blknum);
 184                         unlock_super(s);
 185                         return NULL;
 186                 }
 187 
 188                 vdp = (struct iso_volume_descriptor *)bh->b_data;
 189                 hdp = (struct hs_volume_descriptor *)bh->b_data;
 190 
 191                 
 192                 if (strncmp (hdp->id, HS_STANDARD_ID, sizeof hdp->id) == 0) {
 193                   if (isonum_711 (hdp->type) != ISO_VD_PRIMARY)
 194                         goto out;
 195                   if (isonum_711 (hdp->type) == ISO_VD_END)
 196                         goto out;
 197                 
 198                         s->u.isofs_sb.s_high_sierra = 1;
 199                         high_sierra = 1;
 200                         opt.rock = 'n';
 201                         h_pri = (struct hs_primary_descriptor *)vdp;
 202                         break;
 203                 };
 204                 
 205                 if (strncmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) == 0) {
 206                   if (isonum_711 (vdp->type) != ISO_VD_PRIMARY)
 207                         goto out;
 208                   if (isonum_711 (vdp->type) == ISO_VD_END)
 209                         goto out;
 210                 
 211                         pri = (struct iso_primary_descriptor *)vdp;
 212                         break;
 213                 };
 214 
 215                 brelse(bh);
 216               }
 217         if(iso_blknum == 100) {
 218                 if (!silent)
 219                         printk("Unable to identify CD-ROM format.\n");
 220                 s->s_dev = 0;
 221                 unlock_super(s);
 222                 return NULL;
 223         };
 224         
 225         
 226         if(high_sierra){
 227           rootp = (struct iso_directory_record *) h_pri->root_directory_record;
 228           if (isonum_723 (h_pri->volume_set_size) != 1) {
 229             printk("Multi-volume disks not (yet) supported.\n");
 230             goto out;
 231           };
 232           s->u.isofs_sb.s_nzones = isonum_733 (h_pri->volume_space_size);
 233           s->u.isofs_sb.s_log_zone_size = isonum_723 (h_pri->logical_block_size);
 234           s->u.isofs_sb.s_max_size = isonum_733(h_pri->volume_space_size);
 235         } else {
 236           rootp = (struct iso_directory_record *) pri->root_directory_record;
 237           if (isonum_723 (pri->volume_set_size) != 1) {
 238             printk("Multi-volume disks not (yet) supported.\n");
 239             goto out;
 240           };
 241           s->u.isofs_sb.s_nzones = isonum_733 (pri->volume_space_size);
 242           s->u.isofs_sb.s_log_zone_size = isonum_723 (pri->logical_block_size);
 243           s->u.isofs_sb.s_max_size = isonum_733(pri->volume_space_size);
 244         }
 245         
 246         s->u.isofs_sb.s_ninodes = 0; /* No way to figure this out easily */
 247         
 248         s->u.isofs_sb.s_firstdatazone = isonum_733( rootp->extent) << 
 249                 (ISOFS_BLOCK_BITS - blocksize_bits);
 250         s->s_magic = ISOFS_SUPER_MAGIC;
 251         
 252         /* The CDROM is read-only, has no nodes (devices) on it, and since
 253            all of the files appear to be owned by root, we really do not want
 254            to allow suid.  (suid or devices will not show up unless we have
 255            Rock Ridge extensions) */
 256         
 257         s->s_flags |= MS_RDONLY /* | MS_NODEV | MS_NOSUID */;
 258         
 259         if(s->u.isofs_sb.s_log_zone_size != (1 << ISOFS_BLOCK_BITS)) {
 260                 printk("1 <<Block bits != Block size\n");
 261                 goto out;
 262         };
 263         
 264         brelse(bh);
 265         
 266         printk("Max size:%ld   Log zone size:%ld\n",
 267                s->u.isofs_sb.s_max_size, 
 268                s->u.isofs_sb.s_log_zone_size);
 269         printk("First datazone:%ld   Root inode number %d\n",
 270                s->u.isofs_sb.s_firstdatazone,
 271                isonum_733 (rootp->extent) << ISOFS_BLOCK_BITS);
 272         if(high_sierra) printk("Disc in High Sierra format.\n");
 273         unlock_super(s);
 274         /* set up enough so that it can read an inode */
 275         
 276         s->s_dev = dev;
 277         s->s_op = &isofs_sops;
 278         s->u.isofs_sb.s_mapping = opt.map;
 279         s->u.isofs_sb.s_rock = (opt.rock == 'y' ? 1 : 0);
 280         s->u.isofs_sb.s_conversion = opt.conversion;
 281         s->u.isofs_sb.s_cruft = opt.cruft;
 282         s->u.isofs_sb.s_uid = opt.uid;
 283         s->u.isofs_sb.s_gid = opt.gid;
 284         s->s_blocksize = opt.blocksize;
 285         s->s_blocksize_bits = blocksize_bits;
 286         s->s_mounted = iget(s, isonum_733 (rootp->extent) << ISOFS_BLOCK_BITS);
 287         unlock_super(s);
 288 
 289         if (!(s->s_mounted)) {
 290                 s->s_dev=0;
 291                 printk("get root inode failed\n");
 292                 return NULL;
 293         }
 294 
 295         if(!check_disk_change(s->s_dev)) return s;
 296  out: /* Kick out for various error conditions */
 297         brelse(bh);
 298         s->s_dev = 0;
 299         unlock_super(s);
 300         return NULL;
 301 }
 302 
 303 void isofs_statfs (struct super_block *sb, struct statfs *buf)
     /* [previous][next][first][last][top][bottom][index][help] */
 304 {
 305         put_fs_long(ISOFS_SUPER_MAGIC, &buf->f_type);
 306         put_fs_long(1 << ISOFS_BLOCK_BITS, &buf->f_bsize);
 307         put_fs_long(sb->u.isofs_sb.s_nzones, &buf->f_blocks);
 308         put_fs_long(0, &buf->f_bfree);
 309         put_fs_long(0, &buf->f_bavail);
 310         put_fs_long(sb->u.isofs_sb.s_ninodes, &buf->f_files);
 311         put_fs_long(0, &buf->f_ffree);
 312         put_fs_long(NAME_MAX, &buf->f_namelen);
 313         /* Don't know what value to put in buf->f_fsid */
 314 }
 315 
 316 int isofs_bmap(struct inode * inode,int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 317 {
 318 
 319         if (block<0) {
 320                 printk("_isofs_bmap: block<0");
 321                 return 0;
 322         }
 323         return inode->u.isofs_i.i_first_extent + block;
 324 }
 325 
 326 void isofs_read_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 327 {
 328         unsigned long bufsize = ISOFS_BUFFER_SIZE(inode);
 329         struct buffer_head * bh;
 330         struct iso_directory_record * raw_inode;
 331         unsigned char *pnt = NULL;
 332         void *cpnt = NULL;
 333         int high_sierra;
 334         int block;
 335         int i;
 336 
 337         block = inode->i_ino >> ISOFS_BUFFER_BITS(inode);
 338         if (!(bh=bread(inode->i_dev,block, bufsize))) {
 339           printk("unable to read i-node block");
 340           goto fail;
 341         }
 342         
 343         pnt = ((unsigned char *) bh->b_data
 344                + (inode->i_ino & (bufsize - 1)));
 345         raw_inode = ((struct iso_directory_record *) pnt);
 346         high_sierra = inode->i_sb->u.isofs_sb.s_high_sierra;
 347 
 348         if ((inode->i_ino & (bufsize - 1)) + *pnt > bufsize){
 349                 cpnt = kmalloc(1 << ISOFS_BLOCK_BITS, GFP_KERNEL);
 350                 if (cpnt == NULL) {
 351                         printk(KERN_INFO "NoMem ISO inode %lu\n",inode->i_ino);
 352                         brelse(bh);
 353                         goto fail;
 354                 }
 355                 memcpy(cpnt, bh->b_data, bufsize);
 356                 brelse(bh);
 357                 if (!(bh = bread(inode->i_dev,++block, bufsize))) {
 358                         kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
 359                         printk("unable to read i-node block");
 360                         goto fail;
 361                 }
 362                 memcpy((char *)cpnt + bufsize, bh->b_data, bufsize);
 363                 pnt = ((unsigned char *) cpnt
 364                        + (inode->i_ino & (bufsize - 1)));
 365                 raw_inode = ((struct iso_directory_record *) pnt);
 366         }
 367 
 368         inode->i_mode = S_IRUGO; /* Everybody gets to read the file. */
 369         inode->i_nlink = 1;
 370         
 371         if (raw_inode->flags[-high_sierra] & 2) {
 372                 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
 373                 inode->i_nlink = 2; /* There are always at least 2.  It is
 374                                        hard to figure out what is correct*/
 375         } else {
 376                 inode->i_mode = S_IRUGO; /* Everybody gets to read the file. */
 377                 inode->i_nlink = 1;
 378                 inode->i_mode |= S_IFREG;
 379 /* If there are no periods in the name, then set the execute permission bit */
 380                 for(i=0; i< raw_inode->name_len[0]; i++)
 381                         if(raw_inode->name[i]=='.' || raw_inode->name[i]==';')
 382                                 break;
 383                 if(i == raw_inode->name_len[0] || raw_inode->name[i] == ';') 
 384                         inode->i_mode |= S_IXUGO; /* execute permission */
 385         }
 386         inode->i_uid = inode->i_sb->u.isofs_sb.s_uid;
 387         inode->i_gid = inode->i_sb->u.isofs_sb.s_gid;
 388         inode->i_size = isonum_733 (raw_inode->size);
 389 
 390         /* There are defective discs out there - we do this to protect
 391            ourselves.  A cdrom will never contain more than 700Mb */
 392         if((inode->i_size < 0 || inode->i_size > 700000000) &&
 393             inode->i_sb->u.isofs_sb.s_cruft == 'n') {
 394           printk("Warning: defective cdrom.  Enabling \"cruft\" mount option.\n");
 395           inode->i_sb->u.isofs_sb.s_cruft = 'y';
 396         }
 397 
 398 /* Some dipshit decided to store some other bit of information in the high
 399    byte of the file length.  Catch this and holler.  WARNING: this will make
 400    it impossible for a file to be > 16Mb on the CDROM!!!*/
 401 
 402         if(inode->i_sb->u.isofs_sb.s_cruft == 'y' && 
 403            inode->i_size & 0xff000000){
 404 /*        printk("Illegal format on cdrom.  Pester manufacturer.\n"); */
 405           inode->i_size &= 0x00ffffff;
 406         }
 407         
 408         if (raw_inode->interleave[0]) {
 409                 printk("Interleaved files not (yet) supported.\n");
 410                 inode->i_size = 0;
 411         }
 412 
 413         /* I have no idea what file_unit_size is used for, so
 414            we will flag it for now */
 415         if(raw_inode->file_unit_size[0] != 0){
 416                 printk("File unit size != 0 for ISO file (%ld).\n",inode->i_ino);
 417         }
 418 
 419         /* I have no idea what other flag bits are used for, so
 420            we will flag it for now */
 421         if((raw_inode->flags[-high_sierra] & ~2)!= 0){
 422                 printk("Unusual flag settings for ISO file (%ld %x).\n",
 423                        inode->i_ino, raw_inode->flags[-high_sierra]);
 424         }
 425 
 426 #ifdef DEBUG
 427         printk("Get inode %d: %d %d: %d\n",inode->i_ino, block, 
 428                ((int)pnt) & 0x3ff, inode->i_size);
 429 #endif
 430         
 431         inode->i_mtime = inode->i_atime = inode->i_ctime = 
 432           iso_date(raw_inode->date, high_sierra);
 433 
 434         inode->u.isofs_i.i_first_extent = 
 435           (isonum_733 (raw_inode->extent) + 
 436            isonum_711 (raw_inode->ext_attr_length)) << 
 437                 (ISOFS_BLOCK_BITS - ISOFS_BUFFER_BITS(inode));
 438         
 439         inode->u.isofs_i.i_backlink = 0xffffffff; /* Will be used for previous directory */
 440         switch (inode->i_sb->u.isofs_sb.s_conversion){
 441         case 'a':
 442           inode->u.isofs_i.i_file_format = ISOFS_FILE_UNKNOWN; /* File type */
 443           break;
 444         case 'b':
 445           inode->u.isofs_i.i_file_format = ISOFS_FILE_BINARY; /* File type */
 446           break;
 447         case 't':
 448           inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT; /* File type */
 449           break;
 450         case 'm':
 451           inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT_M; /* File type */
 452           break;
 453         }
 454 
 455 /* Now test for possible Rock Ridge extensions which will override some of
 456    these numbers in the inode structure. */
 457 
 458         if (!high_sierra)
 459           parse_rock_ridge_inode(raw_inode, inode);
 460         
 461 #ifdef DEBUG
 462         printk("Inode: %x extent: %x\n",inode->i_ino, inode->u.isofs_i.i_first_extent);
 463 #endif
 464         brelse(bh);
 465         
 466         inode->i_op = NULL;
 467 
 468         /* A volume number of 0 is nonsense.  Disable checking if we see
 469            this */
 470         if (inode->i_sb->u.isofs_sb.s_cruft == 'n' && 
 471             isonum_723 (raw_inode->volume_sequence_number) == 0) {
 472           printk("Warning: defective cdrom.  Enabling \"cruft\" mount option.\n");
 473           inode->i_sb->u.isofs_sb.s_cruft = 'y';
 474         }
 475 
 476         if (inode->i_sb->u.isofs_sb.s_cruft != 'y' && 
 477             isonum_723 (raw_inode->volume_sequence_number) != 1) {
 478                 printk("Multi volume CD somehow got mounted.\n");
 479         } else {
 480           if (S_ISREG(inode->i_mode))
 481             inode->i_op = &isofs_file_inode_operations;
 482           else if (S_ISDIR(inode->i_mode))
 483             inode->i_op = &isofs_dir_inode_operations;
 484           else if (S_ISLNK(inode->i_mode))
 485             inode->i_op = &isofs_symlink_inode_operations;
 486           else if (S_ISCHR(inode->i_mode))
 487             inode->i_op = &chrdev_inode_operations;
 488           else if (S_ISBLK(inode->i_mode))
 489             inode->i_op = &blkdev_inode_operations;
 490           else if (S_ISFIFO(inode->i_mode))
 491             init_fifo(inode);
 492         }
 493         if (cpnt) {
 494                 kfree_s (cpnt, 1 << ISOFS_BLOCK_BITS);
 495                 cpnt = NULL;
 496         }
 497         return;
 498       fail:
 499         /* With a data error we return this information */
 500         inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
 501         inode->u.isofs_i.i_first_extent = 0;
 502         inode->u.isofs_i.i_backlink = 0xffffffff;
 503         inode->i_size = 0;
 504         inode->i_nlink = 1;
 505         inode->i_uid = inode->i_gid = 0;
 506         inode->i_mode = S_IFREG;  /*Regular file, noone gets to read*/
 507         inode->i_op = NULL;
 508         return;
 509 }
 510 
 511 /* There are times when we need to know the inode number of a parent of
 512    a particular directory.  When control passes through a routine that
 513    has access to the parent information, it fills it into the inode structure,
 514    but sometimes the inode gets flushed out of the queue, and someone
 515    remmembers the number.  When they try to open up again, we have lost
 516    the information.  The '..' entry on the disc points to the data area
 517    for a particular inode, so we can follow these links back up, but since
 518    we do not know the inode number, we do not actually know how large the
 519    directory is.  The disc is almost always correct, and there is
 520    enough error checking on the drive itself, but an open ended search
 521    makes me a little nervous.
 522 
 523    The bsd iso filesystem uses the extent number for an inode, and this
 524    would work really nicely for us except that the read_inode function
 525    would not have any clean way of finding the actual directory record
 526    that goes with the file.  If we had such info, then it would pay
 527    to change the inode numbers and eliminate this function.
 528 */
 529 
 530 int isofs_lookup_grandparent(struct inode * parent, int extent)
     /* [previous][next][first][last][top][bottom][index][help] */
 531 {
 532         unsigned long bufsize = ISOFS_BUFFER_SIZE(parent);
 533         unsigned char bufbits = ISOFS_BUFFER_BITS(parent);
 534         unsigned int block,offset;
 535         int parent_dir, inode_number;
 536         int old_offset;
 537         void * cpnt = NULL;
 538         int result;
 539         struct buffer_head * bh;
 540         struct iso_directory_record * de;
 541         
 542         offset = 0;
 543         block = extent << (ISOFS_BLOCK_BITS - bufbits);
 544         if (!(bh = bread(parent->i_dev, block, bufsize)))  return -1;
 545         
 546         while (1 == 1) {
 547                 de = (struct iso_directory_record *) (bh->b_data + offset);
 548                 if (*((unsigned char *) de) == 0) 
 549                 {
 550                         brelse(bh);
 551                         return -1;
 552                 }
 553                 
 554                 offset += *((unsigned char *) de);
 555 
 556                 if (offset >= bufsize) 
 557                 {
 558                         printk(".. Directory not in first block"
 559                                " of directory.\n");
 560                         brelse(bh);
 561                         return -1;
 562                 }
 563                 
 564                 if (de->name_len[0] == 1 && de->name[0] == 1) 
 565                 {
 566                         parent_dir = find_rock_ridge_relocation(de, parent);
 567                         brelse(bh);
 568                         break;
 569                 }
 570         }
 571 #ifdef DEBUG
 572         printk("Parent dir:%x\n",parent_dir);
 573 #endif
 574         /* Now we know the extent where the parent dir starts on.  We have no
 575            idea how long it is, so we just start reading until we either find
 576            it or we find some kind of unreasonable circumstance. */
 577         
 578         result = -1;
 579 
 580         offset = 0;
 581         block = parent_dir << (ISOFS_BLOCK_BITS - bufbits);
 582         if (!block || !(bh = bread(parent->i_dev,block, bufsize)))
 583                 return -1;
 584         
 585         for(;;)
 586         {
 587                 de = (struct iso_directory_record *) (bh->b_data + offset);
 588                 inode_number = (block << bufbits)+(offset & (bufsize - 1));
 589                 
 590                 /* If the length byte is zero, we should move on to the next
 591                    CDROM sector.  If we are at the end of the directory, we
 592                    kick out of the while loop. */
 593                 
 594                 if (*((unsigned char *) de) == 0) 
 595                 {
 596                         brelse(bh);
 597                         offset = 0;
 598                         block++;
 599                         if((block & 1) && (ISOFS_BLOCK_BITS - bufbits))
 600                           return -1;
 601                         if (!block
 602                             || !(bh = bread(parent->i_dev,block, bufsize)))
 603                                 return -1;
 604                         continue;
 605                 }
 606                 
 607                 /* Make sure that the entire directory record is in the current
 608                    bh block.  If not, we malloc a buffer, and put the two
 609                    halves together, so that we can cleanly read the block.  */
 610 
 611                 old_offset = offset;
 612                 offset += *((unsigned char *) de);
 613 
 614                 if (offset >= bufsize)
 615                 {
 616                         if((block & 1) != 0) return -1;
 617                         cpnt = kmalloc(1<<ISOFS_BLOCK_BITS,GFP_KERNEL);
 618                         memcpy(cpnt, bh->b_data, bufsize);
 619                         de = (struct iso_directory_record *)
 620                                 ((char *)cpnt + old_offset);
 621                         brelse(bh);
 622                         offset -= bufsize;
 623                         block++;
 624                         if (!(bh = bread(parent->i_dev,block,bufsize))) {
 625                                 kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
 626                                 return -1;
 627                         };
 628                         memcpy((char *)cpnt+bufsize, bh->b_data, bufsize);
 629                 }
 630                 
 631                 if (find_rock_ridge_relocation(de, parent) == extent){
 632                         result = inode_number;
 633                         goto out;
 634                 }
 635                 
 636                 if (cpnt) {
 637                         kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
 638                         cpnt = NULL;
 639                 }
 640         }
 641 
 642         /* We go here for any condition we cannot handle.
 643            We also drop through to here at the end of the directory. */
 644 
 645  out:
 646         if (cpnt) {
 647                 kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
 648                 cpnt = NULL;
 649         }
 650         brelse(bh);
 651 #ifdef DEBUG
 652         printk("Resultant Inode %d\n",result);
 653 #endif
 654         return result;
 655 }
 656     
 657 #ifdef LEAK_CHECK
 658 #undef malloc
 659 #undef free_s
 660 #undef bread
 661 #undef brelse
 662 
 663 void * leak_check_malloc(unsigned int size){
     /* [previous][next][first][last][top][bottom][index][help] */
 664   void * tmp;
 665   check_malloc++;
 666   tmp = kmalloc(size, GFP_KERNEL);
 667   return tmp;
 668 }
 669 
 670 void leak_check_free_s(void * obj, int size){
     /* [previous][next][first][last][top][bottom][index][help] */
 671   check_malloc--;
 672   return kfree_s(obj, size);
 673 }
 674 
 675 struct buffer_head * leak_check_bread(int dev, int block, int size){
     /* [previous][next][first][last][top][bottom][index][help] */
 676   check_bread++;
 677   return bread(dev, block, size);
 678 }
 679 
 680 void leak_check_brelse(struct buffer_head * bh){
     /* [previous][next][first][last][top][bottom][index][help] */
 681   check_bread--;
 682   return brelse(bh);
 683 }
 684 
 685 #endif

/* [previous][next][first][last][top][bottom][index][help] */