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                 int frag1, offset;
 350 
 351                 offset = (inode->i_ino & (bufsize - 1));
 352                 frag1 = bufsize - offset;
 353                 cpnt = kmalloc(*pnt,GFP_KERNEL);
 354                 if (cpnt == NULL) {
 355                         printk(KERN_INFO "NoMem ISO inode %lu\n",inode->i_ino);
 356                         brelse(bh);
 357                         goto fail;
 358                 }
 359                 memcpy(cpnt, bh->b_data + offset, frag1);
 360                 brelse(bh);
 361                 if (!(bh = bread(inode->i_dev,++block, bufsize))) {
 362                         kfree(cpnt);
 363                         printk("unable to read i-node block");
 364                         goto fail;
 365                 }
 366                 offset += *pnt - bufsize;
 367                 memcpy((char *)cpnt+frag1, bh->b_data, offset);
 368                 pnt = ((unsigned char *) cpnt);
 369                 raw_inode = ((struct iso_directory_record *) pnt);
 370         }
 371 
 372         inode->i_mode = S_IRUGO; /* Everybody gets to read the file. */
 373         inode->i_nlink = 1;
 374         
 375         if (raw_inode->flags[-high_sierra] & 2) {
 376                 inode->i_mode = S_IRUGO | S_IXUGO | S_IFDIR;
 377                 inode->i_nlink = 1; /* Set to 1.  We know there are 2, but
 378                                        the find utility tries to optimize
 379                                        if it is 2, and it screws up.  It is
 380                                        easier to give 1 which tells find to
 381                                        do it the hard way. */
 382         } else {
 383                 inode->i_mode = S_IRUGO; /* Everybody gets to read the file. */
 384                 inode->i_nlink = 1;
 385                 inode->i_mode |= S_IFREG;
 386 /* If there are no periods in the name, then set the execute permission bit */
 387                 for(i=0; i< raw_inode->name_len[0]; i++)
 388                         if(raw_inode->name[i]=='.' || raw_inode->name[i]==';')
 389                                 break;
 390                 if(i == raw_inode->name_len[0] || raw_inode->name[i] == ';') 
 391                         inode->i_mode |= S_IXUGO; /* execute permission */
 392         }
 393         inode->i_uid = inode->i_sb->u.isofs_sb.s_uid;
 394         inode->i_gid = inode->i_sb->u.isofs_sb.s_gid;
 395         inode->i_size = isonum_733 (raw_inode->size);
 396 
 397         /* There are defective discs out there - we do this to protect
 398            ourselves.  A cdrom will never contain more than 700Mb */
 399         if((inode->i_size < 0 || inode->i_size > 700000000) &&
 400             inode->i_sb->u.isofs_sb.s_cruft == 'n') {
 401           printk("Warning: defective cdrom.  Enabling \"cruft\" mount option.\n");
 402           inode->i_sb->u.isofs_sb.s_cruft = 'y';
 403         }
 404 
 405 /* Some dipshit decided to store some other bit of information in the high
 406    byte of the file length.  Catch this and holler.  WARNING: this will make
 407    it impossible for a file to be > 16Mb on the CDROM!!!*/
 408 
 409         if(inode->i_sb->u.isofs_sb.s_cruft == 'y' && 
 410            inode->i_size & 0xff000000){
 411 /*        printk("Illegal format on cdrom.  Pester manufacturer.\n"); */
 412           inode->i_size &= 0x00ffffff;
 413         }
 414         
 415         if (raw_inode->interleave[0]) {
 416                 printk("Interleaved files not (yet) supported.\n");
 417                 inode->i_size = 0;
 418         }
 419 
 420         /* I have no idea what file_unit_size is used for, so
 421            we will flag it for now */
 422         if(raw_inode->file_unit_size[0] != 0){
 423                 printk("File unit size != 0 for ISO file (%ld).\n",inode->i_ino);
 424         }
 425 
 426         /* I have no idea what other flag bits are used for, so
 427            we will flag it for now */
 428         if((raw_inode->flags[-high_sierra] & ~2)!= 0){
 429                 printk("Unusual flag settings for ISO file (%ld %x).\n",
 430                        inode->i_ino, raw_inode->flags[-high_sierra]);
 431         }
 432 
 433 #ifdef DEBUG
 434         printk("Get inode %d: %d %d: %d\n",inode->i_ino, block, 
 435                ((int)pnt) & 0x3ff, inode->i_size);
 436 #endif
 437         
 438         inode->i_mtime = inode->i_atime = inode->i_ctime = 
 439           iso_date(raw_inode->date, high_sierra);
 440 
 441         inode->u.isofs_i.i_first_extent = 
 442           (isonum_733 (raw_inode->extent) + 
 443            isonum_711 (raw_inode->ext_attr_length)) << 
 444                 (ISOFS_BLOCK_BITS - ISOFS_BUFFER_BITS(inode));
 445         
 446         inode->u.isofs_i.i_backlink = 0xffffffff; /* Will be used for previous directory */
 447         switch (inode->i_sb->u.isofs_sb.s_conversion){
 448         case 'a':
 449           inode->u.isofs_i.i_file_format = ISOFS_FILE_UNKNOWN; /* File type */
 450           break;
 451         case 'b':
 452           inode->u.isofs_i.i_file_format = ISOFS_FILE_BINARY; /* File type */
 453           break;
 454         case 't':
 455           inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT; /* File type */
 456           break;
 457         case 'm':
 458           inode->u.isofs_i.i_file_format = ISOFS_FILE_TEXT_M; /* File type */
 459           break;
 460         }
 461 
 462 /* Now test for possible Rock Ridge extensions which will override some of
 463    these numbers in the inode structure. */
 464 
 465         if (!high_sierra)
 466           parse_rock_ridge_inode(raw_inode, inode);
 467         
 468 #ifdef DEBUG
 469         printk("Inode: %x extent: %x\n",inode->i_ino, inode->u.isofs_i.i_first_extent);
 470 #endif
 471         brelse(bh);
 472         
 473         inode->i_op = NULL;
 474 
 475         /* A volume number of 0 is nonsense.  Disable checking if we see
 476            this */
 477         if (inode->i_sb->u.isofs_sb.s_cruft == 'n' && 
 478             isonum_723 (raw_inode->volume_sequence_number) == 0) {
 479           printk("Warning: defective cdrom.  Enabling \"cruft\" mount option.\n");
 480           inode->i_sb->u.isofs_sb.s_cruft = 'y';
 481         }
 482 
 483         if (inode->i_sb->u.isofs_sb.s_cruft != 'y' && 
 484             isonum_723 (raw_inode->volume_sequence_number) != 1) {
 485                 printk("Multi volume CD somehow got mounted.\n");
 486         } else {
 487           if (S_ISREG(inode->i_mode))
 488             inode->i_op = &isofs_file_inode_operations;
 489           else if (S_ISDIR(inode->i_mode))
 490             inode->i_op = &isofs_dir_inode_operations;
 491           else if (S_ISLNK(inode->i_mode))
 492             inode->i_op = &isofs_symlink_inode_operations;
 493           else if (S_ISCHR(inode->i_mode))
 494             inode->i_op = &chrdev_inode_operations;
 495           else if (S_ISBLK(inode->i_mode))
 496             inode->i_op = &blkdev_inode_operations;
 497           else if (S_ISFIFO(inode->i_mode))
 498             init_fifo(inode);
 499         }
 500         if (cpnt) {
 501                 kfree (cpnt);
 502                 cpnt = NULL;
 503         }
 504         return;
 505       fail:
 506         /* With a data error we return this information */
 507         inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
 508         inode->u.isofs_i.i_first_extent = 0;
 509         inode->u.isofs_i.i_backlink = 0xffffffff;
 510         inode->i_size = 0;
 511         inode->i_nlink = 1;
 512         inode->i_uid = inode->i_gid = 0;
 513         inode->i_mode = S_IFREG;  /*Regular file, no one gets to read*/
 514         inode->i_op = NULL;
 515         return;
 516 }
 517 
 518 /* There are times when we need to know the inode number of a parent of
 519    a particular directory.  When control passes through a routine that
 520    has access to the parent information, it fills it into the inode structure,
 521    but sometimes the inode gets flushed out of the queue, and someone
 522    remembers the number.  When they try to open up again, we have lost
 523    the information.  The '..' entry on the disc points to the data area
 524    for a particular inode, so we can follow these links back up, but since
 525    we do not know the inode number, we do not actually know how large the
 526    directory is.  The disc is almost always correct, and there is
 527    enough error checking on the drive itself, but an open ended search
 528    makes me a little nervous.
 529 
 530    The bsd iso filesystem uses the extent number for an inode, and this
 531    would work really nicely for us except that the read_inode function
 532    would not have any clean way of finding the actual directory record
 533    that goes with the file.  If we had such info, then it would pay
 534    to change the inode numbers and eliminate this function.
 535 */
 536 
 537 int isofs_lookup_grandparent(struct inode * parent, int extent)
     /* [previous][next][first][last][top][bottom][index][help] */
 538 {
 539         unsigned long bufsize = ISOFS_BUFFER_SIZE(parent);
 540         unsigned char bufbits = ISOFS_BUFFER_BITS(parent);
 541         unsigned int block,offset;
 542         int parent_dir, inode_number;
 543         int old_offset;
 544         void * cpnt = NULL;
 545         int result;
 546         int directory_size;
 547         struct buffer_head * bh;
 548         struct iso_directory_record * de;
 549         
 550         offset = 0;
 551         block = extent << (ISOFS_BLOCK_BITS - bufbits);
 552         if (!(bh = bread(parent->i_dev, block, bufsize)))  return -1;
 553         
 554         while (1 == 1) {
 555                 de = (struct iso_directory_record *) (bh->b_data + offset);
 556                 if (*((unsigned char *) de) == 0) 
 557                 {
 558                         brelse(bh);
 559                         return -1;
 560                 }
 561                 
 562                 offset += *((unsigned char *) de);
 563 
 564                 if (offset >= bufsize) 
 565                 {
 566                         printk(".. Directory not in first block"
 567                                " of directory.\n");
 568                         brelse(bh);
 569                         return -1;
 570                 }
 571                 
 572                 if (de->name_len[0] == 1 && de->name[0] == 1) 
 573                 {
 574                         parent_dir = find_rock_ridge_relocation(de, parent);
 575                         directory_size = isonum_733 (de->size);
 576                         brelse(bh);
 577                         break;
 578                 }
 579         }
 580 #ifdef DEBUG
 581         printk("Parent dir:%x\n",parent_dir);
 582 #endif
 583         /* Now we know the extent where the parent dir starts on. */
 584         
 585         result = -1;
 586 
 587         offset = 0;
 588         block = parent_dir << (ISOFS_BLOCK_BITS - bufbits);
 589         if (!block || !(bh = bread(parent->i_dev,block, bufsize)))
 590                 return -1;
 591         
 592         for(;;)
 593         {
 594                 de = (struct iso_directory_record *) (bh->b_data + offset);
 595                 inode_number = (block << bufbits)+(offset & (bufsize - 1));
 596                 
 597                 /* If the length byte is zero, we should move on to the next
 598                    CDROM sector.  If we are at the end of the directory, we
 599                    kick out of the while loop. */
 600                 
 601                 if (*((unsigned char *) de) == 0) 
 602                 {
 603                         brelse(bh);
 604                         offset = 0;
 605                         block++;
 606                         directory_size -= bufsize;
 607                         if(directory_size < 0) return -1;
 608                         if((block & 1) && (ISOFS_BLOCK_BITS - bufbits))
 609                           return -1;
 610                         if (!block
 611                             || !(bh = bread(parent->i_dev,block, bufsize)))
 612                                 return -1;
 613                         continue;
 614                 }
 615                 
 616                 /* Make sure that the entire directory record is in the current
 617                    bh block.  If not, we malloc a buffer, and put the two
 618                    halves together, so that we can cleanly read the block.  */
 619 
 620                 old_offset = offset;
 621                 offset += *((unsigned char *) de);
 622 
 623                 if (offset >= bufsize)
 624                 {
 625                         unsigned int frag1;
 626                         frag1 = bufsize - old_offset;
 627                         cpnt = kmalloc(*((unsigned char *) de),GFP_KERNEL);
 628                         memcpy(cpnt, bh->b_data + old_offset, frag1);
 629                         de = (struct iso_directory_record *) ((char *)cpnt);
 630                         brelse(bh);
 631                         offset -= bufsize;
 632                         directory_size -= bufsize;
 633                         if(directory_size < 0) return -1;
 634                         block++;
 635                         if(!(bh = bread(parent->i_dev,block,bufsize))) {
 636                                 kfree(cpnt);
 637                                 return -1;
 638                         };
 639                         memcpy((char *)cpnt+frag1, bh->b_data, offset);
 640                 }
 641                 
 642                 if (find_rock_ridge_relocation(de, parent) == extent){
 643                         result = inode_number;
 644                         goto out;
 645                 }
 646                 
 647                 if (cpnt) {
 648                         kfree(cpnt);
 649                         cpnt = NULL;
 650                 }
 651         }
 652 
 653         /* We go here for any condition we cannot handle.
 654            We also drop through to here at the end of the directory. */
 655 
 656  out:
 657         if (cpnt) {
 658                 kfree(cpnt);
 659                 cpnt = NULL;
 660         }
 661         brelse(bh);
 662 #ifdef DEBUG
 663         printk("Resultant Inode %d\n",result);
 664 #endif
 665         return result;
 666 }
 667     
 668 #ifdef LEAK_CHECK
 669 #undef malloc
 670 #undef free_s
 671 #undef bread
 672 #undef brelse
 673 
 674 void * leak_check_malloc(unsigned int size){
     /* [previous][next][first][last][top][bottom][index][help] */
 675   void * tmp;
 676   check_malloc++;
 677   tmp = kmalloc(size, GFP_KERNEL);
 678   return tmp;
 679 }
 680 
 681 void leak_check_free_s(void * obj, int size){
     /* [previous][next][first][last][top][bottom][index][help] */
 682   check_malloc--;
 683   return kfree_s(obj, size);
 684 }
 685 
 686 struct buffer_head * leak_check_bread(int dev, int block, int size){
     /* [previous][next][first][last][top][bottom][index][help] */
 687   check_bread++;
 688   return bread(dev, block, size);
 689 }
 690 
 691 void leak_check_brelse(struct buffer_head * bh){
     /* [previous][next][first][last][top][bottom][index][help] */
 692   check_bread--;
 693   return brelse(bh);
 694 }
 695 
 696 #endif

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