Beispiel #1
0
Datei: fs.c Projekt: mainboy/xv6
// Test that write_block works, by smashing the superblock and reading it back.
void
check_write_block(void)
{
	super = 0;

	// back up super block
	read_block(0, 0);
	memmove(diskaddr(0), diskaddr(1), PGSIZE);

	// smash it 
	strcpy(diskaddr(1), "OOPS!\n");
	write_block(1);
	assert(block_is_mapped(1));
	assert(!va_is_dirty(diskaddr(1)));

	// clear it out
	sys_page_unmap(0, diskaddr(1));
	assert(!block_is_mapped(1));

	// read it back in
	read_block(1, 0);
	assert(strcmp(diskaddr(1), "OOPS!\n") == 0);

	// fix it
	memmove(diskaddr(1), diskaddr(0), PGSIZE);
	write_block(1);
	super = (struct Super*)diskaddr(1);

	cprintf("write_block is good\n");
}
Beispiel #2
0
// Fault any disk block that is read in to memory by
// loading it from disk.
static void
bc_pgfault(struct UTrapframe *utf)
{
	void *addr = (void *) utf->utf_fault_va;
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
	int r;

	// Check that the fault was within the block cache region
	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("page fault in FS: eip %08x, va %08x, err %04x",
		      utf->utf_eip, addr, utf->utf_err);

	// Sanity check the block number.
	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	// Allocate a page in the disk map region, read the contents
	// of the block from the disk into that page.
	// Hint: first round addr to page boundary. fs/ide.c has code to read
	// the disk.
	//
	// LAB 5: you code here:
	addr = ROUNDDOWN(addr, PGSIZE);
	if( (r = sys_page_alloc(0, addr, PTE_U | PTE_W | PTE_P)) != 0) {
		panic("in bc_pgfault, sys_page_alloc: %e", r);
	}
	assert(!va_is_dirty(addr)); //debug
	if( (r = ide_read(blockno * BLKSECTS, addr, (PGSIZE/SECTSIZE))) != 0) {
		panic("in bc_pgfault, ide_read: %e", r);
	}
	assert(va_is_dirty(addr)); //debug
	// Clear the dirty bit for the disk block page since we just read the
	// block from disk
	if ((r = sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL)) < 0)
		panic("in bc_pgfault, sys_page_map: %e", r);

	// Check that the block we read was allocated. (exercise for
	// the reader: why do we do this *after* reading the block
	// in?)
	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);
}
Beispiel #3
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
    addr = ROUNDDOWN(addr, PGSIZE);
    if (!va_is_mapped(addr) || !va_is_dirty(addr))
      return;
    ide_write(blockno * BLKSECTS, addr, BLKSECTS);
    sys_page_map(0, addr, 0, addr, uvpt[PGNUM(addr)] & PTE_SYSCALL);
}
Beispiel #4
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;
	int r;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	addr = ROUNDDOWN(addr, PGSIZE);
	if (!va_is_mapped(addr) || !va_is_dirty(addr))
		return;

	if (ide_write(blockno * BLKSECTS, addr, BLKSECTS) < 0)
		panic("ide_write failed");
	if ((r = sys_page_map(0, addr, 0, addr, PTE_USER)) < 0)
		panic("sys_page_map: %e", r);
}
Beispiel #5
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	addr = ROUNDDOWN(addr, PGSIZE);

	if (!va_is_mapped(addr) || !va_is_dirty(addr)) return;
	
	ide_write(blockno * BLKSECTS, addr, BLKSECTS);
	
	if (sys_page_map(0, addr, 0, addr, PTE_SYSCALL) < 0)
		panic("bc.c/flush_block: map page failed.\n");
	//panic("flush_block not implemented");
}
Beispiel #6
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
    void
