fix iget() bug that allocated in-use inode[] entries
This commit is contained in:
parent
8abe2bcf15
commit
17e3cf15ba
14
Notes
14
Notes
|
@ -357,7 +357,6 @@ OH! recursive interrupts will use up any amount of cpu[].stack!
|
||||||
|
|
||||||
disk scheduling
|
disk scheduling
|
||||||
mkdir
|
mkdir
|
||||||
more than one directory content block
|
|
||||||
sh arguments
|
sh arguments
|
||||||
sh redirection
|
sh redirection
|
||||||
indirect blocks
|
indirect blocks
|
||||||
|
@ -366,17 +365,10 @@ two bugs in unlink: don't just return if nlink > 0,
|
||||||
is there a create/create race for same file name?
|
is there a create/create race for same file name?
|
||||||
resulting in two entries w/ same name in directory?
|
resulting in two entries w/ same name in directory?
|
||||||
|
|
||||||
namei
|
|
||||||
return just inode
|
|
||||||
return offset in dir where found, w/ dir locked, for unlink
|
|
||||||
return dir locked, for mknod
|
|
||||||
|
|
||||||
is the offset alone useful? how do I read/write it?
|
|
||||||
|
|
||||||
test: one process unlinks a file while another links to it
|
test: one process unlinks a file while another links to it
|
||||||
test: simultaneous create of same file
|
test: simultaneous create of same file
|
||||||
test: one process opens a file while another deletes it
|
test: one process opens a file while another deletes it
|
||||||
|
|
||||||
oy, mkfs wants dir size to be last written entry, but i
|
wdir should use writei, to avoid special-case block allocation
|
||||||
want it to be nblocks*512
|
also readi
|
||||||
maybe fix kernel code to handle former
|
is dir locked? probably
|
||||||
|
|
2
fd.c
2
fd.c
|
@ -8,6 +8,8 @@
|
||||||
#include "fd.h"
|
#include "fd.h"
|
||||||
#include "spinlock.h"
|
#include "spinlock.h"
|
||||||
#include "dev.h"
|
#include "dev.h"
|
||||||
|
#include "fs.h"
|
||||||
|
#include "fsvar.h"
|
||||||
|
|
||||||
struct spinlock fd_table_lock;
|
struct spinlock fd_table_lock;
|
||||||
struct devsw devsw[NDEV];
|
struct devsw devsw[NDEV];
|
||||||
|
|
50
fs.c
50
fs.c
|
@ -54,7 +54,6 @@ balloc(uint dev)
|
||||||
if (b >= size)
|
if (b >= size)
|
||||||
panic("balloc: out of blocks\n");
|
panic("balloc: out of blocks\n");
|
||||||
|
|
||||||
cprintf ("balloc: allocate block %d\n", b);
|
|
||||||
bp->data[bi/8] |= 0x1 << (bi % 8);
|
bp->data[bi/8] |= 0x1 << (bi % 8);
|
||||||
bwrite (bp, BBLOCK(b, ninodes)); // mark it allocated on disk
|
bwrite (bp, BBLOCK(b, ninodes)); // mark it allocated on disk
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
|
@ -70,7 +69,6 @@ bfree(int dev, uint b)
|
||||||
int ninodes;
|
int ninodes;
|
||||||
uchar m;
|
uchar m;
|
||||||
|
|
||||||
cprintf ("bfree: free block %d\n", b);
|
|
||||||
bp = bread(dev, 1);
|
bp = bread(dev, 1);
|
||||||
sb = (struct superblock *) bp->data;
|
sb = (struct superblock *) bp->data;
|
||||||
ninodes = sb->ninodes;
|
ninodes = sb->ninodes;
|
||||||
|
@ -93,13 +91,14 @@ bfree(int dev, uint b)
|
||||||
struct inode *
|
struct inode *
|
||||||
iget(uint dev, uint inum)
|
iget(uint dev, uint inum)
|
||||||
{
|
{
|
||||||
struct inode *ip, *nip = 0;
|
struct inode *ip, *nip;
|
||||||
struct dinode *dip;
|
struct dinode *dip;
|
||||||
struct buf *bp;
|
struct buf *bp;
|
||||||
|
|
||||||
acquire(&inode_table_lock);
|
acquire(&inode_table_lock);
|
||||||
|
|
||||||
loop:
|
loop:
|
||||||
|
nip = 0;
|
||||||
for(ip = &inode[0]; ip < &inode[NINODE]; ip++){
|
for(ip = &inode[0]; ip < &inode[NINODE]; ip++){
|
||||||
if(ip->count > 0 && ip->dev == dev && ip->inum == inum){
|
if(ip->count > 0 && ip->dev == dev && ip->inum == inum){
|
||||||
if(ip->busy){
|
if(ip->busy){
|
||||||
|
@ -180,11 +179,9 @@ ialloc(uint dev, short type)
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inum >= ninodes) {
|
if (inum >= ninodes)
|
||||||
panic ("ialloc: no inodes left\n");
|
panic ("ialloc: no inodes left\n");
|
||||||
}
|
|
||||||
|
|
||||||
cprintf ("ialloc: %d\n", inum);
|
|
||||||
dip->type = type;
|
dip->type = type;
|
||||||
bwrite (bp, IBLOCK(inum)); // mark it allocated on the disk
|
bwrite (bp, IBLOCK(inum)); // mark it allocated on the disk
|
||||||
brelse(bp);
|
brelse(bp);
|
||||||
|
@ -195,7 +192,6 @@ ialloc(uint dev, short type)
|
||||||
static void
|
static void
|
||||||
ifree(struct inode *ip)
|
ifree(struct inode *ip)
|
||||||
{
|
{
|
||||||
cprintf("ifree: %d\n", ip->inum);
|
|
||||||
ip->type = 0;
|
ip->type = 0;
|
||||||
iupdate(ip);
|
iupdate(ip);
|
||||||
}
|
}
|
||||||
|
@ -220,7 +216,7 @@ ilock(struct inode *ip)
|
||||||
void
|
void
|
||||||
iunlock(struct inode *ip)
|
iunlock(struct inode *ip)
|
||||||
{
|
{
|
||||||
if(ip->busy != 1)
|
if(ip->busy != 1 || ip->count < 1)
|
||||||
panic("iunlock");
|
panic("iunlock");
|
||||||
|
|
||||||
acquire(&inode_table_lock);
|
acquire(&inode_table_lock);
|
||||||
|
@ -271,7 +267,7 @@ iput(struct inode *ip)
|
||||||
if(ip->count < 1 || ip->busy != 1)
|
if(ip->count < 1 || ip->busy != 1)
|
||||||
panic("iput");
|
panic("iput");
|
||||||
|
|
||||||
if ((ip->count <= 1) && (ip->nlink <= 0))
|
if ((ip->count == 1) && (ip->nlink == 0))
|
||||||
iunlink(ip);
|
iunlink(ip);
|
||||||
|
|
||||||
acquire(&inode_table_lock);
|
acquire(&inode_table_lock);
|
||||||
|
@ -498,8 +494,6 @@ mknod(char *cp, short type, short major, short minor)
|
||||||
{
|
{
|
||||||
struct inode *ip, *dp;
|
struct inode *ip, *dp;
|
||||||
|
|
||||||
cprintf("mknod: %s %d %d %d\n", cp, type, major, minor);
|
|
||||||
|
|
||||||
if ((dp = namei(cp, NAMEI_CREATE, 0)) == 0)
|
if ((dp = namei(cp, NAMEI_CREATE, 0)) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -525,24 +519,17 @@ unlink(char *cp)
|
||||||
{
|
{
|
||||||
struct inode *ip, *dp;
|
struct inode *ip, *dp;
|
||||||
struct dirent de;
|
struct dirent de;
|
||||||
uint off, inum, cc;
|
uint off, inum, dev;
|
||||||
|
|
||||||
cprintf("unlink(%s)\n", cp);
|
if ((dp = namei(cp, NAMEI_DELETE, &off)) == 0)
|
||||||
|
|
||||||
if ((dp = namei(cp, NAMEI_DELETE, &off)) == 0) {
|
|
||||||
cprintf("unlink(%s) it doesn't exist\n", cp);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
if((cc = readi(dp, (char*)&de, off, sizeof(de))) != sizeof(de) ||
|
dev = dp->dev;
|
||||||
de.inum == 0){
|
|
||||||
cprintf("off %d dp->size %d cc %d de.inum %d",
|
if(readi(dp, (char*)&de, off, sizeof(de)) != sizeof(de) || de.inum == 0)
|
||||||
off, dp->size, cc, de.inum);
|
|
||||||
panic("unlink no entry");
|
panic("unlink no entry");
|
||||||
}
|
|
||||||
inum = de.inum;
|
inum = de.inum;
|
||||||
cprintf("dinum %d off %d de %s/%d\n",
|
|
||||||
dp->inum, off, de.name, de.inum);
|
|
||||||
|
|
||||||
memset(&de, 0, sizeof(de));
|
memset(&de, 0, sizeof(de));
|
||||||
if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
|
if(writei(dp, (char*)&de, off, sizeof(de)) != sizeof(de))
|
||||||
|
@ -551,9 +538,7 @@ unlink(char *cp)
|
||||||
iupdate(dp);
|
iupdate(dp);
|
||||||
iput(dp);
|
iput(dp);
|
||||||
|
|
||||||
ip = iget(dp->dev, inum);
|
ip = iget(dev, inum);
|
||||||
if(ip == 0)
|
|
||||||
panic("unlink no inode");
|
|
||||||
|
|
||||||
ip->nlink--;
|
ip->nlink--;
|
||||||
|
|
||||||
|
@ -568,14 +553,9 @@ link(char *name1, char *name2)
|
||||||
{
|
{
|
||||||
struct inode *ip, *dp;
|
struct inode *ip, *dp;
|
||||||
|
|
||||||
cprintf("link(%s, %s)\n", name1, name2);
|
if ((ip = namei(name1, NAMEI_LOOKUP, 0)) == 0)
|
||||||
|
|
||||||
if ((ip = namei(name1, NAMEI_LOOKUP, 0)) == 0){
|
|
||||||
cprintf(" failed %s does not exist\n", name1);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
if(ip->type == T_DIR){
|
if(ip->type == T_DIR){
|
||||||
cprintf(" failed %s is a dir\n", name1);
|
|
||||||
iput(ip);
|
iput(ip);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -583,12 +563,10 @@ link(char *name1, char *name2)
|
||||||
iunlock(ip);
|
iunlock(ip);
|
||||||
|
|
||||||
if ((dp = namei(name2, NAMEI_CREATE, 0)) == 0) {
|
if ((dp = namei(name2, NAMEI_CREATE, 0)) == 0) {
|
||||||
cprintf(" failed %s exists\n", name2);
|
|
||||||
idecref(ip);
|
idecref(ip);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if(dp->dev != ip->dev){
|
if(dp->dev != ip->dev){
|
||||||
cprintf(" cross-device link\n");
|
|
||||||
idecref(ip);
|
idecref(ip);
|
||||||
iput(dp);
|
iput(dp);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -602,7 +580,5 @@ link(char *name1, char *name2)
|
||||||
iput(dp);
|
iput(dp);
|
||||||
iput(ip);
|
iput(ip);
|
||||||
|
|
||||||
cprintf(" succeeded\n");
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
3
init.c
3
init.c
|
@ -17,10 +17,7 @@ main(void)
|
||||||
open("console", 1);
|
open("console", 1);
|
||||||
open("console", 1);
|
open("console", 1);
|
||||||
|
|
||||||
puts("init...\n");
|
|
||||||
|
|
||||||
while(1){
|
while(1){
|
||||||
puts("running sh...\n");
|
|
||||||
pid = fork();
|
pid = fork();
|
||||||
if(pid == 0){
|
if(pid == 0){
|
||||||
exec("sh", sh_args);
|
exec("sh", sh_args);
|
||||||
|
|
2
ioapic.c
2
ioapic.c
|
@ -43,7 +43,6 @@ ioapic_init(void)
|
||||||
id = ioapic_read(io, IOAPIC_ID) >> APIC_ID_SHIFT;
|
id = ioapic_read(io, IOAPIC_ID) >> APIC_ID_SHIFT;
|
||||||
if (id != ioapic_id)
|
if (id != ioapic_id)
|
||||||
panic ("ioapic_init: id isn't equal to ioapic_id\n");
|
panic ("ioapic_init: id isn't equal to ioapic_id\n");
|
||||||
cprintf ("ioapic VER: 0x%x id %d nintr %d\n", l, id, nintr);
|
|
||||||
for (i = 0; i < nintr; i++) {
|
for (i = 0; i < nintr; i++) {
|
||||||
// active-hi and edge-triggered for ISA interrupts
|
// active-hi and edge-triggered for ISA interrupts
|
||||||
// Assume that pin 0 on the first I/O APIC is an ExtINT pin.
|
// Assume that pin 0 on the first I/O APIC is an ExtINT pin.
|
||||||
|
@ -78,5 +77,4 @@ ioapic_enable (int irq, int cpunum)
|
||||||
h &= ~IOART_DEST;
|
h &= ~IOART_DEST;
|
||||||
h |= (cpunum << APIC_ID_SHIFT);
|
h |= (cpunum << APIC_ID_SHIFT);
|
||||||
ioapic_write(io, IOAPIC_REDTBL_HI(irq), h);
|
ioapic_write(io, IOAPIC_REDTBL_HI(irq), h);
|
||||||
cprintf("cpu%d: intr %d: lo 0x%x hi 0x%x\n", cpu(), irq, l, h);
|
|
||||||
}
|
}
|
||||||
|
|
7
picirq.c
7
picirq.c
|
@ -22,13 +22,6 @@ irq_setmask_8259A(ushort mask)
|
||||||
|
|
||||||
outb(IO_PIC1+1, (char)mask);
|
outb(IO_PIC1+1, (char)mask);
|
||||||
outb(IO_PIC2+1, (char)(mask >> 8));
|
outb(IO_PIC2+1, (char)(mask >> 8));
|
||||||
|
|
||||||
cprintf("%d: enabled interrupts:", cpu());
|
|
||||||
|
|
||||||
for (i = 0; i < 16; i++)
|
|
||||||
if (~mask & (1<<i))
|
|
||||||
cprintf(" %d", i);
|
|
||||||
cprintf("\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize the 8259A interrupt controllers. */
|
/* Initialize the 8259A interrupt controllers. */
|
||||||
|
|
|
@ -284,6 +284,7 @@ sys_mknod(void)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
nip = mknod (cp->mem + arg0, (short) arg1, (short) arg2, (short) arg3);
|
nip = mknod (cp->mem + arg0, (short) arg1, (short) arg2, (short) arg3);
|
||||||
|
if(nip)
|
||||||
iput(nip);
|
iput(nip);
|
||||||
return (nip == 0) ? -1 : 0;
|
return (nip == 0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue