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

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