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  *  Copyright (C) 1991, 1992  Linus Torvalds
   5  */
   6 
   7 #include <linux/stat.h>
   8 #include <linux/sched.h>
   9 #include <linux/kernel.h>
  10 #include <linux/mm.h>
  11 #include <linux/string.h>
  12 
  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         if (!inode->i_dirt)
  43                 return;
  44         inode->i_dirt = 0;
  45         lock_inode(inode);
  46         if (inode->i_dev && inode->i_sb &&
  47             inode->i_sb->s_op && inode->i_sb->s_op->write_inode)
  48                 inode->i_sb->s_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)
 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                 printk("iput: trying to free free inode\n");
 115                 printk("device %04x, inode %d, mode=%07o\n",inode->i_rdev,
 116                         inode->i_ino,inode->i_mode);
 117                 return;
 118         }
 119         if (inode->i_pipe) {
 120                 wake_up(&PIPE_READ_WAIT(*inode));
 121                 wake_up(&PIPE_WRITE_WAIT(*inode));
 122         }
 123 repeat:
 124         if (inode->i_count>1) {
 125                 inode->i_count--;
 126                 return;
 127         }
 128         if (inode->i_pipe) {
 129                 unsigned long page = (unsigned long) PIPE_BASE(*inode);
 130                 PIPE_BASE(*inode) = NULL;
 131                 free_page(page);
 132         }
 133         if (!inode->i_dev) {
 134                 inode->i_count--;
 135                 return;
 136         }
 137         if (!inode->i_nlink) {
 138                 if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
 139                         inode->i_sb->s_op->put_inode(inode);
 140                         return;
 141                 }
 142         }
 143         if (inode->i_dirt) {
 144                 write_inode(inode);     /* we can sleep - so do again */
 145                 wait_on_inode(inode);
 146                 goto repeat;
 147         }
 148         inode->i_count--;
 149         return;
 150 }
 151 
 152 struct inode * get_empty_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 153 {
 154         struct inode * inode;
 155         static struct inode * last_inode = inode_table;
 156         int i;
 157 
 158         do {
 159                 inode = NULL;
 160                 for (i = NR_INODE; i ; i--) {
 161                         if (++last_inode >= inode_table + NR_INODE)
 162                                 last_inode = inode_table;
 163                         if (!last_inode->i_count) {
 164                                 inode = last_inode;
 165                                 if (!inode->i_dirt && !inode->i_lock)
 166                                         break;
 167                         }
 168                 }
 169                 if (!inode) {
 170                         for (i=0 ; i<NR_INODE ; i++)
 171                                 printk("(%04x: %d (%o)) ",inode_table[i].i_dev,
 172                                         inode_table[i].i_ino,inode_table[i].i_mode);
 173                         panic("No free inodes in mem");
 174                 }
 175                 wait_on_inode(inode);
 176                 while (inode->i_dirt) {
 177                         write_inode(inode);
 178                         wait_on_inode(inode);
 179                 }
 180         } while (inode->i_count);
 181         memset(inode,0,sizeof(*inode));
 182         inode->i_count = 1;
 183         return inode;
 184 }
 185 
 186 struct inode * get_pipe_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 187 {
 188         struct inode * inode;
 189 
 190         if (!(inode = get_empty_inode()))
 191                 return NULL;
 192         if (!(PIPE_BASE(*inode) = (char *) get_free_page(GFP_USER))) {
 193                 inode->i_count = 0;
 194                 return NULL;
 195         }
 196         inode->i_count = 2;     /* sum of readers/writers */
 197         PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
 198         PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
 199         PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
 200         inode->i_pipe = 1;
 201         return inode;
 202 }
 203 
 204 struct inode * iget(int dev,int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 205 {
 206         struct inode * inode, * empty;
 207 
 208         if (!dev)
 209                 panic("iget with dev==0");
 210         empty = get_empty_inode();
 211         inode = inode_table;
 212         while (inode < NR_INODE+inode_table) {
 213                 if (inode->i_dev != dev || inode->i_ino != nr) {
 214                         inode++;
 215                         continue;
 216                 }
 217                 wait_on_inode(inode);
 218                 if (inode->i_dev != dev || inode->i_ino != nr) {
 219                         inode = inode_table;
 220                         continue;
 221                 }
 222                 inode->i_count++;
 223                 if (inode->i_mount) {
 224                         int i;
 225 
 226                         for (i = 0 ; i<NR_SUPER ; i++)
 227                                 if (super_block[i].s_covered==inode)
 228                                         break;
 229                         if (i >= NR_SUPER) {
 230                                 printk("Mounted inode hasn't got sb\n");
 231                                 if (empty)
 232                                         iput(empty);
 233                                 return inode;
 234                         }
 235                         iput(inode);
 236                         if (!(inode = super_block[i].s_mounted))
 237                                 printk("iget: mounted dev has no rootinode\n");
 238                         else {
 239                                 inode->i_count++;
 240                                 wait_on_inode(inode);
 241                         }
 242                 }
 243                 if (empty)
 244                         iput(empty);
 245                 return inode;
 246         }
 247         if (!empty)
 248                 return (NULL);
 249         inode = empty;
 250         if (!(inode->i_sb = get_super(dev))) {
 251                 printk("iget: gouldn't get super-block\n\t");
 252                 iput(inode);
 253                 return NULL;
 254         }
 255         inode->i_dev = dev;
 256         inode->i_ino = nr;
 257         inode->i_flags = inode->i_sb->s_flags;
 258         read_inode(inode);
 259         return inode;
 260 }

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