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

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