root/fs/inode.c

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

DEFINITIONS

This source file includes following definitions.
  1. inode_init
  2. wait_on_inode
  3. lock_inode
  4. unlock_inode
  5. clear_inode
  6. fs_may_mount
  7. fs_may_umount
  8. write_inode
  9. read_inode
  10. notify_change
  11. bmap
  12. invalidate_inodes
  13. sync_inodes
  14. iput
  15. get_empty_inode
  16. get_pipe_inode
  17. iget
  18. __wait_on_inode

   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 static struct inode inode_table[NR_INODE];
  16 static struct inode * last_inode = inode_table;
  17 
  18 void inode_init(void)
     /* [previous][next][first][last][top][bottom][index][help] */
  19 {
  20         memset(inode_table,0,sizeof(inode_table));      
  21 }
  22 
  23 static void __wait_on_inode(struct inode *);
  24 
  25 static inline void wait_on_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  26 {
  27         if (inode->i_lock)
  28                 __wait_on_inode(inode);
  29 }
  30 
  31 static inline void lock_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  32 {
  33         wait_on_inode(inode);
  34         inode->i_lock = 1;
  35 }
  36 
  37 static inline void unlock_inode(struct 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 /*
  44  * Note that we don't want to disturb any wait-queues when we discard
  45  * an inode.
  46  *
  47  * Argghh. Got bitten by a gcc problem with inlining: no way to tell
  48  * the compiler that the inline asm function 'memset' changes 'inode'.
  49  * I've been searching for the bug for days, and was getting desperate.
  50  * Finally looked at the assembler output... Grrr.
  51  *
  52  * The solution is the weird use of 'volatile'. Ho humm. Have to report
  53  * it to the gcc lists, and hope we can do this more cleanly some day..
  54  */
  55 void clear_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  56 {
  57         struct wait_queue * wait;
  58 
  59         wait_on_inode(inode);
  60         wait = ((volatile struct inode *) inode)->i_wait;
  61         memset(inode,0,sizeof(*inode));
  62         ((volatile struct inode *) inode)->i_wait = wait;
  63 }
  64 
  65 int fs_may_mount(dev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
  66 {
  67         struct inode * inode;
  68 
  69         for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++) {
  70                 if (inode->i_dev != dev)
  71                         continue;
  72                 if (inode->i_count || inode->i_dirt || inode->i_lock)
  73                         return 0;
  74                 clear_inode(inode);
  75         }
  76         return 1;
  77 }
  78 
  79 int fs_may_umount(dev_t dev, struct inode * mount_root)
     /* [previous][next][first][last][top][bottom][index][help] */
  80 {
  81         struct inode * inode;
  82 
  83         for (inode = inode_table+0 ; inode < inode_table+NR_INODE ; inode++) {
  84                 if (inode->i_dev==dev && inode->i_count)
  85                         if (inode == mount_root && inode->i_count == 1)
  86                                 continue;
  87                         else
  88                                 return 0;
  89         }
  90         return 1;
  91 }
  92 
  93 static void write_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
  94 {
  95         if (!inode->i_dirt)
  96                 return;
  97         wait_on_inode(inode);
  98         if (!inode->i_dirt)
  99                 return;
 100         if (!inode->i_sb || !inode->i_sb->s_op || !inode->i_sb->s_op->write_inode) {
 101                 inode->i_dirt = 0;
 102                 return;
 103         }
 104         inode->i_lock = 1;      
 105         inode->i_sb->s_op->write_inode(inode);
 106         unlock_inode(inode);
 107 }
 108 
 109 static void read_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 110 {
 111         lock_inode(inode);
 112         if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->read_inode)
 113                 inode->i_sb->s_op->read_inode(inode);
 114         unlock_inode(inode);
 115 }
 116 
 117 /*
 118  * notify_change is called for inode-changing operations such as
 119  * chown, chmod, utime, and truncate.  It is guaranteed (unlike
 120  * write_inode) to be called from the context of the user requesting
 121  * the change.  It is not called for ordinary access-time updates.
 122  * NFS uses this to get the authentication correct.  -- jrs
 123  */
 124 
 125 int notify_change(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 126 {
 127         if (inode->i_sb && inode->i_sb->s_op  &&
 128             inode->i_sb->s_op->notify_change)
 129                 return inode->i_sb->s_op->notify_change(inode);
 130         return 0;
 131 }
 132 
 133 /*
 134  * bmap is needed for demand-loading and paging: if this function
 135  * doesn't exist for a filesystem, then those things are impossible:
 136  * executables cannot be run from the filesystem etc...
 137  *
 138  * This isn't as bad as it sounds: the read-routines might still work,
 139  * so the filesystem would be otherwise ok (for example, you might have
 140  * a DOS filesystem, which doesn't lend itself to bmap very well, but
 141  * you could still transfer files to/from the filesystem)
 142  */
 143 int bmap(struct inode * inode, int block)
     /* [previous][next][first][last][top][bottom][index][help] */
 144 {
 145         if (inode->i_op && inode->i_op->bmap)
 146                 return inode->i_op->bmap(inode,block);
 147         return 0;
 148 }
 149 
 150 void invalidate_inodes(dev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 151 {
 152         int i;
 153         struct inode * inode;
 154 
 155         inode = 0+inode_table;
 156         for(i=0 ; i<NR_INODE ; i++,inode++) {
 157                 wait_on_inode(inode);
 158                 if (inode->i_dev == dev) {
 159                         if (inode->i_count) {
 160                                 printk("inode in use on removed disk\n\r");
 161                                 continue;
 162                         }
 163                         clear_inode(inode);
 164                 }
 165         }
 166 }
 167 
 168 void sync_inodes(dev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 169 {
 170         struct inode * inode;
 171 
 172         for(inode = 0+inode_table ; inode < NR_INODE+inode_table ; inode++) {
 173                 wait_on_inode(inode);
 174                 if (inode->i_dirt)
 175                         write_inode(inode);
 176         }
 177 }
 178 
 179 void iput(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 180 {
 181         if (!inode)
 182                 return;
 183         wait_on_inode(inode);
 184         if (!inode->i_count) {
 185                 printk("iput: trying to free free inode\n");
 186                 printk("device %04x, inode %d, mode=%07o\n",inode->i_rdev,
 187                         inode->i_ino,inode->i_mode);
 188                 return;
 189         }
 190         if (inode->i_pipe) {
 191                 wake_up(&PIPE_READ_WAIT(*inode));
 192                 wake_up(&PIPE_WRITE_WAIT(*inode));
 193         }
 194 repeat:
 195         if (inode->i_count>1) {
 196                 inode->i_count--;
 197                 return;
 198         }
 199         if (inode->i_pipe) {
 200                 unsigned long page = (unsigned long) PIPE_BASE(*inode);
 201                 PIPE_BASE(*inode) = NULL;
 202                 free_page(page);
 203         }
 204         if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
 205                 inode->i_sb->s_op->put_inode(inode);
 206                 if (!inode->i_nlink)
 207                         return;
 208         }
 209         if (inode->i_dirt) {
 210                 write_inode(inode);     /* we can sleep - so do again */
 211                 wait_on_inode(inode);
 212                 goto repeat;
 213         }
 214         inode->i_count--;
 215         return;
 216 }
 217 
 218 struct inode * get_empty_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 219 {
 220         struct inode * inode;
 221         int i;
 222 
 223 repeat:
 224         inode = NULL;
 225         for (i = NR_INODE; i ; i--) {
 226                 if (++last_inode >= inode_table + NR_INODE)
 227                         last_inode = inode_table;
 228                 if (!last_inode->i_count) {
 229                         inode = last_inode;
 230                         if (!inode->i_dirt && !inode->i_lock)
 231                                 break;
 232                 }
 233         }
 234         if (!inode) {
 235                 for (i=0 ; i<NR_INODE ; i++)
 236                         printk("(%04x: %d (%o)) ",inode_table[i].i_dev,
 237                                 inode_table[i].i_ino,inode_table[i].i_mode);
 238                 panic("No free inodes in mem");
 239         }
 240         if (inode->i_lock) {
 241                 wait_on_inode(inode);
 242                 goto repeat;
 243         }
 244         if (inode->i_dirt) {
 245                 write_inode(inode);
 246                 goto repeat;
 247         }
 248         if (inode->i_count)
 249                 goto repeat;
 250         clear_inode(inode);
 251         inode->i_count = 1;
 252         inode->i_nlink = 1;
 253         return inode;
 254 }
 255 
 256 struct inode * get_pipe_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 257 {
 258         struct inode * inode;
 259 
 260         if (!(inode = get_empty_inode()))
 261                 return NULL;
 262         if (!(PIPE_BASE(*inode) = (char *) get_free_page(GFP_USER))) {
 263                 inode->i_count = 0;
 264                 return NULL;
 265         }
 266         inode->i_count = 2;     /* sum of readers/writers */
 267         PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
 268         PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
 269         PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
 270         inode->i_pipe = 1;
 271         return inode;
 272 }
 273 
 274 struct inode * iget(struct super_block * sb,int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 275 {
 276         struct inode * inode, * empty;
 277 
 278         if (!sb)
 279                 panic("iget with sb==NULL");
 280         empty = get_empty_inode();
 281         inode = inode_table;
 282         while (inode < NR_INODE+inode_table) {
 283                 if (inode->i_dev != sb->s_dev || inode->i_ino != nr) {
 284                         inode++;
 285                         continue;
 286                 }
 287                 wait_on_inode(inode);
 288                 if (inode->i_dev != sb->s_dev || inode->i_ino != nr) {
 289                         inode = inode_table;
 290                         continue;
 291                 }
 292                 inode->i_count++;
 293                 if (inode->i_mount) {
 294                         int i;
 295 
 296                         for (i = 0 ; i<NR_SUPER ; i++)
 297                                 if (super_block[i].s_covered==inode)
 298                                         break;
 299                         if (i >= NR_SUPER) {
 300                                 printk("Mounted inode hasn't got sb\n");
 301                                 if (empty)
 302                                         iput(empty);
 303                                 return inode;
 304                         }
 305                         iput(inode);
 306                         if (!(inode = super_block[i].s_mounted))
 307                                 printk("iget: mounted dev has no rootinode\n");
 308                         else {
 309                                 inode->i_count++;
 310                                 wait_on_inode(inode);
 311                         }
 312                 }
 313                 if (empty)
 314                         iput(empty);
 315                 return inode;
 316         }
 317         if (!empty)
 318                 return (NULL);
 319         inode = empty;
 320         inode->i_sb = sb;
 321         inode->i_dev = sb->s_dev;
 322         inode->i_ino = nr;
 323         inode->i_flags = sb->s_flags;
 324         read_inode(inode);
 325         return inode;
 326 }
 327 
 328 /*
 329  * The "new" scheduling primitives (new as of 0.97 or so) allow this to
 330  * be done without disabling interrupts (other than in the actual queue
 331  * updating things: only a couple of 386 instructions). This should be
 332  * much better for interrupt latency.
 333  */
 334 static void __wait_on_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 335 {
 336         struct wait_queue wait = { current, NULL };
 337 
 338         add_wait_queue(&inode->i_wait, &wait);
 339 repeat:
 340         current->state = TASK_UNINTERRUPTIBLE;
 341         if (inode->i_lock) {
 342                 schedule();
 343                 goto repeat;
 344         }
 345         remove_wait_queue(&inode->i_wait, &wait);
 346         current->state = TASK_RUNNING;
 347 }

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