root/fs/inode.c

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

DEFINITIONS

This source file includes following definitions.
  1. wait_on_inode
  2. lock_inode
  3. unlock_inode
  4. sync_inodes
  5. _bmap
  6. bmap
  7. create_block
  8. iput
  9. get_empty_inode
  10. get_pipe_inode
  11. iget
  12. read_inode
  13. write_inode

   1 #include <string.h>
   2 
   3 #include <linux/sched.h>
   4 #include <linux/kernel.h>
   5 #include <linux/mm.h>
   6 #include <asm/system.h>
   7 
   8 struct m_inode inode_table[NR_INODE]={{0,},};
   9 
  10 static void read_inode(struct m_inode * inode);
  11 static void write_inode(struct m_inode * inode);
  12 
  13 static inline void wait_on_inode(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  14 {
  15         cli();
  16         while (inode->i_lock)
  17                 sleep_on(&inode->i_wait);
  18         sti();
  19 }
  20 
  21 static inline void lock_inode(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  22 {
  23         cli();
  24         while (inode->i_lock)
  25                 sleep_on(&inode->i_wait);
  26         inode->i_lock=1;
  27         sti();
  28 }
  29 
  30 static inline void unlock_inode(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  31 {
  32         inode->i_lock=0;
  33         wake_up(&inode->i_wait);
  34 }
  35 
  36 void sync_inodes(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  37 {
  38         int i;
  39         struct m_inode * inode;
  40 
  41         inode = 0+inode_table;
  42         for(i=0 ; i<NR_INODE ; i++,inode++) {
  43                 wait_on_inode(inode);
  44                 if (inode->i_dirt && !inode->i_pipe)
  45                         write_inode(inode);
  46         }
  47 }
  48 
  49 static int _bmap(struct m_inode * inode,int block,int create)
     /* [previous][next][first][last][top][bottom][index][help] */
  50 {
  51         struct buffer_head * bh;
  52         int i;
  53 
  54         if (block<0)
  55                 panic("_bmap: block<0");
  56         if (block >= 7+512+512*512)
  57                 panic("_bmap: block>big");
  58         if (block<7) {
  59                 if (create && !inode->i_zone[block])
  60                         if (inode->i_zone[block]=new_block(inode->i_dev)) {
  61                                 inode->i_ctime=CURRENT_TIME;
  62                                 inode->i_dirt=1;
  63                         }
  64                 return inode->i_zone[block];
  65         }
  66         block -= 7;
  67         if (block<512) {
  68                 if (create && !inode->i_zone[7])
  69                         if (inode->i_zone[7]=new_block(inode->i_dev)) {
  70                                 inode->i_dirt=1;
  71                                 inode->i_ctime=CURRENT_TIME;
  72                         }
  73                 if (!inode->i_zone[7])
  74                         return 0;
  75                 if (!(bh = bread(inode->i_dev,inode->i_zone[7])))
  76                         return 0;
  77                 i = ((unsigned short *) (bh->b_data))[block];
  78                 if (create && !i)
  79                         if (i=new_block(inode->i_dev)) {
  80                                 ((unsigned short *) (bh->b_data))[block]=i;
  81                                 bh->b_dirt=1;
  82                         }
  83                 brelse(bh);
  84                 return i;
  85         }
  86         block -= 512;
  87         if (create && !inode->i_zone[8])
  88                 if (inode->i_zone[8]=new_block(inode->i_dev)) {
  89                         inode->i_dirt=1;
  90                         inode->i_ctime=CURRENT_TIME;
  91                 }
  92         if (!inode->i_zone[8])
  93                 return 0;
  94         if (!(bh=bread(inode->i_dev,inode->i_zone[8])))
  95                 return 0;
  96         i = ((unsigned short *)bh->b_data)[block>>9];
  97         if (create && !i)
  98                 if (i=new_block(inode->i_dev)) {
  99                         ((unsigned short *) (bh->b_data))[block>>9]=i;
 100                         bh->b_dirt=1;
 101                 }
 102         brelse(bh);
 103         if (!i)
 104                 return 0;
 105         if (!(bh=bread(inode->i_dev,i)))
 106                 return 0;
 107         i = ((unsigned short *)bh->b_data)[block&511];
 108         if (create && !i)
 109                 if (i=new_block(inode->i_dev)) {
 110                         ((unsigned short *) (bh->b_data))[block&511]=i;
 111                         bh->b_dirt=1;
 112                 }
 113         brelse(bh);
 114         return i;
 115 }
 116 
 117 int bmap(struct m_inode * inode,int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 118 {
 119         return _bmap(inode,block,0);
 120 }
 121 
 122 int create_block(struct m_inode * inode, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 123 {
 124         return _bmap(inode,block,1);
 125 }
 126                 
 127 void iput(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 128 {
 129         if (!inode)
 130                 return;
 131         wait_on_inode(inode);
 132         if (!inode->i_count)
 133                 panic("iput: trying to free free inode");
 134         if (inode->i_pipe) {
 135                 wake_up(&inode->i_wait);
 136                 if (--inode->i_count)
 137                         return;
 138                 free_page(inode->i_size);
 139                 inode->i_count=0;
 140                 inode->i_dirt=0;
 141                 inode->i_pipe=0;
 142                 return;
 143         }
 144         if (!inode->i_dev || inode->i_count>1) {
 145                 inode->i_count--;
 146                 return;
 147         }
 148 repeat:
 149         if (!inode->i_nlinks) {
 150                 truncate(inode);
 151                 free_inode(inode);
 152                 return;
 153         }
 154         if (inode->i_dirt) {
 155                 write_inode(inode);     /* we can sleep - so do again */
 156                 wait_on_inode(inode);
 157                 goto repeat;
 158         }
 159         inode->i_count--;
 160         return;
 161 }
 162 
 163 static volatile int last_allocated_inode = 0;
 164 
 165 struct m_inode * get_empty_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 166 {
 167         struct m_inode * inode;
 168         int inr;
 169 
 170         while (1) {
 171                 inode = NULL;
 172                 inr = last_allocated_inode;
 173                 do {
 174                         if (!inode_table[inr].i_count) {
 175                                 inode = inr + inode_table;
 176                                 break;
 177                         }
 178                         inr++;
 179                         if (inr>=NR_INODE)
 180                                 inr=0;
 181                 } while (inr != last_allocated_inode);
 182                 if (!inode) {
 183                         for (inr=0 ; inr<NR_INODE ; inr++)
 184                                 printk("%04x: %6d\t",inode_table[inr].i_dev,
 185                                         inode_table[inr].i_num);
 186                         panic("No free inodes in mem");
 187                 }
 188                 last_allocated_inode = inr;
 189                 wait_on_inode(inode);
 190                 while (inode->i_dirt) {
 191                         write_inode(inode);
 192                         wait_on_inode(inode);
 193                 }
 194                 if (!inode->i_count)
 195                         break;
 196         }
 197         memset(inode,0,sizeof(*inode));
 198         inode->i_count = 1;
 199         return inode;
 200 }
 201 
 202 struct m_inode * get_pipe_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 203 {
 204         struct m_inode * inode;
 205 
 206         if (!(inode = get_empty_inode()))
 207                 return NULL;
 208         if (!(inode->i_size=get_free_page())) {
 209                 inode->i_count = 0;
 210                 return NULL;
 211         }
 212         inode->i_count = 2;     /* sum of readers/writers */
 213         PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
 214         inode->i_pipe = 1;
 215         return inode;
 216 }
 217 
 218 struct m_inode * iget(int dev,int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 219 {
 220         struct m_inode * inode, * empty;
 221 
 222         if (!dev)
 223                 panic("iget with dev==0");
 224         empty = get_empty_inode();
 225         inode = inode_table;
 226         while (inode < NR_INODE+inode_table) {
 227                 if (inode->i_dev != dev || inode->i_num != nr) {
 228                         inode++;
 229                         continue;
 230                 }
 231                 wait_on_inode(inode);
 232                 if (inode->i_dev != dev || inode->i_num != nr) {
 233                         inode = inode_table;
 234                         continue;
 235                 }
 236                 inode->i_count++;
 237                 if (empty)
 238                         iput(empty);
 239                 return inode;
 240         }
 241         if (!empty)
 242                 return (NULL);
 243         inode=empty;
 244         inode->i_dev = dev;
 245         inode->i_num = nr;
 246         read_inode(inode);
 247         return inode;
 248 }
 249 
 250 static void read_inode(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 251 {
 252         struct super_block * sb;
 253         struct buffer_head * bh;
 254         int block;
 255 
 256         lock_inode(inode);
 257         sb=get_super(inode->i_dev);
 258         block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
 259                 (inode->i_num-1)/INODES_PER_BLOCK;
 260         if (!(bh=bread(inode->i_dev,block)))
 261                 panic("unable to read i-node block");
 262         *(struct d_inode *)inode =
 263                 ((struct d_inode *)bh->b_data)
 264                         [(inode->i_num-1)%INODES_PER_BLOCK];
 265         brelse(bh);
 266         unlock_inode(inode);
 267 }
 268 
 269 static void write_inode(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 270 {
 271         struct super_block * sb;
 272         struct buffer_head * bh;
 273         int block;
 274 
 275         lock_inode(inode);
 276         sb=get_super(inode->i_dev);
 277         block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
 278                 (inode->i_num-1)/INODES_PER_BLOCK;
 279         if (!(bh=bread(inode->i_dev,block)))
 280                 panic("unable to read i-node block");
 281         ((struct d_inode *)bh->b_data)
 282                 [(inode->i_num-1)%INODES_PER_BLOCK] =
 283                         *(struct d_inode *)inode;
 284         bh->b_dirt=1;
 285         inode->i_dirt=0;
 286         brelse(bh);
 287         unlock_inode(inode);
 288 }

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