xref: /xv6-public/fs.c (revision 11a9947f)
1*11a9947fSrtm #include "types.h"
2*11a9947fSrtm #include "param.h"
3*11a9947fSrtm #include "x86.h"
4*11a9947fSrtm #include "mmu.h"
5*11a9947fSrtm #include "proc.h"
6*11a9947fSrtm #include "defs.h"
7*11a9947fSrtm #include "spinlock.h"
8*11a9947fSrtm #include "buf.h"
9*11a9947fSrtm #include "fs.h"
10*11a9947fSrtm #include "fsvar.h"
11*11a9947fSrtm 
12*11a9947fSrtm // these are inodes currently in use
13*11a9947fSrtm // an entry is free if count == 0
14*11a9947fSrtm struct inode inode[NINODE];
15*11a9947fSrtm struct spinlock inode_table_lock;
16*11a9947fSrtm 
17*11a9947fSrtm struct inode *
18*11a9947fSrtm iget(uint dev, uint inum)
19*11a9947fSrtm {
20*11a9947fSrtm   struct inode *ip, *nip = 0;
21*11a9947fSrtm   struct dinode *dip;
22*11a9947fSrtm   struct buf *bp;
23*11a9947fSrtm 
24*11a9947fSrtm   acquire(&inode_table_lock);
25*11a9947fSrtm 
26*11a9947fSrtm  loop:
27*11a9947fSrtm   for(ip = &inode[0]; ip < &inode[NINODE]; ip++){
28*11a9947fSrtm     if(ip->count > 0 && ip->dev == dev && ip->inum == inum){
29*11a9947fSrtm       if(ip->busy){
30*11a9947fSrtm         sleep(ip, &inode_table_lock);
31*11a9947fSrtm         goto loop;
32*11a9947fSrtm       }
33*11a9947fSrtm       ip->count++;
34*11a9947fSrtm       release(&inode_table_lock);
35*11a9947fSrtm       return ip;
36*11a9947fSrtm     }
37*11a9947fSrtm     if(nip == 0 && ip->count == 0)
38*11a9947fSrtm       nip = ip;
39*11a9947fSrtm   }
40*11a9947fSrtm 
41*11a9947fSrtm   if(nip == 0)
42*11a9947fSrtm     panic("out of inodes");
43*11a9947fSrtm 
44*11a9947fSrtm   nip->dev = dev;
45*11a9947fSrtm   nip->inum = inum;
46*11a9947fSrtm   nip->count = 1;
47*11a9947fSrtm   nip->busy = 1;
48*11a9947fSrtm 
49*11a9947fSrtm   release(&inode_table_lock);
50*11a9947fSrtm 
51*11a9947fSrtm   bp = bread(dev, inum / IPB + 2);
52*11a9947fSrtm   dip = &((struct dinode *)(bp->data))[inum % IPB];
53*11a9947fSrtm   nip->type = dip->type;
54*11a9947fSrtm   nip->nlink = dip->nlink;
55*11a9947fSrtm   nip->size = dip->size;
56*11a9947fSrtm   memmove(nip->addrs, dip->addrs, sizeof(nip->addrs));
57*11a9947fSrtm   cprintf("bn %d off %d\n", inum / IPB + 2, (unsigned)dip - (unsigned)bp->data);
58*11a9947fSrtm   brelse(bp);
59*11a9947fSrtm 
60*11a9947fSrtm   return nip;
61*11a9947fSrtm }
62*11a9947fSrtm 
63*11a9947fSrtm void
64*11a9947fSrtm iput(struct inode *ip)
65*11a9947fSrtm {
66*11a9947fSrtm   acquire(&inode_table_lock);
67*11a9947fSrtm 
68*11a9947fSrtm   ip->count -= 1;
69*11a9947fSrtm   ip->busy = 0;
70*11a9947fSrtm   wakeup(ip);
71*11a9947fSrtm 
72*11a9947fSrtm   release(&inode_table_lock);
73*11a9947fSrtm }
74