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  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                 memcpy(cpnt, bh->b_data, bufsize);
 357                 brelse(bh);
 358                 if (!(bh = bread(inode->i_dev,++block, bufsize))) {
 359                         kfree_s (cpnt, 1 << ISOFS_BLOCK_BITS);
 360                         printk("unable to read i-node block");
 361                         goto fail;
 362                       };
 363                 memcpy((char *)cpnt + bufsize, bh->b_data, bufsize);
 364                 pnt = ((unsigned char *) cpnt
 365                        + (inode->i_ino & (bufsize - 1)));
 366                 raw_inode = ((struct iso_directory_record *) pnt);
 367         };
 368 
 369         inode->i_mode = S_IRUGO; /* Everybody gets to read the file. */
 370         inode->i_nlink = 1;
 371         
 372         if (raw_inode->flags[-high_sierra] & 2) {
 373                 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
 374                 inode->i_nlink = 2; /* There are always at least 2.  It is
 375                                        hard to figure out what is correct*/
 376         } else {
 377                 inode->i_mode = S_IRUGO; /* Everybody gets to read the file. */
 378                 inode->i_nlink = 1;
 379                 inode->i_mode |= S_IFREG;
 380 /* If there are no periods in the name, then set the execute permission bit */
 381                 for(i=0; i< raw_inode->name_len[0]; i++)
 382                         if(raw_inode->name[i]=='.' || raw_inode->name[i]==';')
 383                                 break;
 384                 if(i == raw_inode->name_len[0] || raw_inode->name[i] == ';') 
 385                         inode->i_mode |= S_IXUGO; /* execute permission */
 386         };
 387         inode->i_uid = 0;
 388         inode->i_gid = 0;
 389         inode->i_size = isonum_733 (raw_inode->size);
 390 
 391         /* There are defective discs out there - we do this to protect
 392            ourselves.  A cdrom will never contain more than 700Mb */
 393         if((inode->i_size < 0 || inode->i_size > 700000000) &&
 394             inode->i_sb->u.isofs_sb.s_cruft == 'n') {
 395           printk("Warning: defective cdrom.  Enabling \"cruft\" mount option.\n");
 396           inode->i_sb->u.isofs_sb.s_cruft = 'y';
 397         };
 398 
 399 /* Some dipshit decided to store some other bit of information in the high
 400    byte of the file length.  Catch this and holler.  WARNING: this will make
 401    it impossible for a file to be > 16Mb on the CDROM!!!*/
 402 
 403         if(inode->i_sb->u.isofs_sb.s_cruft == 'y' && 
 404            inode->i_size & 0xff000000){
 405 /*        printk("Illegal format on cdrom.  Pester manufacturer.\n"); */
 406           inode->i_size &= 0x00ffffff;
 407         };
 408         
 409         if (raw_inode->interleave[0]) {
 410                 printk("Interleaved files not (yet) supported.\n");
 411                 inode->i_size = 0;
 412         };
 413 
 414 #ifdef DEBUG
 415         /* I have no idea what extended attributes are used for, so
 416            we will flag it for now */
 417         if(raw_inode->ext_attr_length[0] != 0){
 418                 printk("Extended attributes present for ISO file (%ld).\n",
 419                        inode->i_ino);
 420         }
 421 #endif
 422         
 423         /* I have no idea what file_unit_size is used for, so
 424            we will flag it for now */
 425         if(raw_inode->file_unit_size[0] != 0){
 426                 printk("File unit size != 0 for ISO file (%ld).\n",inode->i_ino);
 427         }
 428 
 429         /* I have no idea what other flag bits are used for, so
 430            we will flag it for now */
 431         if((raw_inode->flags[-high_sierra] & ~2)!= 0){
 432                 printk("Unusual flag settings for ISO file (%ld %x).\n",
 433                        inode->i_ino, raw_inode->flags[-high_sierra]);
 434         }
 435 
 436 #ifdef DEBUG
 437         printk("Get inode %d: %d %d: %d\n",inode->i_ino, block, 
 438                ((int)pnt) & 0x3ff, inode->i_size);
 439 #endif
 440         
 441         inode->i_mtime = inode->i_atime = inode->i_ctime = 
 442           iso_date(raw_inode->date, high_sierra);
 443 
 444         inode->u.isofs_i.i_first_extent = isonum_733 (raw_inode->extent) << 
 445                 (ISOFS_BLOCK_BITS - ISOFS_BUFFER_BITS(inode));
 446         
 447         inode->u.isofs_i.i_backlink = 0xffffffff; /* Will be used for previous directory */
 448         switch (inode->i_sb->u.isofs_sb.s_conversion){
 449         case 'a':
 450           inode->u.isofs_i.i_file_format = ISOFS_FILE_UNKNOWN; /* File type */
 451           break;
 452         case 'b':
 453           inode->u.isofs_i.i_file_format = ISOFS_FILE_BINARY; /* File type */
 454           break;
 455         case 't':
 456           inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT; /* File type */
 457           break;
 458         case 'm':
 459           inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT_M; /* File type */
 460           break;
 461         };
 462         
 463 
 464 /* Now test for possible Rock Ridge extensions which will override some of
 465    these numbers in the inode structure. */
 466 
 467         if (!high_sierra)
 468           parse_rock_ridge_inode(raw_inode, inode);
 469         
 470 #ifdef DEBUG
 471         printk("Inode: %x extent: %x\n",inode->i_ino, inode->u.isofs_i.i_first_extent);
 472 #endif
 473         brelse(bh);
 474         
 475         if (cpnt) {
 476                 kfree_s (cpnt, 1 << ISOFS_BLOCK_BITS);
 477                 cpnt = NULL;
 478         };
 479         
 480         inode->i_op = NULL;
 481         if (inode->i_sb->u.isofs_sb.s_cruft != 'y' && 
 482             isonum_723 (raw_inode->volume_sequence_number) != 1) {
 483                 printk("Multi volume CD somehow got mounted.\n");
 484         } else {
 485           if (S_ISREG(inode->i_mode))
 486             inode->i_op = &isofs_file_inode_operations;
 487           else if (S_ISDIR(inode->i_mode))
 488             inode->i_op = &isofs_dir_inode_operations;
 489           else if (S_ISLNK(inode->i_mode))
 490             inode->i_op = &isofs_symlink_inode_operations;
 491           else if (S_ISCHR(inode->i_mode))
 492             inode->i_op = &chrdev_inode_operations;
 493           else if (S_ISBLK(inode->i_mode))
 494             inode->i_op = &blkdev_inode_operations;
 495           else if (S_ISFIFO(inode->i_mode))
 496             init_fifo(inode);
 497         }
 498         return;
 499       fail:
 500         /* With a data error we return this information */
 501         inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
 502         inode->u.isofs_i.i_first_extent = 0;
 503         inode->u.isofs_i.i_backlink = 0xffffffff;
 504         inode->i_size = 0;
 505         inode->i_nlink = 1;
 506         inode->i_uid = inode->i_gid = 0;
 507         inode->i_mode = S_IFREG;  /*Regular file, noone gets to read*/
 508         inode->i_op = NULL;
 509         return;
 510 }
 511 
 512 /* There are times when we need to know the inode number of a parent of
 513    a particular directory.  When control passes through a routine that
 514    has access to the parent information, it fills it into the inode structure,
 515    but sometimes the inode gets flushed out of the queue, and someone
 516    remmembers the number.  When they try to open up again, we have lost
 517    the information.  The '..' entry on the disc points to the data area
 518    for a particular inode, so we can follow these links back up, but since
 519    we do not know the inode number, we do not actually know how large the
 520    directory is.  The disc is almost always correct, and there is
 521    enough error checking on the drive itself, but an open ended search
 522    makes me a little nervous.
 523 
 524    The bsd iso filesystem uses the extent number for an inode, and this
 525    would work really nicely for us except that the read_inode function
 526    would not have any clean way of finding the actual directory record
 527    that goes with the file.  If we had such info, then it would pay
 528    to change the inode numbers and eliminate this function.
 529 */
 530 
 531 int isofs_lookup_grandparent(struct inode * parent, int extent)
     /* [previous][next][first][last][top][bottom][index][help] */
 532 {
 533         unsigned long bufsize = ISOFS_BUFFER_SIZE(parent);
 534         unsigned char bufbits = ISOFS_BUFFER_BITS(parent);
 535         unsigned int block,offset;
 536         int parent_dir, inode_number;
 537         int old_offset;
 538         void * cpnt = NULL;
 539         int result;
 540         struct buffer_head * bh;
 541         struct iso_directory_record * de;
 542         
 543         offset = 0;
 544         block = extent << (ISOFS_BLOCK_BITS - bufbits);
 545         if (!(bh = bread(parent->i_dev, block, bufsize)))  return -1;
 546         
 547         while (1 == 1) {
 548                 de = (struct iso_directory_record *) (bh->b_data + offset);
 549                 if (*((unsigned char *) de) == 0) 
 550                 {
 551                         brelse(bh);
 552                         return -1;
 553                 }
 554                 
 555                 offset += *((unsigned char *) de);
 556 
 557                 if (offset >= bufsize) 
 558                 {
 559                         printk(".. Directory not in first block"
 560                                " of directory.\n");
 561                         brelse(bh);
 562                         return -1;
 563                 }
 564                 
 565                 if (de->name_len[0] == 1 && de->name[0] == 1) 
 566                 {
 567                         parent_dir = find_rock_ridge_relocation(de, parent);
 568                         brelse(bh);
 569                         break;
 570                 }
 571         }
 572 #ifdef DEBUG
 573         printk("Parent dir:%x\n",parent_dir);
 574 #endif
 575         /* Now we know the extent where the parent dir starts on.  We have no
 576            idea how long it is, so we just start reading until we either find
 577            it or we find some kind of unreasonable circumstance. */
 578         
 579         result = -1;
 580 
 581         offset = 0;
 582         block = parent_dir << (ISOFS_BLOCK_BITS - bufbits);
 583         if (!block || !(bh = bread(parent->i_dev,block, bufsize)))
 584                 return -1;
 585         
 586         for(;;)
 587         {
 588                 de = (struct iso_directory_record *) (bh->b_data + offset);
 589                 inode_number = (block << bufbits)+(offset & (bufsize - 1));
 590                 
 591                 /* If the length byte is zero, we should move on to the next
 592                    CDROM sector.  If we are at the end of the directory, we
 593                    kick out of the while loop. */
 594                 
 595                 if (*((unsigned char *) de) == 0) 
 596                 {
 597                         brelse(bh);
 598                         offset = 0;
 599                         block++;
 600                         if(block & 1) 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] */