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. invalidate_inodes
  5. sync_inodes
  6. _bmap
  7. bmap
  8. create_block
  9. iput
  10. get_empty_inode
  11. get_pipe_inode
  12. iget
  13. read_inode
  14. write_inode

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

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