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

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