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(int flags, 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(flags, 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("VFS: inode busy on removed device %d/%d\n",
 168                                                         MAJOR(dev), MINOR(dev));
 169                                 continue;
 170                         }
 171                         clear_inode(inode);
 172                 }
 173         }
 174 }
 175 
 176 void sync_inodes(dev_t dev)
     /* [previous][next][first][last][top][bottom][index][help] */
 177 {
 178         struct inode * inode;
 179 
 180         for(inode = 0+inode_table ; inode < NR_INODE+inode_table ; inode++) {
 181                 if (dev && inode->i_dev != dev)
 182                         continue;
 183                 wait_on_inode(inode);
 184                 if (inode->i_dirt)
 185                         write_inode(inode);
 186         }
 187 }
 188 
 189 void iput(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 190 {
 191         if (!inode)
 192                 return;
 193         wait_on_inode(inode);
 194         if (!inode->i_count) {
 195                 printk("VFS: iput: trying to free free inode\n");
 196                 printk("VFS: device %d/%d, inode %d, mode=0%07o\n",
 197                         MAJOR(inode->i_rdev), MINOR(inode->i_rdev),
 198                                         inode->i_ino, inode->i_mode);
 199                 return;
 200         }
 201         if (inode->i_pipe) {
 202                 wake_up(&PIPE_READ_WAIT(*inode));
 203                 wake_up(&PIPE_WRITE_WAIT(*inode));
 204         }
 205 repeat:
 206         if (inode->i_count>1) {
 207                 inode->i_count--;
 208                 return;
 209         }
 210         wake_up(&inode_wait);
 211         if (inode->i_pipe) {
 212                 unsigned long page = (unsigned long) PIPE_BASE(*inode);
 213                 PIPE_BASE(*inode) = NULL;
 214                 free_page(page);
 215         }
 216         if (inode->i_sb && inode->i_sb->s_op && inode->i_sb->s_op->put_inode) {
 217                 inode->i_sb->s_op->put_inode(inode);
 218                 if (!inode->i_nlink)
 219                         return;
 220         }
 221         if (inode->i_dirt) {
 222                 write_inode(inode);     /* we can sleep - so do again */
 223                 wait_on_inode(inode);
 224                 goto repeat;
 225         }
 226         inode->i_count--;
 227         return;
 228 }
 229 
 230 struct inode * get_empty_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 231 {
 232         struct inode * inode;
 233         int i;
 234 
 235 repeat:
 236         inode = NULL;
 237         for (i = NR_INODE; i ; i--) {
 238                 if (++last_inode >= inode_table + NR_INODE)
 239                         last_inode = inode_table;
 240                 if (!last_inode->i_count) {
 241                         inode = last_inode;
 242                         if (!inode->i_dirt && !inode->i_lock)
 243                                 break;
 244                 }
 245         }
 246         if (!inode) {
 247                 printk("VFS: No free inodes - contact Linus\n");
 248                 sleep_on(&inode_wait);
 249                 goto repeat;
 250         }
 251         if (inode->i_lock) {
 252                 wait_on_inode(inode);
 253                 goto repeat;
 254         }
 255         if (inode->i_dirt) {
 256                 write_inode(inode);
 257                 goto repeat;
 258         }
 259         if (inode->i_count)
 260                 goto repeat;
 261         clear_inode(inode);
 262         inode->i_count = 1;
 263         inode->i_nlink = 1;
 264         return inode;
 265 }
 266 
 267 struct inode * get_pipe_inode(void)
     /* [previous][next][first][last][top][bottom][index][help] */
 268 {
 269         struct inode * inode;
 270 
 271         if (!(inode = get_empty_inode()))
 272                 return NULL;
 273         if (!(PIPE_BASE(*inode) = (char *) get_free_page(GFP_USER))) {
 274                 inode->i_count = 0;
 275                 return NULL;
 276         }
 277         inode->i_count = 2;     /* sum of readers/writers */
 278         PIPE_READ_WAIT(*inode) = PIPE_WRITE_WAIT(*inode) = NULL;
 279         PIPE_HEAD(*inode) = PIPE_TAIL(*inode) = 0;
 280         PIPE_RD_OPENERS(*inode) = PIPE_WR_OPENERS(*inode) = 0;
 281         PIPE_READERS(*inode) = PIPE_WRITERS(*inode) = 1;
 282         inode->i_pipe = 1;
 283         inode->i_mode |= S_IFIFO;
 284         inode->i_uid = current->euid;
 285         inode->i_gid = current->egid;
 286         inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 287         return inode;
 288 }
 289 
 290 struct inode * iget(struct super_block * sb,int nr)
     /* [previous][next][first][last][top][bottom][index][help] */
 291 {
 292         struct inode * inode, * empty;
 293 
 294         if (!sb)
 295                 panic("VFS: iget with sb==NULL");
 296         empty = get_empty_inode();
 297         inode = inode_table;
 298         while (inode < NR_INODE+inode_table) {
 299                 if (inode->i_dev != sb->s_dev || inode->i_ino != nr) {
 300                         inode++;
 301                         continue;
 302                 }
 303                 wait_on_inode(inode);
 304                 if (inode->i_dev != sb->s_dev || inode->i_ino != nr) {
 305                         inode = inode_table;
 306                         continue;
 307                 }
 308                 inode->i_count++;
 309                 if (inode->i_mount) {
 310                         int i;
 311 
 312                         for (i = 0 ; i<NR_SUPER ; i++)
 313                                 if (super_block[i].s_covered==inode)
 314                                         break;
 315                         if (i >= NR_SUPER) {
 316                                 printk("VFS: Mounted inode hasn't got sb\n");
 317                                 if (empty) {
 318                                         if (last_inode > inode_table)
 319                                                 --last_inode;
 320                                         else
 321                                                 last_inode
 322                                                 = inode_table + NR_INODE;
 323                                         iput(empty);
 324                                 }
 325                                 return inode;
 326                         }
 327                         iput(inode);
 328                         if (!(inode = super_block[i].s_mounted))
 329                                 printk("VFS: Mounted device %d/%d has no rootinode\n",
 330                                         MAJOR(inode->i_dev), MINOR(inode->i_dev));
 331                         else {
 332                                 inode->i_count++;
 333                                 wait_on_inode(inode);
 334                         }
 335                 }
 336                 if (empty) {
 337                         if (last_inode > inode_table)
 338                                 --last_inode;
 339                         else
 340                                 last_inode
 341                                 = inode_table + NR_INODE;
 342                         iput(empty);
 343                 }
 344                 return inode;
 345         }
 346         if (!empty)
 347                 return (NULL);
 348         inode = empty;
 349         inode->i_sb = sb;
 350         inode->i_dev = sb->s_dev;
 351         inode->i_ino = nr;
 352         inode->i_flags = sb->s_flags;
 353         read_inode(inode);
 354         return inode;
 355 }
 356 
 357 /*
 358  * The "new" scheduling primitives (new as of 0.97 or so) allow this to
 359  * be done without disabling interrupts (other than in the actual queue
 360  * updating things: only a couple of 386 instructions). This should be
 361  * much better for interrupt latency.
 362  */
 363 static void __wait_on_inode(struct inode * inode)
     /* [previous][next][first][last][top][bottom][index][help] */
 364 {
 365         struct wait_queue wait = { current, NULL };
 366 
 367         add_wait_queue(&inode->i_wait, &wait);
 368 repeat:
 369         current->state = TASK_UNINTERRUPTIBLE;
 370         if (inode->i_lock) {
 371                 schedule();
 372                 goto repeat;
 373         }
 374         remove_wait_queue(&inode->i_wait, &wait);
 375         current->state = TASK_RUNNING;
 376 }

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