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

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