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 /*
   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 sync_inodes(void)
     /* [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_dirt && !inode->i_pipe)
  52                         write_inode(inode);
  53         }
  54 }
  55 
  56 static int _bmap(struct m_inode * inode,int block,int create)
     /* [previous][next][first][last][top][bottom][index][help] */
  57 {
  58         struct buffer_head * bh;
  59         int i;
  60 
  61         if (block<0)
  62                 panic("_bmap: block<0");
  63         if (block >= 7+512+512*512)
  64                 panic("_bmap: block>big");
  65         if (block<7) {
  66                 if (create && !inode->i_zone[block])
  67                         if (inode->i_zone[block]=new_block(inode->i_dev)) {
  68                                 inode->i_ctime=CURRENT_TIME;
  69                                 inode->i_dirt=1;
  70                         }
  71                 return inode->i_zone[block];
  72         }
  73         block -= 7;
  74         if (block<512) {
  75                 if (create && !inode->i_zone[7])
  76                         if (inode->i_zone[7]=new_block(inode->i_dev)) {
  77                                 inode->i_dirt=1;
  78                                 inode->i_ctime=CURRENT_TIME;
  79                         }
  80                 if (!inode->i_zone[7])
  81                         return 0;
  82                 if (!(bh = bread(inode->i_dev,inode->i_zone[7])))
  83                         return 0;
  84                 i = ((unsigned short *) (bh->b_data))[block];
  85                 if (create && !i)
  86                         if (i=new_block(inode->i_dev)) {
  87                                 ((unsigned short *) (bh->b_data))[block]=i;
  88                                 bh->b_dirt=1;
  89                         }
  90                 brelse(bh);
  91                 return i;
  92         }
  93         block -= 512;
  94         if (create && !inode->i_zone[8])
  95                 if (inode->i_zone[8]=new_block(inode->i_dev)) {
  96                         inode->i_dirt=1;
  97                         inode->i_ctime=CURRENT_TIME;
  98                 }
  99         if (!inode->i_zone[8])
 100                 return 0;
 101         if (!(bh=bread(inode->i_dev,inode->i_zone[8])))
 102                 return 0;
 103         i = ((unsigned short *)bh->b_data)[block>>9];
 104         if (create && !i)
 105                 if (i=new_block(inode->i_dev)) {
 106                         ((unsigned short *) (bh->b_data))[block>>9]=i;
 107                         bh->b_dirt=1;
 108                 }
 109         brelse(bh);
 110         if (!i)
 111                 return 0;
 112         if (!(bh=bread(inode->i_dev,i)))
 113                 return 0;
 114         i = ((unsigned short *)bh->b_data)[block&511];
 115         if (create && !i)
 116                 if (i=new_block(inode->i_dev)) {
 117                         ((unsigned short *) (bh->b_data))[block&511]=i;
 118                         bh->b_dirt=1;
 119                 }
 120         brelse(bh);
 121         return i;
 122 }
 123 
 124 int bmap(struct m_inode * inode,int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 125 {
 126         return _bmap(inode,block,0);
 127 }
 128 
 129 int create_block(struct m_inode * inode, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 130 {
 131         return _bmap(inode,block,1);
 132 }
 133                 
 134 void iput(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 135 {
 136         if (!inode)
 137                 return;
 138         wait_on_inode(inode);
 139         if (!inode->i_count)
 140                 panic("iput: trying to free free inode");
 141         if (inode->i_pipe) {
 142                 wake_up(&inode->i_wait);
 143                 if (--inode->i_count)
 144                         return;
 145                 free_page(inode->i_size);
 146                 inode->i_count=0;
 147                 inode->i_dirt=0;
 148                 inode->i_pipe=0;
 149                 return;
 150         }
 151         if (!inode->i_dev || inode->i_count>1) {
 152                 inode->i_count--;
 153                 return;
 154         }
 155 repeat:
 156         if (S_ISBLK(inode->i_mode)) {
 157                 sync_dev(inode->i_zone[0]);
 158                 wait_on_inode(inode);
 159         }
 160         if (!inode->i_nlinks) {
 161                 truncate(inode);
 162                 free_inode(inode);
 163                 return;
 164         }
 165         if (inode->i_dirt) {
 166                 write_inode(inode);     /* we can sleep - so do again */
 167                 wait_on_inode(inode);
 168                 goto repeat;
 169         }
 170         inode->i_count--;
 171         return;
 172 }
 173 
 174 static volatile int last_allocated_inode = 0;
 175 
 176 struct m_inode * get_empty_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178         struct m_inode * inode;
 179         int inr;
 180 
 181         while (1) {
 182                 inode = NULL;
 183                 inr = last_allocated_inode;
 184                 do {
 185                         if (!inode_table[inr].i_count) {
 186                                 inode = inr + inode_table;
 187                                 break;
 188                         }
 189                         inr++;
 190                         if (inr>=NR_INODE)
 191                                 inr=0;
 192                 } while (inr != last_allocated_inode);
 193                 if (!inode) {
 194                         for (inr=0 ; inr<NR_INODE ; inr++)
 195                                 printk("%04x: %6d\t",inode_table[inr].i_dev,
 196                                         inode_table[inr].i_num);
 197                         panic("No free inodes in mem");
 198                 }
 199                 last_allocated_inode = inr;
 200                 wait_on_inode(inode);
 201                 while (inode->i_dirt) {
 202                         write_inode(inode);
 203                         wait_on_inode(inode);
 204                 }
 205                 if (!inode->i_count)
 206                         break;
 207         }
 208         memset(inode,0,sizeof(*inode));
 209         inode->i_count = 1;
 210         return inode;
 211 }
 212 
 213 struct m_inode * get_pipe_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 214 {
 215         struct m_inode * inode;
 216 
 217         if (!(inode = get_empty_inode()))
 218                 return NULL;
 219         if (!(inode->i_size=get_free_page())) {
 220                 inode->i_count = 0;
 221                 return NULL;
 222         }
 223         inode->i_count = 2;     /* sum of readers/writers */
 224         PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
 225         inode->i_pipe = 1;
 226         return inode;
 227 }
 228 
 229 struct m_inode * iget(int dev,int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 230 {
 231         struct m_inode * inode, * empty;
 232 
 233         if (!dev)
 234                 panic("iget with dev==0");
 235         empty = get_empty_inode();
 236         inode = inode_table;
 237         while (inode < NR_INODE+inode_table) {
 238                 if (inode->i_dev != dev || inode->i_num != nr) {
 239                         inode++;
 240                         continue;
 241                 }
 242                 wait_on_inode(inode);
 243                 if (inode->i_dev != dev || inode->i_num != nr) {
 244                         inode = inode_table;
 245                         continue;
 246                 }
 247                 inode->i_count++;
 248                 if (inode->i_mount) {
 249                         int i;
 250 
 251                         for (i = 0 ; i<NR_SUPER ; i++)
 252                                 if (super_block[i].s_imount==inode)
 253                                         break;
 254                         if (i >= NR_SUPER) {
 255                                 printk("Mounted inode hasn't got sb\n");
 256                                 if (empty)
 257                                         iput(empty);
 258                                 return inode;
 259                         }
 260                         iput(inode);
 261                         dev = super_block[i].s_dev;
 262                         nr = ROOT_INO;
 263                         inode = inode_table;
 264                         continue;
 265                 }
 266                 if (empty)
 267                         iput(empty);
 268                 return inode;
 269         }
 270         if (!empty)
 271                 return (NULL);
 272         inode=empty;
 273         inode->i_dev = dev;
 274         inode->i_num = nr;
 275         read_inode(inode);
 276         return inode;
 277 }
 278 
 279 static void read_inode(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 280 {
 281         struct super_block * sb;
 282         struct buffer_head * bh;
 283         int block;
 284 
 285         lock_inode(inode);
 286         sb=get_super(inode->i_dev);
 287         block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
 288                 (inode->i_num-1)/INODES_PER_BLOCK;
 289         if (!(bh=bread(inode->i_dev,block)))
 290                 panic("unable to read i-node block");
 291         *(struct d_inode *)inode =
 292                 ((struct d_inode *)bh->b_data)
 293                         [(inode->i_num-1)%INODES_PER_BLOCK];
 294         brelse(bh);
 295         unlock_inode(inode);
 296 }
 297 
 298 static void write_inode(struct m_inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 299 {
 300         struct super_block * sb;
 301         struct buffer_head * bh;
 302         int block;
 303 
 304         lock_inode(inode);
 305         sb=get_super(inode->i_dev);
 306         block = 2 + sb->s_imap_blocks + sb->s_zmap_blocks +
 307                 (inode->i_num-1)/INODES_PER_BLOCK;
 308         if (!(bh=bread(inode->i_dev,block)))
 309                 panic("unable to read i-node block");
 310         ((struct d_inode *)bh->b_data)
 311                 [(inode->i_num-1)%INODES_PER_BLOCK] =
 312                         *(struct d_inode *)inode;
 313         bh->b_dirt=1;
 314         inode->i_dirt=0;
 315         brelse(bh);
 316         unlock_inode(inode);
 317 }

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