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

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