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 
 481         /* A volume number of 0 is nonsense.  Disable checking if we see
 482            this */
 483         if (inode->i_sb->u.isofs_sb.s_cruft == 'n' && 
 484             isonum_723 (raw_inode->volume_sequence_number) == 0) {
 485           printk("Warning: defective cdrom.  Enabling \"cruft\" mount option.\n");
 486           inode->i_sb->u.isofs_sb.s_cruft = 'y';
 487         }
 488 
 489         if (inode->i_sb->u.isofs_sb.s_cruft != 'y' && 
 490             isonum_723 (raw_inode->volume_sequence_number) != 1) {
 491                 printk("Multi volume CD somehow got mounted.\n");
 492         } else {
 493           if (S_ISREG(inode->i_mode))
 494             inode->i_op = &isofs_file_inode_operations;
 495           else if (S_ISDIR(inode->i_mode))
 496             inode->i_op = &isofs_dir_inode_operations;
 497           else if (S_ISLNK(inode->i_mode))
 498             inode->i_op = &isofs_symlink_inode_operations;
 499           else if (S_ISCHR(inode->i_mode))
 500             inode->i_op = &chrdev_inode_operations;
 501           else if (S_ISBLK(inode->i_mode))
 502             inode->i_op = &blkdev_inode_operations;
 503           else if (S_ISFIFO(inode->i_mode))
 504             init_fifo(inode);
 505         }
 506         if (cpnt) {
 507                 kfree_s (cpnt, 1 << ISOFS_BLOCK_BITS);
 508                 cpnt = NULL;
 509         }
 510         return;
 511       fail:
 512         /* With a data error we return this information */
 513         inode->i_mtime = inode->i_atime = inode->i_ctime = 0;
 514         inode->u.isofs_i.i_first_extent = 0;
 515         inode->u.isofs_i.i_backlink = 0xffffffff;
 516         inode->i_size = 0;
 517         inode->i_nlink = 1;
 518         inode->i_uid = inode->i_gid = 0;
 519         inode->i_mode = S_IFREG;  /*Regular file, noone gets to read*/
 520         inode->i_op = NULL;
 521         return;
 522 }
 523 
 524 /* There are times when we need to know the inode number of a parent of
 525    a particular directory.  When control passes through a routine that
 526    has access to the parent information, it fills it into the inode structure,
 527    but sometimes the inode gets flushed out of the queue, and someone
 528    remmembers the number.  When they try to open up again, we have lost
 529    the information.  The '..' entry on the disc points to the data area
 530    for a particular inode, so we can follow these links back up, but since
 531    we do not know the inode number, we do not actually know how large the
 532    directory is.  The disc is almost always correct, and there is
 533    enough error checking on the drive itself, but an open ended search
 534    makes me a little nervous.
 535 
 536    The bsd iso filesystem uses the extent number for an inode, and this
 537    would work really nicely for us except that the read_inode function
 538    would not have any clean way of finding the actual directory record
 539    that goes with the file.  If we had such info, then it would pay
 540    to change the inode numbers and eliminate this function.
 541 */
 542 
 543 int isofs_lookup_grandparent(struct inode * parent, int extent)
     /* [previous][next][first][last][top][bottom][index][help] */
 544 {
 545         unsigned long bufsize = ISOFS_BUFFER_SIZE(parent);
 546         unsigned char bufbits = ISOFS_BUFFER_BITS(parent);
 547         unsigned int block,offset;
 548         int parent_dir, inode_number;
 549         int old_offset;
 550         void * cpnt = NULL;
 551         int result;
 552         struct buffer_head * bh;
 553         struct iso_directory_record * de;
 554         
 555         offset = 0;
 556         block = extent << (ISOFS_BLOCK_BITS - bufbits);
 557         if (!(bh = bread(parent->i_dev, block, bufsize)))  return -1;
 558         
 559         while (1 == 1) {
 560                 de = (struct iso_directory_record *) (bh->b_data + offset);
 561                 if (*((unsigned char *) de) == 0) 
 562                 {
 563                         brelse(bh);
 564                         return -1;
 565                 }
 566                 
 567                 offset += *((unsigned char *) de);
 568 
 569                 if (offset >= bufsize) 
 570                 {
 571                         printk(".. Directory not in first block"
 572                                " of directory.\n");
 573                         brelse(bh);
 574                         return -1;
 575                 }
 576                 
 577                 if (de->name_len[0] == 1 && de->name[0] == 1) 
 578                 {
 579                         parent_dir = find_rock_ridge_relocation(de, parent);
 580                         brelse(bh);
 581                         break;
 582                 }
 583         }
 584 #ifdef DEBUG
 585         printk("Parent dir:%x\n",parent_dir);
 586 #endif
 587         /* Now we know the extent where the parent dir starts on.  We have no
 588            idea how long it is, so we just start reading until we either find
 589            it or we find some kind of unreasonable circumstance. */
 590         
 591         result = -1;
 592 
 593         offset = 0;
 594         block = parent_dir << (ISOFS_BLOCK_BITS - bufbits);
 595         if (!block || !(bh = bread(parent->i_dev,block, bufsize)))
 596                 return -1;
 597         
 598         for(;;)
 599         {
 600                 de = (struct iso_directory_record *) (bh->b_data + offset);
 601                 inode_number = (block << bufbits)+(offset & (bufsize - 1));
 602                 
 603                 /* If the length byte is zero, we should move on to the next
 604                    CDROM sector.  If we are at the end of the directory, we
 605                    kick out of the while loop. */
 606                 
 607                 if (*((unsigned char *) de) == 0) 
 608                 {
 609                         brelse(bh);
 610                         offset = 0;
 611                         block++;
 612                         if((block & 1) && (ISOFS_BLOCK_BITS - bufbits))
 613                           return -1;
 614                         if (!block
 615                             || !(bh = bread(parent->i_dev,block, bufsize)))
 616                                 return -1;
 617                         continue;
 618                 }
 619                 
 620                 /* Make sure that the entire directory record is in the current
 621                    bh block.  If not, we malloc a buffer, and put the two
 622                    halves together, so that we can cleanly read the block.  */
 623 
 624                 old_offset = offset;
 625                 offset += *((unsigned char *) de);
 626 
 627                 if (offset >= bufsize)
 628                 {
 629                         if((block & 1) != 0) return -1;
 630                         cpnt = kmalloc(1<<ISOFS_BLOCK_BITS,GFP_KERNEL);
 631                         memcpy(cpnt, bh->b_data, bufsize);
 632                         de = (struct iso_directory_record *)
 633                                 ((char *)cpnt + old_offset);
 634                         brelse(bh);
 635                         offset -= bufsize;
 636                         block++;
 637                         if (!(bh = bread(parent->i_dev,block,bufsize))) {
 638                                 kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
 639                                 return -1;
 640                         };
 641                         memcpy((char *)cpnt+bufsize, bh->b_data, bufsize);
 642                 }
 643                 
 644                 if (find_rock_ridge_relocation(de, parent) == extent){
 645                         result = inode_number;
 646                         goto out;
 647                 }
 648                 
 649                 if (cpnt) {
 650                         kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
 651                         cpnt = NULL;
 652                 }
 653         }
 654 
 655         /* We go here for any condition we cannot handle.
 656            We also drop through to here at the end of the directory. */
 657 
 658  out:
 659         if (cpnt) {
 660                 kfree_s(cpnt, 1 << ISOFS_BLOCK_BITS);
 661                 cpnt = NULL;
 662         }
 663         brelse(bh);
 664 #ifdef DEBUG
 665         printk("Resultant Inode %d\n",result);
 666 #endif
 667         return result;
 668 }
 669     
 670 #ifdef LEAK_CHECK
 671 #undef malloc
 672 #undef free_s
 673 #undef bread
 674 #undef brelse
 675 
 676 void * leak_check_malloc(unsigned int size){
     /* [previous][next][first][last][top][bottom][index][help] */
 677   void * tmp;
 678   check_malloc++;
 679   tmp = kmalloc(size, GFP_KERNEL);
 680   return tmp;
 681 }
 682 
 683 void leak_check_free_s(void * obj, int size){
     /* [previous][next][first][last][top][bottom][index][help] */
 684   check_malloc--;
 685   return kfree_s(obj, size);
 686 }
 687 
 688 struct buffer_head * leak_check_bread(int dev, int block, int size){
     /* [previous][next][first][last][top][bottom][index][help] */
 689   check_bread++;
 690   return bread(dev, block, size);
 691 }
 692 
 693 void leak_check_brelse(struct buffer_head * bh){
     /* [previous][next][first][last][top][bottom][index][help] */
 694   check_bread--;
 695   return brelse(bh);
 696 }
 697 
 698 #endif

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