예제 #1
0
파일: test.c 프로젝트: evilzone/CSE506
void
fs_test(void)
{
	struct File *f;
	int r;
	char *blk;
	uint32_t *bits;

	// back up bitmap
	if ((r = sys_page_alloc(0, (void*) PGSIZE, PTE_P|PTE_U|PTE_W)) < 0)
		panic("sys_page_alloc: %e", r);
	bits = (uint32_t*) PGSIZE;
	memmove(bits, bitmap, PGSIZE);
	// allocate block
	if ((r = alloc_block()) < 0)
		panic("alloc_block: %e", r);
	// check that block was free
	assert(bits[r/32] & (1 << (r%32)));
	// and is not free any more
	assert(!(bitmap[r/32] & (1 << (r%32))));
	cprintf("alloc_block is good\n");

	if ((r = file_open("/not-found", &f)) < 0 && r != -E_NOT_FOUND)
		panic("file_open /not-found: %e", r);
	else if (r == 0)
		panic("file_open /not-found succeeded!");
	if ((r = file_open("/newmotd", &f)) < 0)
		panic("file_open /newmotd: %e", r);
	cprintf("file_open is good\n");

	if ((r = file_get_block(f, 0, &blk)) < 0)
		panic("file_get_block: %e", r);
	if (strcmp(blk, msg) != 0)
		panic("file_get_block returned wrong data");
	cprintf("file_get_block is good\n");

	*(volatile char*)blk = *(volatile char*)blk;
	assert((vpt[PPN(blk)] & PTE_D));
	file_flush(f);
	assert(!(vpt[PPN(blk)] & PTE_D));
	cprintf("file_flush is good\n");

	if ((r = file_set_size(f, 0)) < 0)
		panic("file_set_size: %e", r);
	assert(f->f_direct[0] == 0);
	assert(!(vpt[PPN(f)] & PTE_D));
	cprintf("file_truncate is good\n");

	if ((r = file_set_size(f, strlen(msg))) < 0)
		panic("file_set_size 2: %e", r);
	assert(!(vpt[PPN(f)] & PTE_D));
	if ((r = file_get_block(f, 0, &blk)) < 0)
		panic("file_get_block 2: %e", r);
	strcpy(blk, msg);
	assert((vpt[PPN(blk)] & PTE_D));
	file_flush(f);
	assert(!(vpt[PPN(blk)] & PTE_D));
	assert(!(vpt[PPN(f)] & PTE_D));
	cprintf("file rewrite is good\n");
}
예제 #2
0
파일: fs.c 프로젝트: reddragon/cse506
// Set *file to point at a free File structure in dir.  The caller is
// responsible for filling in the File fields.
static int
dir_alloc_file(struct File *dir, struct File **file)
{
	int r;
	uint32_t nblock, i, j;
	char *blk;
	struct File *f;

	assert((dir->f_size % BLKSIZE) == 0);
	nblock = dir->f_size / BLKSIZE;
	for (i = 0; i < nblock; i++) {
		if ((r = file_get_block(dir, i, &blk)) < 0)
			return r;
		f = (struct File*) blk;
		for (j = 0; j < BLKFILES; j++)
			if (f[j].f_name[0] == '\0') {
				*file = &f[j];
				return 0;
			}
	}
	dir->f_size += BLKSIZE;
	if ((r = file_get_block(dir, i, &blk)) < 0)
		return r;
	f = (struct File*) blk;
	*file = &f[0];
	return 0;
}
예제 #3
0
파일: fs.c 프로젝트: reddragon/cse506
// Read count bytes from f into buf, starting from seek position
// offset.  This meant to mimic the standard pread function.
// Returns the number of bytes read, < 0 on error.
ssize_t
file_read(struct File *f, void *buf, size_t count, off_t offset)
{
	//cprintf("In file_read %x %x \n", count, offset);
	int r, bn;
	off_t pos;
	char *blk;

	if (offset >= f->f_size)
		return 0;

	count = MIN(count, f->f_size - offset);

	for (pos = offset; pos < offset + count; ) {
		//cprintf("In file_read %x\n", pos);
		if ((r = file_get_block(f, pos / BLKSIZE, &blk)) < 0)
			return r;
		//cprintf("\t\t\t\t\tfile_read : blk : %x\n", blk);
		bn = MIN(BLKSIZE - pos % BLKSIZE, offset + count - pos);
		memmove(buf, blk + pos % BLKSIZE, bn);
		pos += bn;
		buf += bn;
	}

	return count;
}
예제 #4
0
파일: fs.c 프로젝트: reddragon/cse506
// Try to find a file named "name" in dir.  If so, set *file to it.
//
// Returns 0 and sets *file on success, < 0 on error.  Errors are:
//	-E_NOT_FOUND if the file is not found
static int
dir_lookup(struct File *dir, const char *name, struct File **file)
{
	int r;
	uint32_t i, j, nblock;
	char *blk;
	struct File *f;

	// Search dir for name.
	// We maintain the invariant that the size of a directory-file
	// is always a multiple of the file system's block size.
	assert((dir->f_size % BLKSIZE) == 0);
	nblock = dir->f_size / BLKSIZE;
	for (i = 0; i < nblock; i++) {
		if ((r = file_get_block(dir, i, &blk)) < 0)
			return r;
		f = (struct File*) blk;
		for (j = 0; j < BLKFILES; j++)
			if (strcmp(f[j].f_name, name) == 0) {
				*file = &f[j];
				return 0;
			}
	}
	return -E_NOT_FOUND;
}
예제 #5
0
파일: fs.c 프로젝트: ChenLanbo/OS-Lab
// Read count bytes from f into buf, starting from seek position
// offset.  This meant to mimic the standard pread function.
// Returns the number of bytes read, < 0 on error.
ssize_t
file_read(struct File *f, void *buf, size_t count, off_t offset)
{
	int r, bn;
	off_t pos;
	char *blk;
	// void *org = buf;

	if (offset >= f->f_size)
		return 0;

	count = MIN(count, f->f_size - offset);

	for (pos = offset; pos < offset + count; ) {
		if ((r = file_get_block(f, pos / BLKSIZE, &blk)) < 0)
			return r;
		bn = MIN(BLKSIZE - pos % BLKSIZE, offset + count - pos);
		memmove(buf, blk + pos % BLKSIZE, bn);
		pos += bn;
		buf += bn;
	}
	/*if (count > 4){
		cprintf("fs/fs.c get %d bytes %x: ", count, org);
		for (r = 0; r < 16; r++){
			cprintf("%02x ", ((unsigned char *)org)[r]);
		}
		cprintf("\n");
	}*/
	
	return count;
}
예제 #6
0
파일: serv.c 프로젝트: SivilTaram/Jos-mips
void
serve_map(u_int envid, struct Fsreq_map *rq)
{
	if (debug) {
		writef("serve_map %08x %08x %08x\n", envid, rq->req_fileid, rq->req_offset);
	}

	struct Open *pOpen;

	u_int filebno;

	void *blk;

	int r;

	// Your code here
	if ((r = open_lookup(envid, rq->req_fileid, &pOpen)) < 0) {
		ipc_send(envid, r, 0, 0);
		return;
	}

	filebno = rq->req_offset / BY2BLK;

	if ((r = file_get_block(pOpen->o_file, filebno, &blk)) < 0) {
		ipc_send(envid, r, 0, 0);
		return;
	}

	ipc_send(envid, 0, (u_int)blk, PTE_V | PTE_R | PTE_LIBRARY);
	return;
	//	user_panic("serve_map not implemented");
}
예제 #7
0
파일: serv.c 프로젝트: yaobaiwei/JOS
void
serve_map(envid_t envid, struct Fsreq_map *rq)
{
	int r;
	char *blk;
	struct OpenFile *o;
	int perm;

	if (debug)
		cprintf("serve_map %08x %08x %08x\n", envid, rq->req_fileid, rq->req_offset);

	// Map the requested block in the client's address space
	// by using ipc_send.
	// Map read-only unless the file's open mode (o->o_mode) allows writes
	// (see the O_ flags in inc/lib.h).
	
	// LAB 5: Your code here.
	if ((r = openfile_lookup(envid, rq->req_fileid, &o)) < 0)
		goto out;

    if ((r = file_get_block(o->o_file, rq->req_offset/BLKSIZE, &blk)) < 0)
        goto out;
    
    if(o->o_mode & O_RDONLY)
        ipc_send(envid, 0, (void *)blk, PTE_P|PTE_U);
    else
        ipc_send(envid, 0, (void *)blk, PTE_P|PTE_U|PTE_W);

    return;

out:
	ipc_send(envid, r, 0, 0);
	//panic("serve_map not implemented");
}
예제 #8
0
// Map the requested block in the client's address space
// by using ipc_send.
void
serve_map(envid_t envid, struct Fsreq_map *rq)
{
	int r;
	char *blk = NULL;
	struct OpenFile *o;
	int perm = 0;

	if (debug)
		cprintf("serve_map %08x %08x %08x\n", envid, rq->req_fileid, rq->req_offset);

	if ((r = openfile_lookup(envid, rq->req_fileid, &o)) < 0)
		goto out;

	// Map read-only unless the file's open mode (o->o_mode) allows writes
	// (see the O_ flags in inc/lib.h).
        perm = PTE_U | PTE_P | PTE_SHARE;
        if (o->o_mode & (O_WRONLY|O_RDWR))
          perm |= PTE_W;
        
	r = file_get_block(o->o_file, rq->req_offset/BLKSIZE, &blk);

out:
	ipc_send(envid, r, blk, perm);
}
예제 #9
0
파일: fs.c 프로젝트: ren85/jos2006
// Mark the offset/BLKSIZE'th block dirty in file f
// by writing its first word to itself.  
int
file_dirty(struct File *f, off_t offset)
{
	int r;
	char *blk;

	if ((r = file_get_block(f, offset/BLKSIZE, &blk)) < 0)
		return r;
	*(volatile char*)blk = *(volatile char*)blk;
	return 0;
}
int	file_data_write(struct File *f, char *buf, size_t count, int block_no)
{
    int err;
	int pblk, hash_addr;
	int addr;
	int hash_second_table_addr;
	int second_table_offset;
	int flag = 0;
	uint32_t hash = generate_hash(buf, BLKSIZE);

    int hash_first_table_addr = HashBlock_Start + (hash & HashLowBits);

    fseek(fp,hash_first_table_addr,SEEK_SET);
    fread(&addr, sizeof(int), 1, fp);

    if(addr == 0)
    {

    	if(alloc_block(&hash_addr) < 0)
    	{
        	printf("\n error in block allocation for write");
        	return -1;
    	}
    	fseek(fp,hash_first_table_addr,SEEK_SET);
    	fwrite(&hash_addr, sizeof(int), 1, fp);
    	flush_block(hash_addr);

    	if((err = file_get_block(f, block_no, &pblk)) < 0)
    	{
    		printf("\n error in getting block for write");
    		return -1;
    	}
    	flush_block(pblk);
    	fseek(fp,pblk,SEEK_SET);
    	fwrite(buf, count, 1, fp);

    	f->f_size += count;
    	f->f_written += count;
    	f->n_blocks += 1;
    	super->total_blocks+=1;
    	super->written_blocks+=1;

    	second_table_offset = (hash & HashHighBits) >> 25;
    	hash_second_table_addr = (int)((int *)hash_addr + second_table_offset);

    	fseek(fp,hash_second_table_addr,SEEK_SET);
    	fwrite(&pblk, sizeof(int), 1, fp);

    }
    else
    {
예제 #11
0
void
serve_map(u_int envid, struct Fsreq_map *rq)
{
    struct Open *o;
    void *blk;
    int r = 0;
	if (debug) printf("serve_map %08x %08x %08x\n", envid, rq->req_fileid, rq->req_offset);
    if((r = open_lookup(envid, rq->req_fileid, &o)) < 0)
        goto out_map;
    if((r = file_get_block(&o->o_ff->f_file, rq->req_offset/BY2BLK, &blk)) < 0)
        goto out_map;
    ipc_send(envid, 0, (u_long)blk, PTE_P|PTE_U|PTE_W|PTE_LIBRARY);
    return;
out_map:
    ipc_send(envid, r, 0, 0);
	// Your code here
	// panic("serve_map not implemented");
}
예제 #12
0
파일: fs.c 프로젝트: reddragon/cse506
// Write count bytes from buf into f, starting at seek position
// offset.  This is meant to mimic the standard pwrite function.
// Extends the file if necessary.
// Returns the number of bytes written, < 0 on error.
int
file_write(struct File *f, const void *buf, size_t count, off_t offset)
{
	int r, bn;
	off_t pos;
	char *blk;

	// Extend file if necessary
	if (offset + count > f->f_size)
		if ((r = file_set_size(f, offset + count)) < 0)
			return r;

	for (pos = offset; pos < offset + count; ) {
		if ((r = file_get_block(f, pos / BLKSIZE, &blk)) < 0)
			return r;
		bn = MIN(BLKSIZE - pos % BLKSIZE, offset + count - pos);
		memmove(blk + pos % BLKSIZE, buf, bn);
		pos += bn;
		buf += bn;
	}

	return count;
}
예제 #13
0
파일: serv.c 프로젝트: ichaos/jos
void
serve_map(envid_t envid, struct Fsreq_map *rq)
{
	int r;
	char *blk;
	struct OpenFile *o;
	int perm = PTE_U | PTE_P | PTE_AVAIL;
        uint32_t *pdiskbno;

	if (debug)
		cprintf("serve_map %08x %08x %08x\n", envid,
                        rq->req_fileid, rq->req_offset);

	// Map the requested block in the client's address space
	// by using ipc_send.
	// Map read-only unless the file's open mode (o->o_mode) allows writes
	// (see the O_ flags in inc/lib.h).

	// LAB 5: Your code here.
        r = openfile_lookup(envid, rq->req_fileid, &o);
        if (r<0) {
                cprintf("serv.c:serve_map--openfile_lookup failed.\n");
                ipc_send(envid, r, 0, 0);
                return;
        }
        r = file_get_block(o->o_file, rq->req_offset, &blk);
        if (r<0) {
                cprintf("serv.c:serve_map--file_get_walk failed.\n");
                goto out;
        }
        if (o->o_mode&O_RDWR) {//what happens if O_WRONLY?
                perm = PTE_USER;
        }
 out:
        ipc_send(envid, r, blk, perm);
	//panic("serve_map not implemented");
}