Exemple #1
0
// Allocate a page to hold the disk block
int
map_block(uint32_t blockno)
{
	if (block_is_mapped(blockno))
		return 0;
	return sys_page_alloc(0, diskaddr(blockno), PTE_U|PTE_P|PTE_W);
}
Exemple #2
0
// Set *blk to point at the filebno'th block in file 'f'.
// Allocate the block if it doesn't yet exist.
// Returns 0 on success, < 0 on error.
int
file_get_block(struct File *f, uint32_t filebno, char **blk)
{
	int r;
	uint32_t diskbno;

	// Read in the block, leaving the pointer in *blk.
	// Hint: Use file_map_block and read_block.
	// LAB 5: Your code here.
	r = file_map_block(f, filebno, &diskbno, 1);
	if (r)
		return r;

	// If the block is already mapped we return it
	// instead of reading the block from disk again.
	// XXX: I'm not sure whether this is the right
	// thing to do, however, looks like lab5 says
	// to do that (p. 7).
	if (block_is_mapped(diskbno)) {
		if (blk)
			*blk = diskaddr(diskbno);
		return 0;
	}

	return read_block(diskbno, blk);
}
Exemple #3
0
// Make sure a particular disk block is loaded into memory.
// Returns 0 on success, or a negative error code on error.
// 
// If blk != 0, set *blk to the address of the block in memory.
//
// Hint: Use diskaddr, map_block, and ide_read.
static int
read_block(uint32_t blockno, char **blk)
{
	int r;
	char *addr;

	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);

	// LAB 5: Your code here.
	addr = diskaddr(blockno);
	if (block_is_mapped(blockno)) {
		goto succeeded;
	}

	// now that the block is not in memory, allocate memory and read it in.
	if ((r = map_block(blockno)) < 0)
		return r;
	if ((r = ide_read(blockno * BLKSECTS, addr, BLKSECTS)) < 0)
		return r;