flush_block(void *addr)
{
	uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
	int r;

    if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
        panic("flush_block of bad va %08x", addr);
		
			// LAB 5: Your code here.
	if((va_is_mapped(addr))&&(va_is_dirty(addr)))
	#ifndef VMM_GUEST
		ide_write(blockno*BLKSECTS, ROUNDDOWN(addr,BLKSIZE), BLKSECTS);
	#else
		host_write(blockno*BLKSECTS, ROUNDDOWN(addr,BLKSIZE), BLKSECTS);
	#endif	
	if((va_is_mapped(addr)) && ((r = sys_page_map(0, ROUNDDOWN(addr,PGSIZE), 0, ROUNDDOWN(addr,PGSIZE), PTE_SYSCALL&~PTE_D)) < 0))
			panic("Couldn't flush disk page%e",r);
}
Beispiel #7
0
Datei: bc.c Projekt: YYmooon/439h
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
    addr             = (void *) ROUNDDOWN(addr, PGSIZE);
    uint32_t sectno  = ((uint32_t)addr - DISKMAP) / SECTSIZE;
    uint32_t blockno = (sectno / BLKSECTS);

    if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
        panic("flush_block of bad va %08x", addr);

    // LAB 5: Your code here.
    if(va_is_dirty(addr) && va_is_mapped(addr)) {
        ide_write(sectno, addr, BLKSECTS);
        sys_page_map(0, addr, 
                     0, addr,
                     (PTE_SYSCALL));
        BC_DEBUG("Wrote block %08x, now mapped r/o\n", blockno);
    }
}
Beispiel #8
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
	int r;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	void *dst_addr = (void *)(ROUNDDOWN(addr, PGSIZE));
	// Project addition --> Transparent disk encryption.
	if(va_is_mapped(dst_addr))
	{
		if(va_is_dirty(dst_addr))
		{
			if((blockno == 0) || (blockno == 2)) 
			 	ide_write(blockno * BLKSECTS, dst_addr, BLKSECTS);
			else if((blockno == 1))
			{
				if(!s_encrypted)
					ide_write(blockno * BLKSECTS, dst_addr, BLKSECTS);
				else
				{
					r = transparent_disk_encrypt(blockno, dst_addr);
					if(r)
						return;
				}
			}
			else 
			{ 
				r = transparent_disk_encrypt(blockno, dst_addr);
				if(r)
					return;
			}
			sys_page_map(thisenv->env_id, dst_addr, thisenv->env_id, dst_addr, PTE_SYSCALL);
		}
	}

