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

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