succeeded:
	if (blk)
		*blk = addr;
	return 0;
}
Exemple #4
0
// Flush the contents and metadata of file f out to disk.
// Loop over all the blocks in file.
// Translate the file block number into a disk block number
// and then check whether that disk block is dirty.  If so, write it out.
void
file_flush(struct File *f)
{
	int i;
	uint32_t *pdiskbno;

	for (i = 0; i < (f->f_size + BLKSIZE - 1) / BLKSIZE; i++) {
		if (file_block_walk(f, i, &pdiskbno, 0) < 0 ||
		    pdiskbno == NULL || *pdiskbno == 0)
			continue;
		flush_block(diskaddr(*pdiskbno));
	}
	flush_block(f);
	if (f->f_indirect)
		flush_block(diskaddr(f->f_indirect));
}
Exemple #5
0
// Make sure a particular disk block is loaded into memory.
// Returns 0 on success, or a negative error code on error.
// 
// If blk != 0, set *blk to the address of the block in memory.
//
// Hint: Use diskaddr, map_block, and ide_read.
static int
read_block(uint32_t blockno, char **blk)
{
	int r;
	char *addr;

	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);
	
	addr = diskaddr(blockno);
    if(!block_is_mapped(blockno)){
        if((r = map_block(blockno)) < 0)
            return r;
        r = ide_read(blockno*BLKSECTS, (void *)addr, BLKSECTS);
        if(r < 0)
            return r;
    }
    if(blk)
        *blk = addr;
	
	return 0;
}
Exemple #6
0
Fichier : fs.c Projet : MG47/JOS-MG
// Set *blk to the address in memory where the filebno'th
// block of file 'f' would be mapped.
//
// Returns 0 on success, < 0 on error.  Errors are:
//	-E_NO_DISK if a block needed to be allocated but the disk is full.
//	-E_INVAL if filebno is out of range.
//
// Hint: Use file_block_walk and alloc_block.
int
file_get_block(struct File *f, uint32_t filebno, char **blk)
{
       // code for lab 5- M.G
       //      panic("file_get_block not implemented");

    uint32_t *ppdiskbno;
    uint32_t new_block_no;

    int return_value;    

    if ((return_value = file_block_walk(f, filebno, &ppdiskbno,true)) < 0)
    {
        return return_value;
    }    

    if (!*ppdiskbno)
    {
		if ((new_block_no = alloc_block()) < 0)
        {
			return -E_NO_DISK;
        }
	    *ppdiskbno = new_block_no;
    }   
    
    *blk = diskaddr(*ppdiskbno);

    return 0;
}
Exemple #7
0
// Read and validate the file system bitmap.
//
// Read all the bitmap blocks into memory.
// Set the "bitmap" pointer to point at the beginning of the first
// bitmap block.
// 
// Check that all reserved blocks -- 0, 1, and the bitmap blocks themselves --
// are all marked as in-use
// (for each block i, assert(!block_is_free(i))).
//
// Hint: Assume that the superblock has already been loaded into
// memory (in variable 'super').  Check out super->s_nblocks.
void
read_bitmap(void)
{
	int r;
	uint32_t i;

	// Read the bitmap into memory.
	// The bitmap consists of one or more blocks.  A single bitmap block
	// contains the in-use bits for BLKBITSIZE blocks.  There are
	// super->s_nblocks blocks in the disk altogether.
	// Set 'bitmap' to point to the first address in the bitmap.
	// Hint: Use read_block.

	// LAB 5: Your code here.
	// bitmap blocks start at block 2.
	for (i = 0; i < (super->s_nblocks - 1) / BLKBITSIZE + 1; i++) {
		if ((r = read_block(i + 2, NULL)) < 0)
			panic("read_block for bitmap %d failed: %e.\n", i, r);
	}
	bitmap = (uint32_t *) diskaddr(2);

	// Make sure the reserved and root blocks are marked in-use.
	assert(!block_is_free(0));
	assert(!block_is_free(1));
	assert(bitmap);

	// Make sure that the bitmap blocks are marked in-use.
	// LAB 5: Your code here.
	for (i = 0; i < super->s_nblocks / BLKBITSIZE; i++)
		assert(!block_is_free(i + 2));
	cprintf("read_bitmap is good\n");
}
Exemple #8
0
Fichier : fs.c Projet : scau/JOS
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
	if (filebno >= NDIRECT + NINDIRECT) {
		return -E_INVAL;
	}
	uint32_t nblock = f->f_size / BLKSIZE;
	if (filebno > nblock) {
		return -E_NOT_FOUND;
	}
	if (filebno < NDIRECT) {
		*ppdiskbno = &f->f_direct[filebno];
		return 0;
	}
	else {
		if(!f->f_indirect) {
			return -E_NOT_FOUND;
		}
		uint32_t* index = (uint32_t*)diskaddr(f->f_indirect);
		*ppdiskbno = &index[filebno - NDIRECT] ;
	}
	return 0;
    // LAB 5: Your code here.
	// panic("file_block_walk not implemented");
}
Exemple #9
0
// Make sure a particular disk block is loaded into memory.
// Returns 0 on success, or a negative error code on error.
// 
// If blk != 0, set *blk to the address of the block in memory.
//
// Hint: Use diskaddr, map_block, and ide_read.
static int
read_block(uint32_t blockno, char **blk)
{
	int r;
	char *addr;

	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);

	// LAB 5: Your code here.
	r = map_block(blockno);
	if (r)
		return r;

	addr = diskaddr(blockno);
	r = ide_read(blockno * BLKSECTS, addr, BLKSECTS);
	if (r)
		return r;

	if (blk)
		*blk = addr;

	return sys_page_map(0, addr, 0, addr, vpt[VPN(addr)] & PTE_USER);
}
Exemple #10
0
// Sync the entire file system.  A big hammer.
void
fs_sync(void)
{
	int i;
	for (i = 1; i < super->s_nblocks; i++)
		flush_block(diskaddr(i));
}
Exemple #11
0
int
fs_rmdir(const char *path)
{
	struct inode *dir;
	struct dirent *dent;
	uint32_t nblock, i, j;
	char *blk;
	int r;

	if ((r = inode_open(path, &dir)) < 0)
		return r;
	if (dir == diskaddr(super->s_root))
		return -EPERM;
	if (!S_ISDIR(dir->i_mode))
		return -ENOTDIR;

	nblock = dir->i_size / BLKSIZE;
	for (i = 0; i < nblock; i++) {
		if ((r = inode_get_block(dir, i, &blk)) < 0)
			return r;
		dent = (struct dirent *)blk;
		for (j = 0; j < BLKDIRENTS; ++j)
			if (dent[j].d_name[0] != '\0')
				return -ENOTEMPTY;
	}
	return inode_unlink(path);
}
Exemple #12
0
Fichier : fs.c Projet : darfux/jos
// Make sure a particular disk block is loaded into memory.
// Returns 0 on success, or a negative error code on error.
// 
// If blk != 0, set *blk to the address of the block in memory.
//
// Hint: Use diskaddr, map_block, and ide_read.
static int
read_block(uint32_t blockno, char **blk)
{
	int r;
	char *addr;

	if (super && blockno >= super->s_nblocks)
		panic("reading non-existent block %08x\n", blockno);

	if (bitmap && block_is_free(blockno))
		panic("reading free block %08x\n", blockno);

	// LAB 5: Your code here.
	addr = diskaddr(blockno);
	int error = map_block(blockno);
	if(error<0) return error;

	int secno = blockno*BLKSECTS;
	error = ide_read(secno, addr, (size_t)BLKSECTS);
	if(error) return error;

	if(blk) *blk = addr;
	// panic("read_block not implemented");

	return 0;
}
Exemple #13
0
Fichier : fs.c Projet : darfux/jos
// 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.

	// We will use the VM hardware to keep track of whether a 
	// disk block has been modified since it was last read from 
	// or written to disk. To see whether a block needs writing, 
	// we can just look to see if the PTE_D "dirty" bit is set 
	// in the vpt entry.
	addr = diskaddr(blockno);
	if(!va_is_dirty(addr)) return;

	
	int error;
	int secno = blockno*BLKSECTS;
	error = ide_write(secno, addr, BLKSECTS);
	if(error<0) panic("write block error on writing");

	int env_id = sys_getenvid();
	error = sys_page_map(env_id, addr, 
		env_id, addr, ((PTE_U|PTE_P|PTE_W) & ~PTE_D));
	if(error<0) panic("write block error on clearing PTE_D");



	// panic("write_block not implemented");
}
Exemple #14
0
Fichier : fs.c Projet : MG47/JOS-MG
// Search the bitmap for a free block and allocate it.  When you
// allocate a block, immediately flush the changed bitmap block
// to disk.
//
// Return block number allocated on success,
// -E_NO_DISK if we are out of blocks.
//
// Hint: use free_block as an example for manipulating the bitmap.
int
alloc_block(void)
{
	// The bitmap consists of one or more blocks.  A single bitmap block
	// contains the in-use bits for BLKBITSIZE blocks.  There are
	// super->s_nblocks blocks in the disk altogether.

	// code for lab 5 -M.G
    //	panic("alloc_block not implemented");

    uint32_t i,j;
    for (i = 0; i < super->s_nblocks/32; i++)
    {
    	for (j = 0; j < 32; j++) 
        {
    	    uint32_t mark_bit = (1 << j);
    	    if (bitmap[i] & mark_bit) 
            {
        		bitmap[i] &= ~mark_bit;
        		flush_block(diskaddr((i * 32 | j)/BLKBITSIZE + 2));
        		return (i * 32) | j;
    	    }
	    }
    }
    return -E_NO_DISK;
}
Exemple #15
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.  
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
	// LAB 5: Your code here.
	//panic("file_block_walk not implemented");
	int result;

	if(filebno >= NDIRECT+NINDIRECT)
	{
		return -E_INVAL;
	}
	
	if(filebno < NDIRECT) 
	{
		if(ppdiskbno)
		{
			*ppdiskbno=(f->f_direct+filebno);
		}

		return 0;
	}

	if(!f->f_indirect && !alloc)
	{
		return -E_NOT_FOUND;
	}

	if(!f->f_indirect) 
	{
		if((result=alloc_block()) < 0)
		{
			return -E_NO_DISK;
		}

		f->f_indirect=result;
				
		memset(diskaddr(result), 0, BLKSIZE);
		flush_block(diskaddr(result));
	}
					
	if(ppdiskbno)
	{
		*ppdiskbno=(uint32_t *)diskaddr(f->f_indirect)+filebno-NDIRECT;
	}
			
	return 0;
}
Exemple #16
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{	
	// Lab 5 ex 4
	// LAB 5: Your code here.
	if(!f || !ppdiskbno)
		return -E_INVAL;
	int new_block;
	void *blk_addr;
	uint32_t * index;
	if(filebno >= (NDIRECT + NINDIRECT))
		return -E_INVAL;

	if(filebno < 10)
	{
		*ppdiskbno = &(f->f_direct[filebno]);
		return 0;
	}
	else
	{
		filebno -= 10;
		if(f->f_indirect)
		{
			blk_addr = diskaddr((uint64_t)(f->f_indirect));
			index = (uint32_t *) blk_addr;
		        *ppdiskbno = (index + filebno); 	
			return 0;
		}
		else
		{
			if(alloc == 0)
				return -E_NOT_FOUND;
			new_block = alloc_block();
			if(new_block == -E_NO_DISK)
				return -E_NO_DISK;
			f->f_indirect = (uint32_t)new_block;
			blk_addr = diskaddr((uint64_t)(f->f_indirect));
                        index = (uint32_t *) blk_addr;
                        *ppdiskbno = (index + filebno);
			return 0;			
		}	
	}
	
	//panic("file_block_walk not implemented");
}
Exemple #17
0
void
bc_init(void)
{
	struct Super super;
	set_pgfault_handler(bc_pgfault);

	// cache the super block by reading it once
	memmove(&super, diskaddr(1), sizeof super);
}
Exemple #18
0
static void print_block_list()
{
       cprintf("\n");
       cprintf("==============block usage list==============\n");
       int i;
       for (i=0; i<MAXBLK; ++i)
               if (plist[i].valid)
                    cprintf("+block at %x, used %d times, last used at time %d\n", diskaddr(i), plist[i].count, plist[i].tstamp);
       cprintf("++++++++++++++++++end list++++++++++++++++++\n");
}
Exemple #19
0
Fichier : fs.c Projet : MG47/JOS-MG
// Initialize the file system
void
fs_init(void)
{
	static_assert(sizeof(struct File) == 256);

       // Find a JOS disk.  Use the second IDE disk (number 1) if availabl
       if (ide_probe_disk1())
               ide_set_disk(1);
       else
               ide_set_disk(0);
	bc_init();

	// Set "super" to point to the super block.
	super = diskaddr(1);
	check_super();

	// Set "bitmap" to the beginning of the first bitmap block.
	bitmap = diskaddr(2);
	check_bitmap();
}
Exemple #20
0
Fichier : fs.c Projet : MG47/JOS-MG
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
       // code for lab 5-M.G
        //       panic("file_block_walk not implemented");

   	uint32_t new_block_no;

	if (filebno < NDIRECT) 
    {
		*ppdiskbno = &f->f_direct[filebno];
	}
    else if (filebno < (NDIRECT + NINDIRECT)) 
    {
		if (!f->f_indirect) 
        { 
			if (alloc == false)
            {
                return -E_NOT_FOUND;
            }
            else
            {        
            
			    if ((new_block_no = alloc_block()) < 0)
			    {
                	return -E_NO_DISK;
                }
            
			f->f_indirect = new_block_no;
			memset(diskaddr(new_block_no), 0, BLKSIZE);
            }
		} 
		*ppdiskbno = &((uintptr_t *) diskaddr(f->f_indirect))[filebno - NDIRECT];
	} 
    else 
    {
		return -E_INVAL;
    }

	return 0;
}
Exemple #21
0
// Find the disk block number slot for the 'filebno'th block in file 'f'.
// Set '*ppdiskbno' to point to that slot.
// The slot will be one of the f->f_direct[] entries,
// or an entry in the indirect block.
// When 'alloc' is set, this function will allocate an indirect block
// if necessary.
//
// Returns:
//	0 on success (but note that *ppdiskbno might equal 0).
//	-E_NOT_FOUND if the function needed to allocate an indirect block, but
//		alloc was 0.
//	-E_NO_DISK if there's no space on the disk for an indirect block.
//	-E_INVAL if filebno is out of range (it's >= NDIRECT + NINDIRECT).
//
// Analogy: This is like pgdir_walk for files.
// Hint: Don't forget to clear any block you allocate.
static int
file_block_walk(struct File *f, uint32_t filebno, uint32_t **ppdiskbno, bool alloc)
{
       // LAB 5: Your code here.
       // panic("file_block_walk not implemented");
	if (!f) panic("file not exist!\n");
	if (filebno >= NDIRECT + NINDIRECT) return -E_INVAL;
	if (filebno < NDIRECT) {
		*ppdiskbno = &(f->f_direct[filebno]);
		return 0;
	}
	if (!f->f_indirect) {
		if (!alloc) return -E_NOT_FOUND;
		int n;
		if ((n = alloc_block()) < 0) return n;
		f->f_indirect = n;
		memset(diskaddr(n), 0, BLKSIZE);
	}
	*ppdiskbno =  (uint32_t*)(diskaddr(f->f_indirect) + 4 * (filebno - NDIRECT));
	return 0;
}
Exemple #22
0
int
main(int argc, char **argv)
{
	struct fuse_args args = FUSE_ARGS_INIT(0, NULL);
	const char *imgname = NULL, *mntpoint = NULL;
	char fsname_buf[17 + PATH_MAX];
	int r, fd;

	fuse_opt_add_arg(&args, argv[0]);
	if (argc < 2)
		panic("missing image or mountpoint parameter, see help");
	for (r = 1; r < argc; r++) {
		if (imgname == NULL && argv[r][0] != '-' && strcmp(argv[r - 1], "-o") != 0) {
			imgname = argv[r];
		} else if(mntpoint == NULL && argv[r][0] != '-' && strcmp(argv[r - 1], "-o") != 0) {
			mntpoint = argv[r];
			fuse_opt_add_arg(&args, argv[r]);
		} else {
			fuse_opt_add_arg(&args, argv[r]);
		}
	}

	// Use a fsname (which shows up in df) in the style of sshfs, another
	// FUSE-based file system, with format "fsname#fslocation".
	snprintf(fsname_buf, sizeof(fsname_buf), "-ofsname=CS202fs#%s", imgname);
	fuse_opt_add_arg(&args, "-s"); // Always run single-threaded.
	fuse_opt_add_arg(&args, "-odefault_permissions"); // Kernel handles access.
	fuse_opt_add_arg(&args, fsname_buf); // Set the filesystem name.

	if (imgname == NULL) {
		fuse_opt_parse(&args, NULL, fs_opts, fs_parse_opt);
		return -1;
	} else {
		struct inode *dirroot;

		map_disk_image(imgname, mntpoint);

		// Make sure the superblock fields are sane.
		assert(super->s_magic == FS_MAGIC);
		assert(super->s_root != 0);

		// Guarantee that the root directory has proper permissions.
		// This is vital so that we can unmount the disk.
		dirroot = diskaddr(super->s_root);
		dirroot->i_mode = S_IFDIR | 0777;

		fuse_opt_parse(&args, NULL, fs_opts, fs_parse_opt);
		return fuse_main(args.argc, args.argv, &fs_oper, NULL);
	}
}
Exemple #23
0
// Make sure this block is unmapped.
void
unmap_block(uint32_t blockno)
{
	int r;

	if (!block_is_mapped(blockno))
		return;

	assert(block_is_free(blockno) || !block_is_dirty(blockno));

	if ((r = sys_page_unmap(0, diskaddr(blockno))) < 0)
		panic("unmap_block: sys_mem_unmap: %e", r);
	assert(!block_is_mapped(blockno));
}
Exemple #24
0
int
fs_chmod(const char *path, mode_t mode)
{
	struct inode *ino;
	int r;

	if ((r = inode_open(path, &ino)) < 0)
		return r;
	if (ino == diskaddr(super->s_root))
		return -EPERM;
	ino->i_mode = mode;
	ino->i_ctime = time(NULL);
	flush_block(ino);

	return 0;
}
Exemple #25
0
// Allocate a block -- first find a free block in the bitmap,
// then map it into memory.
int
alloc_block(void)
{
	int r, bno;

	if ((r = alloc_block_num()) < 0)
		return r;
	bno = r;

	if ((r = map_block(bno)) < 0) {
		free_block(bno);
		return r;
	}
	memset(diskaddr(bno), 0, BLKSIZE);
	return bno;
}
Exemple #26
0
// Set *blk to the address in memory where the filebno'th
// block of file 'f' would be mapped.
//
// Returns 0 on success, < 0 on error.  Errors are:
//	-E_NO_DISK if a block needed to be allocated but the disk is full.
//	-E_INVAL if filebno is out of range.
//
// Hint: Use file_block_walk and alloc_block.
int
file_get_block(struct File *f, uint32_t filebno, char **blk)
{
       // LAB 5: Your code here.
    int r;
    uint32_t *ppdiskbno;
    if ((r = file_block_walk(f, filebno, &ppdiskbno, 1)) < 0)
        return r;
    if (!*ppdiskbno)
    {
        if ((r = alloc_block()) < 0) 
            return r;
        *ppdiskbno = r;
    }
    *blk = (char *) diskaddr(*ppdiskbno);
    return 0;
}
Exemple #27
0
Fichier : fs.c Projet : scau/JOS
// Set *blk to the address in memory where the filebno'th
// block of file 'f' would be mapped.
//
// Returns 0 on success, < 0 on error.  Errors are:
//	-E_NO_DISK if a block needed to be allocated but the disk is full.
//	-E_INVAL if filebno is out of range.
//
int
file_get_block(struct File *f, uint32_t filebno, char **blk)
{
	if (filebno >= NDIRECT + NINDIRECT) {
		return -E_INVAL;
	}
	uint32_t *ppdiskbno;
	int r = file_block_walk(f, filebno, &ppdiskbno, false);
	if (r < 0)
		return r;
    if (!*ppdiskbno)
        return -E_NO_DISK;
	*blk = (char*)diskaddr(*ppdiskbno);
	return 0;
	// LAB 5: Your code here.
	//panic("file_block_walk not implemented");
}
Exemple #28
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)
{
	int r;
	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 ((r = ide_write(blockno * BLKSECTS, addr, BLKSECTS)) < 0)
		panic("write_block: ide_write failed: %e.\n", r);
	if ((r = sys_page_map(0, addr, 0, addr, PTE_USER)) < 0)
		panic("write_block: sys_page_map failed: %e.\n", r);
}
Exemple #29
0
// Search the bitmap for a free block and allocate it.  When you
// allocate a block, immediately flush the changed bitmap block
// to disk.
// 
// Return block number allocated on success,
// -E_NO_DISK if we are out of blocks.
//
// Hint: use free_block as an example for manipulating the bitmap.
int
alloc_block(void)
{
	// The bitmap consists of one or more blocks.  A single bitmap block
	// contains the in-use bits for BLKBITSIZE blocks.  There are
	// super->s_nblocks blocks in the disk altogether.

	// LAB 5: Your code here.
	uint32_t blockno;
	for(blockno = 1; blockno < super->s_nblocks; blockno++)
		if(block_is_free(blockno))
		{
			bitmap[blockno/32] ^= (1<<(blockno%32));
			flush_block(diskaddr(2));
			assert(!block_is_free(blockno));
			return blockno;
		}
	return -E_NO_DISK;
}
Exemple #30
0
int
fs_chown(const char *path, uid_t uid, gid_t gid)
{
	struct inode *ino;
	int r;

	if ((r = inode_open(path, &ino)) < 0)
		return r;
	if (ino == diskaddr(super->s_root))
		return -EPERM;
	if (uid != -1)
		ino->i_owner = uid;
	if (gid != -1)
		ino->i_group = gid;
	ino->i_ctime = time(NULL);
	flush_block(ino);

	return 0;
}