//	panic("flush_block not implemented");
}
Beispiel #9
0
Datei: bc.c Projekt: YYmooon/439h
// Test that the block cache works, by smashing the superblock and
// reading it back.
static void
check_bc(void)
{
    cprintf("Starting..\n");
    struct Super backup;

    // back up super block
    memmove(&backup, diskaddr(1), sizeof(backup));
    BC_DEBUG("Wrote superblock to disk ram block..\n");
    BC_DEBUG("in memory magic number: %08x\n", ((struct Super*)diskaddr(1))->s_magic);

    // smash it
    strcpy(diskaddr(1), "OOPS!\n");
    flush_block(diskaddr(1));
    assert(va_is_mapped(diskaddr(1)));
    assert(!va_is_dirty(diskaddr(1)));
    cprintf("Smashed disk superblock..\n");

    // clear it out
    sys_page_unmap(0, diskaddr(1));
    assert(!va_is_mapped(diskaddr(1)));
    cprintf("Unmapped superblock va..\n");

    // read it back in
    assert(strcmp(diskaddr(1), "OOPS!\n") == 0);
    cprintf("re-read superblock va..\n");

    // fix it
    memmove(diskaddr(1), &backup, sizeof(backup));
    assert(memcmp(diskaddr(1), &backup, sizeof(backup)) == 0);
    
    flush_block(diskaddr(1));

    assert(memcmp(diskaddr(1), &backup, sizeof(backup)) == 0);
    BC_DEBUG("backup magic number   : %08x\n", backup.s_magic);
    BC_DEBUG("in memory magic number: %08x\n", ((struct Super*)diskaddr(1))->s_magic);
    BC_DEBUG("expected magic value  : %08x\n", FS_MAGIC);
    cprintf("Fixed superblock..\n");

    cprintf("block cache is good\n");
}
Beispiel #10
0
Datei: bc.c Projekt: wuxy/mitjos
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	int r;
	void *blkva;
	blkva=ROUNDDOWN(addr,BLKSIZE);
	if(va_is_mapped(addr)&&va_is_dirty(addr))
	{
		ide_write(blockno*BLKSECTS,blkva,BLKSECTS);
		if((r=sys_page_map(0,blkva,0,blkva,PTE_USER))<0)
			panic("page mapping failed:%e\n",r);
		
	}
	//panic("flush_block not implemented");
}
Beispiel #11
0
Datei: fs.c Projekt: mainboy/xv6
// Copy the current contents of the block out to disk.
// Then clear the PTE_D bit using sys_page_map.
// Hint: Use ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
void
write_block(uint32_t blockno)
{
	char *addr;

	if (!block_is_mapped(blockno))
		panic("write unmapped block %08x", blockno);
	
	// Write the disk block and clear PTE_D.
	// LAB 5: Your code here.
	addr = diskaddr(blockno);	
	if(va_is_dirty(addr) == 0){
		cprintf("va isn't dirty!\n");
		return;
	}
	if(ide_write(blockno * BLKSECTS, addr, BLKSECTS) < 0)
		panic("write_block ide_write fail!\n");
	if(sys_page_map(0,addr,0,addr, PTE_USER) < 0)
		panic("write_block sys_page_map fail!\n");
	return;
}
Beispiel #12
0
// Copy the current contents of the block out to disk.
// Then clear the PTE_D bit using sys_page_map.
// Hint: Use ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
void
write_block(uint32_t blockno)
{
	char *addr;
	int r;
	if (!block_is_mapped(blockno))
		panic("write unmapped block %08x", blockno);
	
	// Write the disk block and clear PTE_D.
	// LAB 5: Your code here.

	addr = diskaddr(blockno);
    if(va_is_dirty(addr)){
        r = ide_write(blockno*BLKSECTS, (void *)addr, BLKSECTS);
        if(r < 0)
            panic("GZ write block fault !!\n");
        r = sys_page_map(0, addr, 0, addr, PTE_USER);
        if(r < 0)
            panic("GZ can not clear PTE_D!!\n");
    }
	//panic("write_block not implemented");
}
Beispiel #13
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_USER constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
    uint32_t blockno = ((uint32_t)addr - DISKMAP) / BLKSIZE;

    if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
        panic("flush_block of bad va %08x", addr);

    // LAB 5: Your code here.
    //panic("flush_block not implemented");
    addr=ROUNDDOWN(addr, PGSIZE);

    if(va_is_mapped(addr) && va_is_dirty(addr))
    {
        ide_write(BLKSECTS*blockno, addr, BLKSECTS);

        if(sys_page_map(0, addr, 0, addr, PTE_USER) < 0)
        {
            panic ("flush_block(), sys_page_map error");
        }
    }
}
Beispiel #14
0
// Flush the contents of the block containing VA out to disk if
// necessary, then clear the PTE_D bit using sys_page_map.
// If the block is not in the block cache or is not dirty, does
// nothing.
// Hint: Use va_is_mapped, va_is_dirty, and ide_write.
// Hint: Use the PTE_SYSCALL constant when calling sys_page_map.
// Hint: Don't forget to round addr down.
void
flush_block(void *addr)
{
	uint64_t blockno = ((uint64_t)addr - DISKMAP) / BLKSIZE;
	int r;	

	if (addr < (void*)DISKMAP || addr >= (void*)(DISKMAP + DISKSIZE))
		panic("flush_block of bad va %08x", addr);

	// LAB 5: Your code here.
	addr = ROUNDDOWN(addr,BLKSIZE);
	if (va_is_mapped(addr) && va_is_dirty(addr))
#ifdef VMM_GUEST
		host_write(blockno*BLKSECTS, addr, BLKSECTS);
#else
		ide_write(blockno*BLKSECTS, addr, BLKSECTS);
#endif
	if(va_is_mapped(addr)) {
		if ((r = sys_page_map(0,addr,0,addr,PTE_SYSCALL&~PTE_D))<0)
			cprintf("error in flushing the block : %e\n",r);
	}
	//panic("flush_block not implemented");
}
Beispiel #15
0
// Is this block dirty?
bool
block_is_dirty(uint32_t blockno)
{
	char *va = diskaddr(blockno);
	return va_is_mapped(va) && va_is_dirty(va);
}