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

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