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

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