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

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