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

   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/minix_fs.h>
  12 #include <linux/kernel.h>
  13 #include <linux/mm.h>
  14 #include <asm/system.h>
  15 
  16 struct inode inode_table[NR_INODE]={{0,},};
  17 
  18 extern void minix_read_inode(struct inode * inode);
  19 extern void minix_write_inode(struct inode * inode);
  20 
  21 static inline void wait_on_inode(struct 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         sti();
  27 }
  28 
  29 static inline void lock_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  30 {
  31         cli();
  32         while (inode->i_lock)
  33                 sleep_on(&inode->i_wait);
  34         inode->i_lock=1;
  35         sti();
  36 }
  37 
  38 static inline void unlock_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  39 {
  40         inode->i_lock=0;
  41         wake_up(&inode->i_wait);
  42 }
  43 
  44 static void write_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  45 {
  46         lock_inode(inode);
  47         if (!inode->i_dirt || !inode->i_dev) {
  48                 unlock_inode(inode);
  49                 return;
  50         }
  51         minix_write_inode(inode);
  52         unlock_inode(inode);
  53 }
  54 
  55 static void read_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57         lock_inode(inode);
  58         minix_read_inode(inode);
  59         unlock_inode(inode);
  60 }
  61 
  62 int bmap(struct inode * inode, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
  63 {
  64         return minix_bmap(inode,block);
  65 }
  66 
  67 void invalidate_inodes(int dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  68 {
  69         int i;
  70         struct inode * inode;
  71 
  72         inode = 0+inode_table;
  73         for(i=0 ; i<NR_INODE ; i++,inode++) {
  74                 wait_on_inode(inode);
  75                 if (inode->i_dev == dev) {
  76                         if (inode->i_count) {
  77                                 printk("inode in use on removed disk\n\r");
  78                                 continue;
  79                         }
  80                         inode->i_dev = inode->i_dirt = 0;
  81                 }
  82         }
  83 }
  84 
  85 void sync_inodes(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  86 {
  87         int i;
  88         struct inode * inode;
  89 
  90         inode = 0+inode_table;
  91         for(i=0 ; i<NR_INODE ; i++,inode++) {
  92                 wait_on_inode(inode);
  93                 if (inode->i_dirt && !inode->i_pipe)
  94                         write_inode(inode);
  95         }
  96 }
  97 
  98 void iput(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  99 {
 100         if (!inode)
 101                 return;
 102         wait_on_inode(inode);
 103         if (!inode->i_count)
 104                 panic("iput: trying to free free inode");
 105         if (inode->i_pipe) {
 106                 wake_up(&inode->i_wait);
 107                 wake_up(&inode->i_wait2);
 108                 if (--inode->i_count)
 109                         return;
 110                 free_page(inode->i_size);
 111                 inode->i_count=0;
 112                 inode->i_dirt=0;
 113                 inode->i_pipe=0;
 114                 return;
 115         }
 116         if (!inode->i_dev) {
 117                 inode->i_count--;
 118                 return;
 119         }
 120         if (S_ISBLK(inode->i_mode)) {
 121                 sync_dev(inode->i_rdev);
 122                 wait_on_inode(inode);
 123         }
 124 repeat:
 125         if (inode->i_count>1) {
 126                 inode->i_count--;
 127                 return;
 128         }
 129         if (!inode->i_nlink) {
 130                 minix_truncate(inode);
 131                 minix_free_inode(inode);
 132                 return;
 133         }
 134         if (inode->i_dirt) {
 135                 write_inode(inode);     /* we can sleep - so do again */
 136                 wait_on_inode(inode);
 137                 goto repeat;
 138         }
 139         inode->i_count--;
 140         return;
 141 }
 142 
 143 struct inode * get_empty_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 144 {
 145         struct inode * inode;
 146         static struct inode * last_inode = inode_table;
 147         int i;
 148 
 149         do {
 150                 inode = NULL;
 151                 for (i = NR_INODE; i ; i--) {
 152                         if (++last_inode >= inode_table + NR_INODE)
 153                                 last_inode = inode_table;
 154                         if (!last_inode->i_count) {
 155                                 inode = last_inode;
 156                                 if (!inode->i_dirt && !inode->i_lock)
 157                                         break;
 158                         }
 159                 }
 160                 if (!inode) {
 161                         for (i=0 ; i<NR_INODE ; i++)
 162                                 printk("(%04x: %d (%o)) ",inode_table[i].i_dev,
 163                                         inode_table[i].i_ino,inode_table[i].i_mode);
 164                         panic("No free inodes in mem");
 165                 }
 166                 wait_on_inode(inode);
 167                 while (inode->i_dirt) {
 168                         write_inode(inode);
 169                         wait_on_inode(inode);
 170                 }
 171         } while (inode->i_count);
 172         memset(inode,0,sizeof(*inode));
 173         inode->i_count = 1;
 174         return inode;
 175 }
 176 
 177 struct inode * get_pipe_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 178 {
 179         struct inode * inode;
 180 
 181         if (!(inode = get_empty_inode()))
 182                 return NULL;
 183         if (!(inode->i_size=get_free_page())) {
 184                 inode->i_count = 0;
 185                 return NULL;
 186         }
 187         inode->i_count = 2;     /* sum of readers/writers */
 188         PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
 189         inode->i_pipe = 1;
 190         return inode;
 191 }
 192 
 193 struct inode * iget(int dev,int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 194 {
 195         struct inode * inode, * empty;
 196 
 197         if (!dev)
 198                 panic("iget with dev==0");
 199         empty = get_empty_inode();
 200         inode = inode_table;
 201         while (inode < NR_INODE+inode_table) {
 202                 if (inode->i_dev != dev || inode->i_ino != nr) {
 203                         inode++;
 204                         continue;
 205                 }
 206                 wait_on_inode(inode);
 207                 if (inode->i_dev != dev || inode->i_ino != nr) {
 208                         inode = inode_table;
 209                         continue;
 210                 }
 211                 inode->i_count++;
 212                 if (inode->i_mount) {
 213                         int i;
 214 
 215                         for (i = 0 ; i<NR_SUPER ; i++)
 216                                 if (super_block[i].s_covered==inode)
 217                                         break;
 218                         if (i >= NR_SUPER) {
 219                                 printk("Mounted inode hasn't got sb\n");
 220                                 if (empty)
 221                                         iput(empty);
 222                                 return inode;
 223                         }
 224                         iput(inode);
 225                         if (!(inode = super_block[i].s_mounted))
 226                                 printk("iget: mounted dev has no rootinode\n");
 227                         else {
 228                                 inode->i_count++;
 229                                 wait_on_inode(inode);
 230                         }
 231                 }
 232                 if (empty)
 233                         iput(empty);
 234                 return inode;
 235         }
 236         if (!empty)
 237                 return (NULL);
 238         inode = empty;
 239         if (!(inode->i_sb = get_super(dev))) {
 240                 printk("iget: gouldn't get super-block\n\t");
 241                 iput(inode);
 242                 return NULL;
 243         }
 244         inode->i_dev = dev;
 245         inode->i_ino = nr;
 246         read_inode(inode);
 247         return inode;
 248 }

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