root/fs/minix/bitmap.c

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

DEFINITIONS

This source file includes following definitions.
  1. minix_free_block
  2. minix_new_block
  3. minix_free_inode
  4. minix_new_inode

   1 /*
   2  *  linux/fs/bitmap.c
   3  *
   4  *  (C) 1991  Linus Torvalds
   5  */
   6 
   7 /* bitmap.c contains the code that handles the inode and block bitmaps */
   8 #include <linux/string.h>
   9 
  10 #include <linux/sched.h>
  11 #include <linux/minix_fs.h>
  12 #include <linux/kernel.h>
  13 
  14 #define clear_block(addr) \
  15 __asm__("cld\n\t" \
  16         "rep\n\t" \
  17         "stosl" \
  18         ::"a" (0),"c" (BLOCK_SIZE/4),"D" ((long) (addr)):"cx","di")
  19 
  20 #define set_bit(nr,addr) ({\
  21 char res; \
  22 __asm__ __volatile__("btsl %1,%2\n\tsetb %0": \
  23 "=q" (res):"r" (nr),"m" (*(addr))); \
  24 res;})
  25 
  26 #define clear_bit(nr,addr) ({\
  27 char res; \
  28 __asm__ __volatile__("btrl %1,%2\n\tsetnb %0": \
  29 "=q" (res):"r" (nr),"m" (*(addr))); \
  30 res;})
  31 
  32 #define find_first_zero(addr) ({ \
  33 int __res; \
  34 __asm__("cld\n" \
  35         "1:\tlodsl\n\t" \
  36         "notl %%eax\n\t" \
  37         "bsfl %%eax,%%edx\n\t" \
  38         "jne 2f\n\t" \
  39         "addl $32,%%ecx\n\t" \
  40         "cmpl $8192,%%ecx\n\t" \
  41         "jl 1b\n\t" \
  42         "xorl %%edx,%%edx\n" \
  43         "2:\taddl %%edx,%%ecx" \
  44         :"=c" (__res):"0" (0),"S" (addr):"ax","dx","si"); \
  45 __res;})
  46 
  47 int minix_free_block(int dev, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
  48 {
  49         struct super_block * sb;
  50         struct buffer_head * bh;
  51         unsigned int bit,zone;
  52 
  53         if (!(sb = get_super(dev)))
  54                 panic("trying to free block on nonexistent device");
  55         if (block < sb->s_firstdatazone || block >= sb->s_nzones)
  56                 panic("trying to free block not in datazone");
  57         bh = get_hash_table(dev,block);
  58         if (bh) {
  59                 if (bh->b_count > 1) {
  60                         brelse(bh);
  61                         return 0;
  62                 }
  63                 bh->b_dirt=0;
  64                 bh->b_uptodate=0;
  65                 if (bh->b_count)
  66                         brelse(bh);
  67         }
  68         zone = block - sb->s_firstdatazone + 1;
  69         bit = zone & 8191;
  70         zone >>= 13;
  71         bh = sb->s_zmap[zone];
  72         if (clear_bit(bit,bh->b_data))
  73                 printk("free_block (%04x:%d): bit already cleared\n",dev,block);
  74         bh->b_dirt = 1;
  75         return 1;
  76 }
  77 
  78 int minix_new_block(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  79 {
  80         struct buffer_head * bh;
  81         struct super_block * sb;
  82         int i,j;
  83 
  84         if (!(sb = get_super(dev)))
  85                 panic("trying to get new block from nonexistant device");
  86         j = 8192;
  87         for (i=0 ; i<8 ; i++)
  88                 if (bh=sb->s_zmap[i])
  89                         if ((j=find_first_zero(bh->b_data))<8192)
  90                                 break;
  91         if (i>=8 || !bh || j>=8192)
  92                 return 0;
  93         if (set_bit(j,bh->b_data))
  94                 panic("new_block: bit already set");
  95         bh->b_dirt = 1;
  96         j += i*8192 + sb->s_firstdatazone-1;
  97         if (j >= sb->s_nzones)
  98                 return 0;
  99         if (!(bh=getblk(dev,j)))
 100                 panic("new_block: cannot get block");
 101         if (bh->b_count != 1)
 102                 panic("new block: count is != 1");
 103         clear_block(bh->b_data);
 104         bh->b_uptodate = 1;
 105         bh->b_dirt = 1;
 106         brelse(bh);
 107         return j;
 108 }
 109 
 110 void minix_free_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 111 {
 112         struct buffer_head * bh;
 113 
 114         if (!inode)
 115                 return;
 116         if (!inode->i_dev) {
 117                 memset(inode,0,sizeof(*inode));
 118                 return;
 119         }
 120         if (inode->i_count>1) {
 121                 printk("free_inode: inode has count=%d\n",inode->i_count);
 122                 return;
 123         }
 124         if (inode->i_nlink) {
 125                 printk("free_inode: inode has nlink=%d\n",inode->i_nlink);
 126                 return;
 127         }
 128         if (!inode->i_sb) {
 129                 printk("free_inode: inode on nonexistent device\n");
 130                 return;
 131         }
 132         if (inode->i_ino < 1 || inode->i_ino > inode->i_sb->s_ninodes) {
 133                 printk("free_inode: inode 0 or nonexistent inode\n");
 134                 return;
 135         }
 136         if (!(bh=inode->i_sb->s_imap[inode->i_ino>>13])) {
 137                 printk("free_inode: nonexistent imap in superblock\n");
 138                 return;
 139         }
 140         if (clear_bit(inode->i_ino&8191,bh->b_data))
 141                 printk("free_inode: bit already cleared.\n\r");
 142         bh->b_dirt = 1;
 143         memset(inode,0,sizeof(*inode));
 144 }
 145 
 146 struct inode * minix_new_inode(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 147 {
 148         struct inode * inode;
 149         struct buffer_head * bh;
 150         int i,j;
 151 
 152         if (!(inode=get_empty_inode()))
 153                 return NULL;
 154         if (!(inode->i_sb = get_super(dev))) {
 155                 printk("new_inode: unknown device\n");
 156                 iput(inode);
 157                 return NULL;
 158         }
 159         j = 8192;
 160         for (i=0 ; i<8 ; i++)
 161                 if (bh=inode->i_sb->s_imap[i])
 162                         if ((j=find_first_zero(bh->b_data))<8192)
 163                                 break;
 164         if (!bh || j >= 8192 || j+i*8192 > inode->i_sb->s_ninodes) {
 165                 iput(inode);
 166                 return NULL;
 167         }
 168         if (set_bit(j,bh->b_data)) {    /* shouldn't happen */
 169                 printk("new_inode: bit already set");
 170                 iput(inode);
 171                 return NULL;
 172         }
 173         bh->b_dirt = 1;
 174         inode->i_count = 1;
 175         inode->i_nlink = 1;
 176         inode->i_dev = dev;
 177         inode->i_uid = current->euid;
 178         inode->i_gid = current->egid;
 179         inode->i_dirt = 1;
 180         inode->i_ino = j + i*8192;
 181         inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
 182         inode->i_op = NULL;
 183         return inode;
 184 }

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