Пример #1
0
static s64_t sbp_read_or_write(s64_t fd, void* buf, u64_t len, char* method) {
	if (fds[fd] == NULL)
		return -1;
	char tran_fd[32];
	char tran_offset[32];
	char tran_len[32];
	s64_t ret = -1;
	SBP_PREPARE_REQUEST
	sprintf(tran_fd, "%lld", fds[fd]->server_fd);
	sprintf(tran_offset, "%lld", fds[fd]->offset);
	sprintf(tran_len, "%lld", len);
	mkent(head,METHOD,method);
	mkent(head,ARGC,"3");
	mkent(head,"Arg0",tran_fd);
	mkent(head,"Arg1",tran_offset);
	mkent(head,"Arg2",tran_len);
	mkent(head,CONTENT_LEN,"0");

	SBP_SEND_AND_PROCESS_REPLY

	if (strncmp(head.title, REQUEST_OK, strlen(REQUEST_OK)) == 0) {
		u64_t content_l = -1;
		char* value = get_head_entry_value(&head, CONTENT_LEN);
		if (value == NULL) {
			seterr(HEAD_ERR,NO_CONTENT_LEN);
			goto err_exit3;
		}
		content_l = atoll(value);
		if (content_l % sizeof(struct block_entry)) {
			printf("content l :%lld :%ld\n", content_l,
					sizeof(struct block_entry));
			seterr(DATA_ERR,DATA_LEN);
			goto err_exit3;
		}
		u64_t block_ent_num = content_l / sizeof(struct block_entry);
		struct block_entry* ents = (struct block_entry*) (rec_data
				+ head.head_len);
		if (strcmp(method, "WRITE") == 0) {
			ret = write_blocks(ents, block_ent_num, buf, fds[fd]->auth_code);
		} else if (strcmp(method, "READ") == 0) {
			ret = read_blocks(ents, block_ent_num, buf, fds[fd]->auth_code);
		}
		if (ret >= 0){

			fds[fd]->offset += ret;
			//printf("fds offset :%lld\n",fds[fd]->offset);
		}
		goto ok_exit;
	} else if (strncmp(head.title, REQUEST_ERR, strlen(REQUEST_ERR)) == 0) {
		sbp_update_err(&head);
		goto err_exit3;
	} else {
		seterr(HEAD_ERR, UNKNOWN_HEAD);
	}

	err_exit3: free_head(&head);
	err_exit2: free(rec_data);
	err_exit1: free(data);
	err_exit: free(usr);
	free(pass);

	return ret;
	ok_exit: free(data);
	free(rec_data);
	free_head(&head);
	free(usr);
	free(pass);

	return ret;

}
Пример #2
0
/* returns negative value on error 
 file is name of the disk that was given to testfs.
 this function initializes all the in memory data structures maintained by the sb
 block.
 */
int testfs_init_super_block(const char *file, int corrupt,
		struct super_block **sbp) {
	struct super_block *sb = malloc(sizeof(struct super_block));
	char block[BLOCK_SIZE];
	int ret, sock;

	if (!sb) {
		return -ENOMEM;
	}

	if ((sock = open(file, O_RDWR
#ifndef DISABLE_OSYNC
			| O_SYNC
#endif
			)) < 0) {
		return errno;
	} else if ((sb->dev = fdopen(sock, "r+")) == NULL) {
		return errno;
	}

	// sb->dev type = FILE
	// read from sb into block.
	read_blocks(sb, block, 0, 1);
	// copy only 24 bytes from block corresponding to dsuper_block
	_memcpy(&sb->sb, block, sizeof(struct dsuper_block));

	// 64 * 1 * 8
	// bitmap create will return a inode_bitmap structure.
	// and point sb->inode_freemap to that structure.
	// currently the inode bitmap is all 0.
	// at the end of this function, bitmap is created in memory 
	ret = bitmap_create(BLOCK_SIZE * INODE_FREEMAP_SIZE * BITS_PER_WORD,
			&sb->inode_freemap);
	if (ret < 0)
		return ret;
	// bitmap_getdata returns v -> the byte array containing bit info
	// read_blocks reads sb->v into sb at offset freemap_start till 
	// INODE_FREEMAP_SIZE
	// sb is only sent to read_blocks since we need the sb device handle.
	// data from sb->dev is used to populate arg 2  sb->inode_freemap
	read_blocks(sb, bitmap_getdata(sb->inode_freemap),
			sb->sb.inode_freemap_start, INODE_FREEMAP_SIZE);

	ret = bitmap_create(BLOCK_SIZE * BLOCK_FREEMAP_SIZE * BITS_PER_WORD,
			&sb->block_freemap);
	if (ret < 0)
		return ret;
	read_blocks(sb, bitmap_getdata(sb->block_freemap),
			sb->sb.block_freemap_start, BLOCK_FREEMAP_SIZE);
	sb->csum_table = malloc(CSUM_TABLE_SIZE * BLOCK_SIZE);
	if (!sb->csum_table)
		return -ENOMEM;
	read_blocks(sb, (char *) sb->csum_table, sb->sb.csum_table_start,
	CSUM_TABLE_SIZE);
	sb->tx_in_progress = TX_NONE;
	/*
	 inode_hash_init() initializes inode_hash_table of size 256 bytes
	 each entry of the inode table contains a first pointer. each
	 node of the first pointer has a prev pointer and a next pointer.
	 */
	inode_hash_init();
	*sbp = sb;

	return 0;
}
Пример #3
0
/* given logical block number, read the corresponding physical block into block.
 * return physical block number.
 * returns 0 if physical block does not exist.
 * returns negative value on other errors. */
 static int
 testfs_read_block(struct inode *in, int log_block_nr, char *block)
 {
 	//printf("log_block_nr:%d\n",log_block_nr);
 	int phy_block_nr = 0;
 	assert(log_block_nr >= 0);

 	// when log block number is less 0~9
 	if (log_block_nr < NR_DIRECT_BLOCKS) {
 		phy_block_nr = (int)in->in.i_block_nr[log_block_nr];
 	}

 	else {
 		log_block_nr -= NR_DIRECT_BLOCKS;

 		if (log_block_nr >= NR_INDIRECT_BLOCKS)
 		{
 			//need to implement DID part, not done yet.
 			if (in->in.i_dindirect > 0)
 			{
 	 		log_block_nr -= NR_INDIRECT_BLOCKS; //log block ranges from 0 ~ 4194303

 	 		int level1_block = DIVROUNDUP(log_block_nr + 1,2048) - 1;   // ranges 0~2047

	 		int level2_block= log_block_nr % 2048;


	 		read_blocks(in->sb, block, in->in.i_dindirect, 1);

	 		
	 		if (((int*)block)[level1_block]!=0)
	 		{
	 			read_blocks(in->sb, block, ((int*)block)[level1_block], 1);

	 			if (((int*)block)[level2_block]!=0)
	 			{
	 				phy_block_nr = ((int *)block)[level2_block];
	 				read_blocks(in->sb, block, phy_block_nr, 1);
	 				return phy_block_nr;	
	 			}

	 		}
	 	}
	 	return phy_block_nr;
	 	}

	 if (in->in.i_indirect > 0) {
	 	read_blocks(in->sb, block, in->in.i_indirect, 1);
	 	phy_block_nr = ((int *)block)[log_block_nr];
	 }
	}

	if (phy_block_nr > 0) {
		read_blocks(in->sb, block, phy_block_nr, 1);
	} else {

		/* we support sparse files by zeroing out a block that is not
		 * allocated on disk. */
		bzero(block, BLOCK_SIZE);
	}
	return phy_block_nr;
}
Пример #4
0
void sfs_write(int fd, char *buf, int length){
	int i;
        int position = 0;
        int maxLength;
	int apendLength;
        int FATi;
	int currFATi;
	int newBlock;

	writeLength = length;
	currmyfile = fd;
	writeBuff = (char *) malloc(length);
	appendBuff = (char *) malloc(1024 + length);
        for(i=0; i < writeLength; i++){
		writeBuff[i] = buf[i];
	}
	writeBuff[writeLength] = 0;
        myfile = directory[FDT[currmyfile].dirIndex];
	rootFAT = myfile.indFAT;
	currFATi = rootFAT;
        for(i=0; i < 1024; i++){//get last block in myfile
            if(FDT[currmyfile].write - position > 1024){
		position = position + 1024;
		currFATi = FAT[currFATi][1];
            }

	}
	read_blocks(FAT[currFATi][0], 1, appendBuff);
	appendBuff[FDT[currmyfile].write - position] = 0;
	maxLength = FDT[currmyfile].write + writeLength;
	strcat(appendBuff, writeBuff);
	apendLength = FDT[currmyfile].write - position + writeLength;
	appendBuff[apendLength] = 0; 

	for(i=0; i < apendLength;i++){
            if(apendLength - 1024 <= 0){
		write_blocks(FAT[currFATi][0],1,appendBuff);
		FAT[currFATi][1] = EOF; 
            }
            else{
                write_blocks(FAT[currFATi][0],1,appendBuff);
		appendBuff = appendBuff + 1024;
		apendLength = apendLength - 1024;
		newBlock = searchBlockSpace();
		FATi = searchFAT();
		if(newBlock > 0){
                    FAT[currFATi][1] = FATi;
                    FAT[FATi][0] = newBlock;
                    FAT[FATi][1] = EOF;
                    free_list[newBlock] = '1';
                    currFATi = FATi;
                }
		else{
                    error = 1;
		}
            }
	}
	if(error != 1){
            FDT[currmyfile].write = maxLength;
            directory[FDT[fd].dirIndex].date = time(NULL);
            directory[FDT[fd].dirIndex].size = directory[FDT[fd].dirIndex].size + length;
            updateDisk();
            free(writeBuff);
            free(appendBuff);
            printf("Data writing successfull\n");
	}
	else{
            printf("ERROR!!!--end of free blocks\n");
        }

}
Пример #5
0
int sfs_fwrite(int fileID, const char *buf, int length){

	int inode_index = dir_table[fileID].inode_number;
	int num_bytes_to_be_written=0;
	
	//index of rw pointers which points to the current block of inode
	int rw_index = file_des_t[fileID].rw_pointer/BLOCKSIZE+1; 
	//rw pointer offset within its current block
	int rw_offset = file_des_t[fileID].rw_pointer%BLOCKSIZE; 
	//calculate number of blocks to be written
	int num_blocks;
	if(length<BLOCKSIZE-rw_offset){
		num_blocks=1;
	}
	else{
		num_blocks=(length-(BLOCKSIZE-rw_offset))/BLOCKSIZE+2; //+2 for the first & last partial blocks
	}

	//writing to an empty file.
	if(inodes[inode_index].pointers[0]==0){
	//If file is empty all inode pointers will be zero 
	int num_bytes_to_be_written = 0;
	int inode_index=dir_table[fileID].inode_number;
	int num_blocks=length/(BLOCKSIZE)+1;
	
		if(num_blocks<=(INODE_POINTERS-1)){ 
			//don't need the indirect pointer
			int j;
			char write_block_buffer[BLOCKSIZE];
			for(j=0;j<num_blocks-1;j++){
				//reset buffer
				memset(write_block_buffer,0,BLOCKSIZE); 
				memcpy(write_block_buffer,buf,BLOCKSIZE); 
				inodes[inode_index].pointers[j]=findfreeblock();
				
				int flag = write_blocks(inodes[inode_index].pointers[j],1,write_block_buffer);
				if(flag){ 
				//if write into disk successfully,count the number of bytes written
					num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE;
				}
				//upodate the bitmap
				markfreeblock(inodes[inode_index].pointers[j]);
			}
			
			//last block could be a partial block
			char direct_pointer_buf_last[BLOCKSIZE];
			memset(direct_pointer_buf_last,0,BLOCKSIZE);
			memcpy(direct_pointer_buf_last, buf+(num_blocks-1)*BLOCKSIZE, length % BLOCKSIZE);
			//find a free block for the last direct pointer
			int last_direct_pointer = findfreeblock();
			markfreeblock(last_direct_pointer);
			inodes[inode_index].pointers[num_blocks-1] = last_direct_pointer;
			//if write into disk successfully then count the number of bytes
			int flag = write_blocks(last_direct_pointer,1,direct_pointer_buf_last);
			if(flag){
				num_bytes_to_be_written = num_bytes_to_be_written + length%BLOCKSIZE;
			}
			//update the information in file descriptor table
			file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + length;
			inodes[inode_index].size = inodes[inode_index].size + num_bytes_to_be_written;
			
			//update info on the disk
			int inode_number = inode_index;
			int block_of_inode=inode_number/8+1; 
			char inode_update_buf[BLOCKSIZE];
			memset(inode_update_buf,0, BLOCKSIZE);
			read_blocks(block_of_inode, 1, inode_update_buf);
			memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE));
			write_blocks(block_of_inode, 1, inode_update_buf);	
			write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap);
			return num_bytes_to_be_written;
		}
		else{	
				//else need the indirect pointer
				int m;
				char write_block_buffer[BLOCKSIZE];
				//handle all the direct pointer firstly,similar as the above 
				for(m=0;m<INODE_POINTERS-1;m++){
				memset(write_block_buffer,0,BLOCKSIZE); 
				memcpy(write_block_buffer,buf,BLOCKSIZE); 
				inodes[inode_index].pointers[m]=findfreeblock();
				int flag=write_blocks(inodes[inode_index].pointers[m],1,write_block_buffer);
				if(flag){num_bytes_to_be_written+=BLOCKSIZE;}
				markfreeblock(inodes[inode_index].pointers[m]);
			}
			//now let's handle the indirect pointer
			int num_indirect_pointers = num_blocks-(INODE_POINTERS-1);
			//get free blocks for indirect pointer
			int freeblock_indirect = findfreeblock(); 
			markfreeblock(freeblock_indirect);
			int arr_of_indirectptr[num_indirect_pointers];
			int k;
			//write the remaining data to the indirect blocks
			char indirect_pointer_buf[BLOCKSIZE];
			for(k=0;k<num_indirect_pointers-1;k++){
				arr_of_indirectptr[k] = findfreeblock();
				memset(indirect_pointer_buf,0,BLOCKSIZE);
				memcpy(indirect_pointer_buf, buf+(INODE_POINTERS-1)*BLOCKSIZE + k*BLOCKSIZE, BLOCKSIZE);
				int flag=write_blocks(arr_of_indirectptr[k],1,indirect_pointer_buf);
				if(flag){num_bytes_to_be_written+=BLOCKSIZE;}
				markfreeblock(arr_of_indirectptr[k]);
			}
			//handle partial indirect block
			int last_indirect_pointers = findfreeblock();
			arr_of_indirectptr[num_indirect_pointers-1] = last_indirect_pointers;
			markfreeblock(last_indirect_pointers);
			char last_indirect_pointer_buf[BLOCKSIZE];
			memset(last_indirect_pointer_buf,0,BLOCKSIZE);
			memcpy(last_indirect_pointer_buf,buf+(INODE_POINTERS-1)*BLOCKSIZE+(num_indirect_pointers-1)*BLOCKSIZE,length%BLOCKSIZE);
			int flag = write_blocks(arr_of_indirectptr[num_indirect_pointers-1],1,last_indirect_pointer_buf);
			if(flag){
				num_bytes_to_be_written = num_bytes_to_be_written + length%BLOCKSIZE;
			}
			
			//Write the indirect pointers to the indirect block
			char indirect_buffer[BLOCKSIZE];
			memset(indirect_buffer,0,BLOCKSIZE);
			memcpy(indirect_buffer,arr_of_indirectptr,num_indirect_pointers*sizeof(int));
			write_blocks(freeblock_indirect,1,indirect_buffer); 
			inodes[inode_index].pointers[INODE_POINTERS-1]=freeblock_indirect;
			file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + length;
			inodes[inode_index].size = inodes[inode_index].size + num_bytes_to_be_written;
			
			//update all the info into the disk
			int inode_number = inode_index;
			int block_of_inode = inode_number/8+1; 
			char inode_update_buf[BLOCKSIZE];
			memset(inode_update_buf,0, BLOCKSIZE);
			read_blocks(block_of_inode, 1, inode_update_buf);
			memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE));
			write_blocks(block_of_inode, 1, inode_update_buf);	
			write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap);
			return num_bytes_to_be_written;
			}	
		}

	//file not empty
	int number_pointers;
	if(get_num_pointers_inode(inode_index)>INODE_POINTERS-1){
		//first ignore the indrect pointers if it is used
		number_pointers = get_num_pointers_inode(inode_index)-1; 
	}
	else{
		number_pointers = get_num_pointers_inode(inode_index);
	}
	
	int array_blockptr[number_pointers];
	get_pointers(inode_index,array_blockptr,number_pointers);

	int num_unchanged_blocks = rw_index;
	//Update all those blocks	
	int updated_array_blockptr[num_blocks + num_unchanged_blocks];
	memset(updated_array_blockptr,0,num_blocks*sizeof(int));
	//Copy the unchanged blocks
	int p;
	for(p = 0; p < rw_index-1; p++){		
		updated_array_blockptr[p] = array_blockptr[p];
	}

	int s;
	for(s=rw_index-1; s<((num_blocks+num_unchanged_blocks)-1); s++){
		//Allocate additional free blocks when s>total intial blocks
		if(s>number_pointers-1){
			//free block is not enough, find more
				if(s==(num_blocks+num_unchanged_blocks-2)){
				//last block need to do a partial write
				int free_block = findfreeblock();
				updated_array_blockptr[s] = free_block;
				markfreeblock(free_block);
				if(num_blocks==1){
					update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,length);
					num_bytes_to_be_written=num_bytes_to_be_written+length;
				}
				else{
					if((BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)<0){
						return -1;//write in last block
					}
					update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)),0,(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE);	
					num_bytes_to_be_written = num_bytes_to_be_written + (length-(BLOCKSIZE-rw_offset)) % BLOCKSIZE;
				}			
			}
			else{				
				int free_block = findfreeblock();
				updated_array_blockptr[s] = free_block;
				markfreeblock(free_block);
				update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index)),0,BLOCKSIZE);	
				num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE;
			}	
		}
		else{
			markfreeblock(array_blockptr[s]);
			updated_array_blockptr[s] = array_blockptr[s];	
			if(s==rw_index-1){
				//Overwriting the first block of write
				if(num_blocks==1){	
					//if only updating one block - will not be filling the first block of the write.
					update_block(array_blockptr[s],(char*)buf,rw_offset,length);
					num_bytes_to_be_written = num_bytes_to_be_written + length;
				}
				else{
					update_block(array_blockptr[s],(char*)buf,rw_offset,BLOCKSIZE-rw_offset);
					num_bytes_to_be_written = num_bytes_to_be_written + BLOCKSIZE-rw_offset;
				}
			}
			else if(s==(num_blocks + num_unchanged_blocks-2)){
				//last block may be partial
				if(num_blocks==1){
					//special case for one block write.
					update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,length);
					num_bytes_to_be_written = num_bytes_to_be_written+length;
				}
				else{
					update_block(updated_array_blockptr[s],(char*)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE);
					num_bytes_to_be_written = num_bytes_to_be_written+(length-(BLOCKSIZE-rw_offset))%BLOCKSIZE;
				}
			}
			else{
				//overwriting a full block
				update_block(array_blockptr[s],(char *)(buf+(BLOCKSIZE-rw_offset)+BLOCKSIZE*(s-rw_index-1)),0,BLOCKSIZE);
				num_bytes_to_be_written = num_bytes_to_be_written+BLOCKSIZE;
			}
		}
	}


	//storing the block pointers and put updated_array_blockptr into inode
	update_inode_pointers(inode_index,updated_array_blockptr,num_blocks+num_unchanged_blocks);
	int f_num_pointers = get_num_pointers_inode(inode_index);
	if(f_num_pointers > INODE_POINTERS-1){
		//exclude superblock if it is used
		f_num_pointers--;
	}
	int final_inode_pointers[f_num_pointers];
	get_pointers(inode_index,final_inode_pointers,f_num_pointers);
	file_des_t[fileID].rw_pointer+=length;
	inodes[inode_index].size = return_filesize(inode_index);
	
	//writing into disk
	int inode_number = inode_index;
	int block_of_inode=inode_number/8+1; 
	char inode_update_buf[BLOCKSIZE];
	memset(inode_update_buf,0, BLOCKSIZE);
	read_blocks(block_of_inode, 1, inode_update_buf);
	memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE));
	write_blocks(block_of_inode, 1, inode_update_buf);	
	write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap);
	return num_bytes_to_be_written;
}
Пример #6
0
int sfs_remove(char *file){
	int i;
	for(i=0;i<TOTAL_NUM_FILES;i++){
		if(strncmp(dir_table[i].filename, file, MAXFILENAME)==0){//find the file to be removed in directory table 
			//clear data
			int inode_index = dir_table[i].inode_number;
			int num_pointers_in_inode = get_num_pointers_inode(inode_index);
			int indirect_pointer = 0;
			if(num_pointers_in_inode>=INODE_POINTERS){
				//get the indirect block address
				indirect_pointer = inodes[inode_index].pointers[INODE_POINTERS-1];
				//and remove it from number of pointers
				num_pointers_in_inode--;
			}
			int array_blockptr[num_pointers_in_inode];
			get_pointers(inode_index, array_blockptr,num_pointers_in_inode);//get all pointers in array_blockptr
			//remove indirect pointer
			if(indirect_pointer){
				char buffer[BLOCKSIZE];//write a empty buffer into disk to overwrite indirect_pointer 
				memset(buffer,0,BLOCKSIZE);
				write_blocks(indirect_pointer,1,buffer);
				set_freeblock(indirect_pointer);//set it free again
			}
			
			//handle other pointers 
			//reset the inode
			INODE free_inode={
				.mode=0, 
				.link_cnt=0, 
				.uid=0, 
				.gid=0, 
				.size=0,
				.pointers={0,0,0,0,0,0,0,0,0,0,0,0,0} //set all the pointers to 0
			};

			int n;
			char empty_block_buf[BLOCKSIZE];
			for(n=0; n < num_pointers_in_inode; n++){
				memset(empty_block_buf,0,BLOCKSIZE);
				write_blocks(array_blockptr[n],1,empty_block_buf);
				set_freeblock(array_blockptr[n]);
			}
 			
			inodes[inode_index] = free_inode;

	        write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap); //update the free_bitmap

			//write the updated inode in disk
			int inode_number = inode_index;
			int block_of_inode=inode_number/8+1; 
			char update_inode_buffer[BLOCKSIZE];
			memset(update_inode_buffer,0, BLOCKSIZE);
			read_blocks(block_of_inode, 1, update_inode_buffer);
			memcpy((void *)update_inode_buffer+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE));
			write_blocks(block_of_inode, 1, update_inode_buffer);	

			//set information in directory table to 0
			memset(dir_table[i].filename,0,MAXFILENAME);
			dir_table[i].inode_number=0;
			
			//update this information into disk
			char dir_entry_buffer[BLOCKSIZE];
			int block_dir_entry=i/NUM_ENTRIES_PERBLOCK+8+1;
			memset(dir_entry_buffer,0, BLOCKSIZE);
			read_blocks(block_dir_entry, 1, dir_entry_buffer);
			memcpy((void *)dir_entry_buffer+(i%21)*sizeof(dir_entry),(const void *) &dir_table[i], sizeof(dir_entry));
			write_blocks(block_dir_entry,1,dir_entry_buffer);

			//clear file descriptor table
			file_des_t[inode_index-1].open=0;
			file_des_t[inode_index-1].rw_pointer=0;
			return 0;
		}
	}
	//files does not exist, return -1
	return -1; 
}
Пример #7
0
uint64_t write_file(file_descriptor* fd, void* buf, uint64_t length)
{
  // Store number of bytes written.
  uint64_t written = 0;
  int read_error, write_error;

  // Pull inode.
  inode_t* inode = &table[fd->inode];

  // Allocate room for a block size in memory.
  void* block = (void*)malloc(BLOCK_SZ);

  // Write from block at RW pointer until length is complete.
  int starting_block_index = fd->rwptr / BLOCK_SZ;
  int current_block_count = starting_block_index;
  while (length) {
    // Get block index.
    int block_index = get_block_at(inode, current_block_count, true);
    if (block_index < 0) {
      perror("write_file()");
      break;
    }

    // Read from block.
    clear_block(block, 0, BLOCK_SZ);
    read_error = read_blocks(block_index, 1, block);
    if (read_error < 0) {
      perror("write_file(): read chunk from block");
      break;
    }

    // Modify block in memory.
    for (int j = fd->rwptr % BLOCK_SZ; j < BLOCK_SZ; j++) {
      // Copy current byte into buffer.
      memcpy(block + j, buf, 1);

      // Increment pointers.
      fd->rwptr += 1;
      buf += 1;

      // Increment number written.
      written += 1;

      // Decrement length.
      length -= 1;
      if (length == 0) {
        // Done in the middle of a block.
        break;
      }
    }

    // Write block.
    write_error = write_blocks(block_index, 1, block);
    if (write_error < 0) {
      perror("write_file(): write chunk to block");
      break;
    }

    // Increment block.
    current_block_count += 1;
  }

  // Free block.
  free(block);

  // Update inode size.
  if (fd->rwptr > inode->size) {
    inode->size = fd->rwptr;
  }

  // Write inodes and free blocks.
  write_inode_table();
  write_free_blocks();

  // Return number of bytes written.
  return written;
}
Пример #8
0
static gboolean
sync_read (f_str_t * in, void *arg)
{
	struct rspamd_sync_ctx *ctx = arg;
	gchar buf[256];
	guint64 rev = 0;
	time_t ti = 0;

	if (in->len == 0) {
		/* Skip empty lines */
		return TRUE;
	}
	switch (ctx->state) {
	case SYNC_STATE_GREETING:
		/* Skip greeting line and write sync command */
		/* Write initial data */
		statfile_get_revision (ctx->real_statfile, &rev, &ti);
		rev = rspamd_snprintf (buf,
				sizeof (buf),
				"sync %s %uL %T" CRLF,
				ctx->st->symbol,
				rev,
				ti);
		ctx->state = SYNC_STATE_READ_LINE;
		return rspamd_dispatcher_write (ctx->dispatcher, buf, rev, FALSE,
				   FALSE);
		break;
	case SYNC_STATE_READ_LINE:
		/* Try to parse line from server */
		if (!parse_revision_line (ctx, in)) {
			msg_info ("cannot parse line of length %z: '%*s'",
				in->len,
				(gint)in->len,
				in->begin);
			close (ctx->sock);
			rspamd_remove_dispatcher (ctx->dispatcher);
			ctx->is_busy = FALSE;
			return FALSE;
		}
		else if (ctx->state != SYNC_STATE_QUIT) {
			if (ctx->new_len > 0) {
				ctx->state = SYNC_STATE_READ_REV;
				rspamd_set_dispatcher_policy (ctx->dispatcher,
					BUFFER_CHARACTER,
					ctx->new_len);
			}
		}
		else {
			/* Quit this session */
			msg_info ("sync ended for: %s", ctx->st->symbol);
			close (ctx->sock);
			rspamd_remove_dispatcher (ctx->dispatcher);
			ctx->is_busy = FALSE;
			/* Immediately return from callback */
			return FALSE;
		}
		break;
	case SYNC_STATE_READ_REV:
		/* In now contains all blocks of specified revision, so we can read them directly */
		if (!read_blocks (ctx, in)) {
			msg_info ("cannot read blocks");
			close (ctx->sock);
			rspamd_remove_dispatcher (ctx->dispatcher);
			ctx->is_busy = FALSE;
			return FALSE;
		}
		statfile_set_revision (ctx->real_statfile, ctx->new_rev, ctx->new_time);
		msg_info ("set new revision: %uL, readed %z bytes",
			ctx->new_rev,
			in->len);
		/* Now try to read other revision or END line */
		ctx->state = SYNC_STATE_READ_LINE;
		rspamd_set_dispatcher_policy (ctx->dispatcher, BUFFER_LINE, 0);
		break;
	case SYNC_STATE_QUIT:
		close (ctx->sock);
		rspamd_remove_dispatcher (ctx->dispatcher);
		ctx->is_busy = FALSE;
		return FALSE;
	}

	return TRUE;
}
Пример #9
0
int sfs_fread(int fileID, char *buf, int length){
	if (check_open(fileID) == 0){
		printf("Can't write, file not opened\n");
		return -1;
	}
	//SETTING UP META INFO FOR EASY ACCESS
	int blk_inode = fd_table[fileID].inode;			//inode index of file we are reading from
	int read_ptr = fd_table[fileID].rptr;			//read pointer in bytes
	int blk_offset = read_ptr % BLOCK_SIZE;			//offset in bytes of the wptr within the first block
	int blk_index = read_ptr / BLOCK_SIZE;			//inode pointer of first block we start to read from
	int block_nmb;

	/*printf("===================================\n");
	printf("Read Pointer is at : %d\n", read_ptr);
	printf("Length taken as argument: %d\n", length);
	printf("File size: %d\n", inode_table[blk_inode].size);*/

	if (inode_table[blk_inode].size == 0){
		printf("File is empty, nothing to read\n");
		free(buffer);
		return 0;
	}
	if ((read_ptr + length) > inode_table[blk_inode].size) {
		length = inode_table[blk_inode].size - read_ptr;
	}
	
	buffer = (void*) malloc(BLOCK_SIZE);
	int nmb_of_bytes_read = 0;
	block_nmb = fetch_block(blk_inode, blk_index);
	//====================if the data we want to read is less than a block========================
	if ((blk_offset + length) < BLOCK_SIZE){
		read_blocks(block_nmb,1,buffer);
		memcpy(buf, (buffer+blk_offset), length);	//copy to buf only starting from offset
		nmb_of_bytes_read += length;
	
	//====================if the data we want to read is more than a block========================
	}else{
		// (1) READING REST OF FIRST BLOCK WHERE RPTR IS TO BUFFER
		read_blocks(block_nmb,1,buffer);
		memcpy(buf, (buffer+blk_offset), (BLOCK_SIZE - blk_offset));	//copy to buf only starting from offset
		blk_index++;

		nmb_of_bytes_read += BLOCK_SIZE - blk_offset;
		// (2) READING THE FULL BLOCKS
		int nmb_of_fullblocks = (length - (BLOCK_SIZE - blk_offset)) / BLOCK_SIZE;
		for (int i = 0; i < nmb_of_fullblocks; i++){
			block_nmb = fetch_block(blk_inode, blk_index);
			read_blocks(block_nmb,1,buffer);
			memcpy((buf + nmb_of_bytes_read),buffer,BLOCK_SIZE);
			nmb_of_bytes_read += BLOCK_SIZE;
			blk_index++;
		}

		// (3) READING THE LAST BLOCK
		block_nmb = fetch_block(blk_inode, blk_index);
		read_blocks(block_nmb,1,buffer);
		memcpy(buf + nmb_of_bytes_read, buffer, length - nmb_of_bytes_read);
		nmb_of_bytes_read += length - nmb_of_bytes_read;
	}

	//printf("Number of bytes read: %d\n", nmb_of_bytes_read);
	//printf("\nIn buf:\n%s\n", buf);

	//END THE READ
	//printf("String Length:%lu\n", strlen(buf));
	//printf("Length:%d\n", length);
	free(buffer);
	return length;
}
Пример #10
0
uint64_t read_file(file_descriptor* fd, void* buf, uint64_t length)
{
  // Store number of bytes read.
  uint64_t read = 0;
  int read_error;

  // Pull inode.
  inode_t* inode = &table[fd->inode];

  // Allocate room for a block size in memory.
  void* block = (void*)malloc(BLOCK_SZ);

  // Read from block at RW pointer until length is complete.
  int starting_block_index = fd->rwptr / BLOCK_SZ;
  int current_block_count = starting_block_index;
  while (length) {
    // Get block index.
    int block_index = get_block_at(inode, current_block_count, false);
    if (block_index < 0) {
      perror("read_file()");
      break;
    }

    // Read from block.
    clear_block(block, 0, BLOCK_SZ);
    read_error = read_blocks(block_index, 1, block);
    if (read_error < 0) {
      perror("read_file(): read chunk from block");
      break;
    }

    // Modify block in memory.
    for (int j = fd->rwptr % BLOCK_SZ; j < BLOCK_SZ; j++) {
      // Check if EOF.
      if (fd->rwptr == inode->size) {
        // Reached end of file. Done.
        break;
      }

      // Copy current byte into buffer.
      memcpy(buf, block + j, 1);

      // Increment pointers.
      fd->rwptr += 1;
      buf += 1;

      // Increment number of bytes read.
      read += 1;

      // Decrement length.
      length -= 1;
      if (length == 0) {
        // Done in the middle of a block.
        break;
      }
    }

    // Increment block.
    current_block_count += 1;
  }

  // Free memory buffer.
  free(block);

  // Return bytes read.
  return read;
}
Пример #11
0
int sfs_fwrite(int fileID, char *buf, int length){
	if (check_open(fileID) == 0){
		printf("Can't write, file not opened\n");
		return -1;
	}
	//SETTING UP META INFO FOR EASY ACCESS
	buffer = (void*) malloc(BLOCK_SIZE);
	int blk_inode = fd_table[fileID].inode;			//inode index of file we are writing in
	int current_size = inode_table[blk_inode].size;	//file size in bytes
	int write_ptr = fd_table[fileID].wptr;			//write pointer in bytes
	int blk_offset = write_ptr % BLOCK_SIZE;		//offset in bytes of the wptr within the first block
	int blk_index = write_ptr / BLOCK_SIZE;			//inode pointer of first block we start to write in

	//get block number where wptr is located within sfs
	int block_nmb = fetch_block(blk_inode, blk_index);		//get the block number in the sfs
	if (block_nmb == -1){
		return -1;
	}

	//GETTING THE BLOCK WHERE WPTR IS
	read_blocks(block_nmb,1,buffer);						//read what's already on the block

	/*printf("WPTR AT: %d\n", write_ptr);
	printf("File size before read: %d\n", current_size);
	printf("current_size: %d\n", current_size);
	printf("Write pointer + length: %d\n", write_ptr + length);*/
	//UPDATING INODE SIZE
	if (current_size <  write_ptr + length) {
		inode_table[blk_inode].size = write_ptr + length;
	}
	fd_table[fileID].wptr = write_ptr + length;
	//==========================if the data WILL NOT overflow to next block========================
	if (blk_offset + length < BLOCK_SIZE) {
		memcpy((buffer+blk_offset),buf,length);		//write the whole block with added data in buffer

		//WRITE THE BLOCK ON DISK
		write_blocks(block_nmb, 1, buffer);

	//==========================if the data WILL overflow to next block=============================
	} else {
		int nmb_of_bytes_copied = 0;

		//WRITING THE FIRST BLOCK
		memcpy(buffer+blk_offset,buf,(BLOCK_SIZE-blk_offset));	//write the whole block with added data in buffer
		nmb_of_bytes_copied += BLOCK_SIZE - blk_offset;

		//(1) WRITE THE FIRST BLOCK ON DISK
		write_blocks(block_nmb, 1, buffer);
		blk_index++;

		//(2) WRITE THE FULL BLOCKS
		int nmb_of_fullblocks = (length - (BLOCK_SIZE-blk_offset)) / BLOCK_SIZE;
		for (int i = 0; i < nmb_of_fullblocks; i++){
			memcpy(buffer,(buf+nmb_of_bytes_copied),BLOCK_SIZE);
			nmb_of_bytes_copied += BLOCK_SIZE;

			block_nmb = fetch_block(blk_inode, blk_index);		//get the block number in the sfs
			if (block_nmb == -1){
				return -1;
			}
			write_blocks(block_nmb, 1, buffer);
			blk_index++;
		}

		//(3) WRITE LAST BLOCK
		memcpy(buffer,(buf+nmb_of_bytes_copied),(length-nmb_of_bytes_copied));
		block_nmb = fetch_block(blk_inode, blk_index);		//get the block number in the sfs
		if (block_nmb == -1){
			return -1;
		}
		write_blocks(block_nmb, 1, buffer);
	}
	
	//printf("Length written: %d\n", length);
	//printf("File size after read: %d\n", inode_table[blk_inode].size);

	//END THE WRITE
	free(buffer);
	flush_to_disk(blk_inode, 2);		//flushing with option 2
	return length;
}
Пример #12
0
/* given logical block number, allocate a new physical block, if it does not
 * exist already, and return the physical block number that is allocated.
 * returns negative value on error. */
static int testfs_allocate_block(struct inode *in, int log_block_nr, char *block) {
    int phy_block_nr;
    char indirect[BLOCK_SIZE];
    int indirect_allocated = 0;

    assert(log_block_nr >= 0);
    phy_block_nr = testfs_read_block(in, log_block_nr, block);

    /* phy_block_nr > 0: block exists, so we don't need to allocate it, 
       phy_block_nr < 0: some error */
    if (phy_block_nr != 0)
        return phy_block_nr;

    /* allocate a direct block */
    if (log_block_nr < NR_DIRECT_BLOCKS) {
        assert(in->in.i_block_nr[log_block_nr] == 0);
        phy_block_nr = testfs_alloc_block_for_inode(in);
        if (phy_block_nr >= 0) {
            in->in.i_block_nr[log_block_nr] = phy_block_nr;
        }
        return phy_block_nr;
    }

    log_block_nr -= NR_DIRECT_BLOCKS;
    if (log_block_nr >= NR_INDIRECT_BLOCKS) {
        log_block_nr -= NR_INDIRECT_BLOCKS;
        char dindirect[BLOCK_SIZE];
        int dindirect_allocated = 0;
        int position = log_block_nr/NR_INDIRECT_BLOCKS;
        if (log_block_nr >= NR_INDIRECT_BLOCKS * NR_INDIRECT_BLOCKS) {
            return -EFBIG;
        }
        //get the double indirect block first
        if(in->in.i_dindirect == 0){
            bzero(dindirect, BLOCK_SIZE);
            phy_block_nr = testfs_alloc_block_for_inode(in);
            if(phy_block_nr < 0)
                return phy_block_nr;
            dindirect_allocated = 1;
            in->in.i_dindirect = phy_block_nr;
        } else{
            read_blocks(in->sb, dindirect, in->in.i_dindirect, 1);
        }
        //get the indirect block in double indirect block
        if(((int*) dindirect)[position] == 0) {
            bzero(indirect, BLOCK_SIZE);
            phy_block_nr = testfs_alloc_block_for_inode(in);
            if (phy_block_nr < 0){
                if (dindirect_allocated) {
                    testfs_free_block_from_inode(in, in->in.i_dindirect);
                    return phy_block_nr;
                }
            } else{
                indirect_allocated = 1;
                ((int *) dindirect)[position] = phy_block_nr;
                write_blocks(in->sb, dindirect, in->in.i_dindirect, 1);
            }
        }else{
            read_blocks(in->sb, indirect, ((int*) dindirect)[position], 1);
        }
        //get the direct block
        assert(((int *) indirect)[log_block_nr % NR_INDIRECT_BLOCKS] == 0);
        phy_block_nr = testfs_alloc_block_for_inode(in);
        if(phy_block_nr < 0){
            if(dindirect_allocated){
                testfs_free_block_from_inode(in, ((int *)dindirect)[position]);
                testfs_free_block_from_inode(in, in->in.i_dindirect);
            }else if(indirect_allocated)
                testfs_free_block_from_inode(in, ((int *)dindirect)[position]);
            return phy_block_nr;
        }
        else if (phy_block_nr >= 0) {
            ((int *) indirect)[log_block_nr % NR_INDIRECT_BLOCKS] = phy_block_nr;
            write_blocks(in->sb, indirect, ((int *)dindirect)[position], 1);
        } 
        return phy_block_nr;
    } 
    
    
    if (in->in.i_indirect == 0) { /* allocate an indirect block */
        bzero(indirect, BLOCK_SIZE);
        phy_block_nr = testfs_alloc_block_for_inode(in);
        if (phy_block_nr < 0)
            return phy_block_nr;
        indirect_allocated = 1;
        in->in.i_indirect = phy_block_nr;
    } else { /* read indirect block */
        read_blocks(in->sb, indirect, in->in.i_indirect, 1);
    }

    /* allocate direct block */
    assert(((int *) indirect)[log_block_nr] == 0);
    phy_block_nr = testfs_alloc_block_for_inode(in);

    if (phy_block_nr >= 0) {
        /* update indirect block */
        ((int *) indirect)[log_block_nr] = phy_block_nr;
        write_blocks(in->sb, indirect, in->in.i_indirect, 1);
    } else if (indirect_allocated) {
        /* free the indirect block that was allocated */
        testfs_free_block_from_inode(in, in->in.i_indirect);
    }
    return phy_block_nr;
}
Пример #13
0
void sfs_read(int fd, char *buf, int length){
	
	currmyfile = fd;
        int blockID = 1;
	int position = 0;
	int diff;
	int spaceLeft;
        int i,j;
	int currFATi;
        int temptr;

	readBuff = (char *) malloc(1024);
	tempbuff = (char *) malloc(1024);
	tempbuff2 = (char *) malloc(1024);
	tempbuff3 = (char *) malloc(1024);
	readLen = length;
	spaceLeft = readLen;
	myfile = directory[FDT[fd].dirIndex];
	rootFAT = myfile.indFAT;
	currFATi = rootFAT;
	for(i=0; i < 1024; i++){
            if(FDT[currmyfile].read - position > 1024){
		position = position + 1024;
		blockID = blockID + 1;
		currFATi = FAT[currFATi][1];
            }
	}

	diff = (blockID * 1024) - FDT[currmyfile].read;
	temptr = FDT[currmyfile].read;
        for(i=0; i < 1024;i++){
		if(readLen > diff){
                    read_blocks(FAT[currFATi][0],1,readBuff);
			for(j=0; j < diff; j++){
				tempbuff[j] = readBuff[j+FDT[currmyfile].read];
			}
			readLen = readLen - diff;
			temptr = temptr + diff;
			currFATi = FAT[currFATi][1];
			blockID = blockID + 1;
			position = position + 1024;
			diff = 1024;
                }
		else{
                    read_blocks(FAT[currFATi][0],1,readBuff);
                    if(FDT[currmyfile].read==0){
                        for(j=0; j < readLen; j++){
                            tempbuff[j] = readBuff[j+FDT[currmyfile].read];
			}
                    }
                    else{
			if(diff != 1024){
                            for(j=0; j < diff; j++){
                                tempbuff[j] = readBuff[j+FDT[currmyfile].read -(blockID-1)*1024];
                            }
			}
                        if(diff == 1024){
                            for(j=0; j < readLen; j++){
                                 tempbuff2[j] = readBuff[j];
				}
			}
                    }
		}
	}
	strcpy(buf,tempbuff);
	strcat(buf,tempbuff2);
	FDT[currmyfile].read = FDT[currmyfile].read + length;

}
Пример #14
0
int main (int argc, char **argv)
{
	FILE *fd;
	uint16_t i;
	int rv;
	int error = 0;
	TALLOC_CTX *mem_ctx;
	
	if (argc == 1) {
		puts("Usage: chkregf REGFILE");
		return 1;
	}
	if (!(fd = fopen(argv[1], "r"))) {
		puts("Error: file not found");
		return 2;
	}

	mem_ctx = talloc_init("chkregf registry checker");
	if (!mem_ctx) {
		printf("Memory allocation error\n");
		return 3;
	}
	
	printf("\nPass 1: Checking registry regf header\n\n");
	
	if (!read_regf_header(fd)) {
		printf("Regf header contains errors\n");
		return 1;
	} 
	

	printf("\nPass 2: Checking keys for incorrect values\n\n");
	
	for(i = 0; i < regf.data_size / 0x1000; i++) {
		uint32_t size;
		
		if (!(size = get_hbin_header(fd, 0x1000 * i))) {
			printf("Errors in hbin header at 0x%lx.",
					(long int) (0x1000 * i) + 0x1000);
			return 1;
		}
		rv = read_blocks(mem_ctx, fd, 0x1000 * i);
		if (!rv) {
			error = 1;
		}
		if (size / 0x1000 > 1) {
			i += (size/0x1000) - 1;
		}
	}

	printf("\nPass 3: Checking offsets and tree\n");

	rv = parse_tree(mem_ctx, fd, regf.key_offset, 0, "nk", 0);
	if (!rv) {
		error = 1;
	}

	if (error) {
		printf("Errors encountered\n");
		return 1;
	}
	printf("\nDone checking, no errors...\n\n");

	fclose(fd);
	return 0;
}
Пример #15
0
int get_block_at(inode_t* inode, int i, bool create)
{
  int block_index = -1;

  // Get direct block.
  if (i < NUM_DIRECT_BLOCKS) {
    if (inode->direct_blocks[i]) {
      // It exists.
      return inode->direct_blocks[i];
    } else if (create) {
      // Yield free block.
      block_index = yield_block();
      if (block_index < 0) {
        errno = ENOSPC;
        return block_index;
      }

      // Add to inode.
      inode->direct_blocks[i] = block_index;
      write_inode_table();

      return block_index;
    }
  }

  // Not enough blocks.
  if (i >= MAX_BLOCKS_PER_INODE) {
    // File too big.
    errno = EFBIG;
    return block_index;
  }

  // Otherwise, get indirect block.
  if (i >= NUM_DIRECT_BLOCKS) {
    uint64_t* block;
    if (inode->indirect_block || create) {
      // Create buffer in memory.
      block = (uint64_t*)malloc(BLOCK_SZ);
      clear_block(block, 0, BLOCK_SZ);

      if (create && inode->indirect_block == 0) {
        // Create if needed.
        int indirect_block_index = yield_block();
        if (indirect_block_index < 0) {
          free(block);
          errno = ENOSPC;
          return indirect_block_index;
        }

        // Write to inode.
        inode->indirect_block = indirect_block_index;
        write_inode_table();
      }

      uint64_t indirect_block_ptr = i - NUM_DIRECT_BLOCKS;
      read_blocks(inode->indirect_block, 1, block);
      if (block[indirect_block_ptr] > 0) {
        block_index = block[indirect_block_ptr];
      } else if (create) {
        // Create if needed.
        block_index = yield_block();
        if (block_index > 0) {
          // Succeeded, so write to disk.
          block[indirect_block_ptr] = block_index;
          write_blocks(inode->indirect_block, 1, block);
        }
      }

      // Free memory.
      free(block);
    }
  }

  if (block_index < 0) {
    errno = EFAULT;
  }
  return block_index;
}
static long int
jitter_read (cdrom_drive_t *d, void *p, lsn_t begin, long i_sectors,
	     jitter_baddness_t jitter_badness)
{
  static int i_jitter=0;
  int jitter_flag;
  long i_sectors_orig = i_sectors;
  long i_jitter_offset = 0;

  char *p_buf=malloc(CDIO_CD_FRAMESIZE_RAW*(i_sectors+1));

  if (d->i_test_flags & CDDA_TEST_ALWAYS_JITTER)
    jitter_flag = 1;
  else
#ifdef HAVE_DRAND48
    jitter_flag = (drand48() > .9) ? 1 : 0;
#else
    jitter_flag = (((float)rand()/RAND_MAX) > .9) ? 1 : 0;
#endif

  if (jitter_flag) {
    int i_coeff = 0;
    int i_jitter_sectors = 0;
    switch(jitter_badness) {
    case JITTER_SMALL  : i_coeff =   4; break;
    case JITTER_LARGE  : i_coeff =  32; break;
    case JITTER_MASSIVE: i_coeff = 128; break;
    case JITTER_NONE   :
    default            : ;
    }
#ifdef HAVE_DRAND48
    i_jitter = i_coeff * (int)((drand48()-.5)*CDIO_CD_FRAMESIZE_RAW/8);
#else
    i_jitter = i_coeff * (int)((((float)rand()/RAND_MAX)-.5)*CDIO_CD_FRAMESIZE_RAW/8);
#endif

    /* We may need to add another sector to compensate for the bytes that
       will be dropped off when jittering, and the begin location may
       be a little different.
    */
    i_jitter_sectors = i_jitter / CDIO_CD_FRAMESIZE_RAW;

    if (i_jitter >= 0)
      i_jitter_offset  = i_jitter % CDIO_CD_FRAMESIZE_RAW;
    else {
      i_jitter_offset  = CDIO_CD_FRAMESIZE_RAW -
	(-i_jitter % CDIO_CD_FRAMESIZE_RAW);
      i_jitter_sectors--;
    }


    if (begin + i_jitter_sectors > 0) {
#if TRACE_PARANOIA
      char buffer[256];
      sprintf(buffer, "jittering by %d, offset %ld\n", i_jitter,
	      i_jitter_offset);
      cdmessage(d,buffer);
#endif

      begin += i_jitter_sectors;
      i_sectors ++;
    } else
      i_jitter_offset = 0;

  }

  i_sectors = read_blocks(d, p_buf, begin, i_sectors);

  if (i_sectors < 0) return i_sectors;

  if (i_sectors < i_sectors_orig) {
    /* Had to reduce # of sectors due to read errors. So give full amount,
       with no jittering. */
    if (p) memcpy(p, p_buf, i_sectors*CDIO_CD_FRAMESIZE_RAW);
  } else {
    /* Got full amount, but now adjust size for jittering. */
    if (p) memcpy(p, p_buf+i_jitter_offset, i_sectors_orig*CDIO_CD_FRAMESIZE_RAW);
    i_sectors = i_sectors_orig;
  }

  free(p_buf);
  return(i_sectors);
}
Пример #17
0
void mksfs(int fresh){
	//Implement mksfs here
	if (fresh == 1){
		//deletes fs if it already exists
		if(access(DISK_FILE, F_OK) != -1){
			unlink(DISK_FILE);			
		}
		//fs creation
		printf("Initalizing sfs\n");
		init_fresh_disk(DISK_FILE, BLOCK_SIZE, MAX_BLOCKS);
        //zero_everything();
		// writes superblock to the first block
        printf("Writing superblocks\n");
        init_superblock();
		write_blocks(0, 1, &sb);
		// write the inode table to the 2nd block
        printf("Writing inode table\n");
		init_inode_table();
        //add_root_dir_inode();
        //add_dummy_file_inode();
		//write_blocks(1, 1, &inode_table);
		// creates free list
		init_free_list();
        // write root directory data to the 3rd block
        printf("Writing root dir\n");		
		init_root_dir();

		//allocate memory for directory inode
		inode_t *inode = malloc(ADJUST((MAX_FILES+1)*sizeof(inode_t)));
		read_blocks(INODE_TABLE, INODE_TABLE_SIZE, inode);
		if(inode == NULL){
			return;
		}
		//set first inode to point to directory
		inode[0].size = DIRECTORY_SIZE*BLOCK_SIZE;
		inode[0].link_cnt = DIRECTORY_SIZE;
		inode[0].exists = 1;
		
		//check to see if we need to use ref_ptr
		//if(DIRECTORY_SIZE > 12){
			//inode[0].ref_ptr = search();
			//setAlloc(inode[0].ref_ptr);
			//unsigned int *buffer = malloc(BLOCK_SIZE);
			//write_blocks(19 + inode[0].ref_ptr, 1, buffer);
			//free(buffer);
		
		//assign the pointers the location of directory files
		int i;
		for(i = 0; i < DIRECTORY_SIZE; i++){
			if(i > 11){
				unsigned int *buffer = malloc(BLOCK_SIZE);
				read_blocks(19+ inode[0].ref_ptr, 1, buffer);
				buffer[i - 12] = 2 + i;
				write_blocks(19+ inode[0].ref_ptr, 1, buffer);
				free(buffer);
			} 
			else{
				inode[0].data_ptrs[i] = 2 + i;
			}
		}
		//update inode and free memory
		write_blocks(INODE_TABLE, INODE_TABLE_SIZE, inode);
		free(inode);		
	}
	
	else if (fresh == 0){
		if(init_disk(DISK_FILE, BLOCK_SIZE, MAX_BLOCKS) != 0){
			printf("Error initializing disk\n");
			return;
		}
	}
	//allocate main memory for filesystem data structures
	int *superblock = malloc(BLOCK_SIZE*SUPERBLOCK_SIZE);

	if(superblock == NULL){
		printf("Error allocating memory for superblock\n");
		return;
	}
	read_blocks(0, SUPERBLOCK_SIZE, superblock);
	//allocate main memory for directory
	root_dir = malloc(ADJUST(sizeof(dir_entry_t)*MAX_FILES));
	
	if(root_dir == NULL){
		printf("Error allocating memory for root directory\n");
		return;
	}
	read_blocks(2, DIRECTORY_SIZE, root_dir);
	//allocate memory for inode table
	inode_table = malloc(ADJUST(sizeof(inode_t)*(MAX_FILES+1)));
	
	if(inode_table == NULL){
		printf("Error allocating memory for inode table");
		return;
	}

	read_blocks(INODE_TABLE, INODE_TABLE_SIZE, inode_table);
	fileCount = 0;
	fd_table = NULL;
	return;		
}
Пример #18
0
int sfs_fopen(char *name){
	
	int i;
	for(i=0;i<TOTAL_NUM_FILES;i++){
		if(strncmp(dir_table[i].filename, name, MAXFILENAME+1+MAXFILEEXTENTSION)==0){ //check the whole name including the extention
			if(file_des_t[i].open == 1){//check if it is opened
				return i; //return the index in file descriptor table		
			}
			//else open this file 
			file_des_t[i].open = 1;
			//put the pointer after the new opened file
			file_des_t[i].rw_pointer = inodes[i+1].size;
			return i;
		}
	}
	//file does not exist
	int unoccupied_inode_index;
	int j;
	for(j=1;j<NUMBER_INODES;j++){//j =1 because j = 0 is the root inode
		if(inodes[NUMBER_INODES-1].link_cnt==1){
			return -1;
		}
		if(inodes[j].link_cnt==0){ //link_cnt = 0,means unoccupied
			unoccupied_inode_index=j;
			break;
		}
	}	

	//initialize a new node
	INODE new_inode={
		.mode=0777, 
		.link_cnt=1, // has one link pointing to it 
		.uid=0, 
		.gid=0, 
		.size=0,
		.pointers={0,0,0,0,0,0,0,0,0,0,0,0,0} 
	};
	
	inodes[unoccupied_inode_index] = new_inode;
	
	int inode_num = unoccupied_inode_index;
	int num_blocks = inode_num/8+1; 
	char update_inode_buffer[BLOCKSIZE];
	memset(update_inode_buffer,0, BLOCKSIZE);
	read_blocks(num_blocks, 1, update_inode_buffer);
	memcpy((void *)update_inode_buffer+(inode_num%8)*sizeof(INODE),(const void *) &inodes[inode_num], sizeof(INODE));
	write_blocks(num_blocks, 1, update_inode_buffer);	

	//find a free position in directory table
	int index_of_directory;
	for (index_of_directory=0; index_of_directory < TOTAL_NUM_FILES; index_of_directory++){
		if(dir_table[index_of_directory].inode_number==0){
			break;	
		}
	}
	
	//initialize new directory entry in 
	dir_entry new_dir_entry;
	strcpy(new_dir_entry.filename, name);
	new_dir_entry.inode_number=unoccupied_inode_index;
	dir_table[index_of_directory]=new_dir_entry;

	//write it into disk
	int index_dir_entry_block = index_of_directory/NUM_ENTRIES_PERBLOCK+BLOCKS_INODES_TABLE+1; //+1 for superblock
	char buf[BLOCKSIZE];
	memset(buf,0, BLOCKSIZE);
	read_blocks(index_dir_entry_block, 1, buf);
	memcpy((void *)buf+(index_of_directory%NUM_ENTRIES_PERBLOCK)*sizeof(dir_entry),(const void *) &dir_table[index_of_directory], sizeof(dir_entry));
	write_blocks(index_dir_entry_block,1,buf);
	file_des_t[index_of_directory].open = 1;
	return index_of_directory;
} 

//close opened file by setting open arrtibute to 0 
int sfs_fclose(int fileID){
	if(file_des_t[fileID].open==1){
		file_des_t[fileID].open=0;
		return 0;
	}
	else
	{
		return -1;
	}
} 

//helper function to help update the block numbers by received an offset bytes and update the buffered  memory of the block
int update_block(int block_num, char *data, int offset_bytes, int num_bytes_write){
	char buffer[BLOCKSIZE];
	memset(buffer, 0, BLOCKSIZE);
	//read existing blocks into buffer
	read_blocks(block_num,1, buffer);
	memcpy(buffer+offset_bytes, data, num_bytes_write);
	int flag = write_blocks(block_num, 1, buffer);
	if(flag){
		return num_bytes_write;
	}
	else{
		return -1;
	}
}
Пример #19
0
int sfs_fread(int fileID, char *buf, int length){

	//Implement sfs_fread here	

    // error check
    if(fd_table[fileID] == NULL || length < 0 || fileID > fileCount || buf == NULL){
        printf("Error reading file\n");
        return -1;
    }
	
    fd_table_t *read = fd_table[fileID];
    inode_t *temp_inode = &(inode_table[read->inode_idx]);


    if(read->inode_idx == LIMIT){
        printf("Inode error\n");
        return -1;
    }
    
    if(read->rd_write_ptr + length > temp_inode->size){
        length = temp_inode->size - read->rd_write_ptr;
    }

    char *buffer = malloc(BLOCK_SIZE);

    int readLength = length, offset = 0;
    int block = (read->rd_write_ptr)/BLOCK_SIZE;
    int bytes = (read->rd_write_ptr)%BLOCK_SIZE;
    int endOfBlock = (temp_inode->size)/BLOCK_SIZE;

    unsigned int readLocation;

    if(block > 139){
        printf("ERROR: Cannot read. File exceeds maximum size\n");
        return -1;
    }
    else if(block > 11){
        unsigned int *tempBuf = malloc(BLOCK_SIZE);
        read_blocks(19 + temp_inode->ref_ptr, 1, tempBuf);
        readLocation = tempBuf[block - 12];
        free(tempBuf);
    }
    else{
        readLocation = temp_inode->data_ptrs[block];
    }

    while(length > 0){
        read_blocks((19 + readLocation), 1, buffer);
		int bytesRead;

        if(BLOCK_SIZE - bytes < length){
            bytesRead = BLOCK_SIZE - bytes;
        }
        else{
            bytesRead = length;
        }

        memcpy(&buf[offset], &buffer[bytes], bytesRead);
        length -= (bytesRead);
        offset += (bytesRead);
        bytes = 0;

        if(length > 0){
            block++;
            if(endOfBlock < block){
                return -1;
            }
            if(block > 139){
                printf("ERROR: Cannot read. File exceeds maximum size\n");
                return -1;
            }
            else if(block > 11){
                unsigned int *nextBuffer = malloc(BLOCK_SIZE);
                read_blocks(19 + temp_inode->ref_ptr, 1, nextBuffer);
                readLocation = nextBuffer[block - 12];
                free(nextBuffer);
            }
            else{
                readLocation = temp_inode->data_ptrs[block];
            }
        }
    }

    free(buffer);
    read->rd_write_ptr += readLength;
    
    return readLength;
}
Пример #20
0
int sfs_fread(int fileID, char *buf, int length){

	int num_bytes = 0;
	int num_pointers = 0;
	int inode_index = dir_table[fileID].inode_number;
	
	if(file_des_t[fileID].open==0){ 	 //check if file is opened
		return -1;
	}
	
	if(length>inodes[inode_index].size){
		length=inodes[inode_index].size; //attempt to read more data than the file has
	}

	num_pointers = get_num_pointers_inode(inode_index);
	
	if(num_pointers>INODE_POINTERS-1){
		num_pointers--;
	}
	int array_blockptr[num_pointers];
	get_pointers(inode_index,array_blockptr,num_pointers);//get pointers in inode into array_blockptr
	
	//find the number of blocks to read
	int rw_offset = file_des_t[fileID].rw_pointer % BLOCKSIZE;
	int rw_index  = file_des_t[fileID].rw_pointer / BLOCKSIZE + 1; 

	int num_blocks;
	if(length<(BLOCKSIZE-rw_offset)){ 
	    //read within one block
		char read_buf[BLOCKSIZE];
		memset(read_buf,0,BLOCKSIZE);
		read_blocks(array_blockptr[rw_index-1],1,read_buf);
		memcpy(buf,read_buf+rw_offset,length);
		file_des_t[fileID].rw_pointer+=length;
		return length;
	}
	else{
		num_blocks=(length-(BLOCKSIZE-rw_offset))/BLOCKSIZE+2; //+2 for the first and last partial block
	}
	
	int k;
	char read_buf[BLOCKSIZE];
	for(k=rw_index-1;k<rw_index+num_blocks-1;k++){
		memset(read_buf,0,BLOCKSIZE);
		read_blocks(array_blockptr[k],1,read_buf);
		if(k==rw_index-1){
			//first is partial block
			memcpy(buf,read_buf+rw_offset,BLOCKSIZE-rw_offset); //read only the remaining data
			num_bytes = num_bytes + (BLOCKSIZE-rw_offset);
		}
		else if(k==rw_index+num_blocks-2){
			//last block is partial block
			memcpy(buf+num_bytes, read_buf, (length-(BLOCKSIZE-rw_offset))%BLOCKSIZE);
			num_bytes = num_bytes + (length-(BLOCKSIZE-rw_offset))%BLOCKSIZE;
		}
		else{
			//full block
			memcpy(buf+num_bytes, read_buf, BLOCKSIZE);
			num_bytes = num_bytes + BLOCKSIZE;
		}
		
	}
	
	file_des_t[fileID].rw_pointer = file_des_t[fileID].rw_pointer + num_bytes;
	return num_bytes;
}
Пример #21
0
int sfs_fwrite(int fileID, const char *buf, int length){

	//Implement sfs_fwrite here
	
    // error check
    if(fd_table[fileID] == NULL || length < 0 || fileID > fileCount || buf == NULL){
        printf("Error reading file\n");
        return -1;
    }
	
	fd_table_t *write = fd_table[fileID];
	inode_t *temp_inode = &(inode_table[write->inode_idx]);
	
	// check fd table entry
    if(write->inode_idx == LIMIT){
		printf("Inode error");
		return -1;
	}
	  
    char *buffer = malloc(BLOCK_SIZE);

    int writeLength = length, offset = 0;
    int block = (write->rd_write_ptr)/BLOCK_SIZE;
    int bytes = (write->rd_write_ptr)%BLOCK_SIZE;
    int endOfBlock = (temp_inode->size)/BLOCK_SIZE;
    int bytesToWrite;

    unsigned int writeLocation;	  
	
	// max file size error check
    if(block > 139){
        printf("ERROR: Cannot write. File exceeds maximum size\n");
        return -1;
    }
	
	// retrieves block location using ref_ptr
    else if(block > 11){
        unsigned int *tempBuf = malloc(BLOCK_SIZE);
        read_blocks(19 + temp_inode->ref_ptr, 1, tempBuf);
        writeLocation = tempBuf[block - 12];
        free(tempBuf);
    }	
	// uses data pointers if ref_ptr search fails
    else{
        writeLocation = temp_inode->data_ptrs[block];
    }	

	if(writeLocation != -1){
		while(length > 0){ 
			read_blocks((19 + writeLocation), 1, buffer);
			if(BLOCK_SIZE - bytes < length){
				bytesToWrite = BLOCK_SIZE - bytes;
			}
			else{
				bytesToWrite = length;			
			}
			memcpy(&buffer[bytes], &buf[offset], bytesToWrite);
			write_blocks(19 + writeLocation, 1, buffer);
	
			length -= (bytesToWrite);
			offset += (bytesToWrite);
			bytes = 0;
			block++;
		
			if(length > 0){
				if(block > 139){
					printf("ERROR: Cannot write. File exceeds maximum size\n");
					return -1;
				}
				else if(endOfBlock < block){ 
					if(block == 12 && temp_inode->ref_ptr == LIMIT){
						int searchPtr = search();
						allocate(searchPtr);
						temp_inode->ref_ptr = searchPtr;
					}
					int nextLocation = search();
					allocate(nextLocation);
					if(nextLocation == -1){
						return -1;
					}
					writeLocation = nextLocation;
					if(block > 11){
						unsigned int *nextBuffer = malloc(BLOCK_SIZE);
						read_blocks(19+ temp_inode->ref_ptr, 1, nextBuffer);
						nextBuffer[block - 12] = writeLocation;
						write_blocks(19+ temp_inode->ref_ptr, 1, nextBuffer);
						free(nextBuffer);
					}
					else{
						temp_inode->data_ptrs[block] = writeLocation;					
					}
				
					temp_inode->link_cnt++; // updates link count. Not sure if necessary
				}
				else{
					if(block > 11){
						unsigned int *nextBuffer = malloc(BLOCK_SIZE);
						read_blocks(19+ temp_inode->ref_ptr, 1, nextBuffer);
						writeLocation = nextBuffer[block - 12];
						free(nextBuffer);
					}
					else{
						writeLocation = temp_inode->data_ptrs[block];					
					}
				}
			}
		}
	}
	// update filesize in inode table
	if(write->rd_write_ptr + writeLength > temp_inode->size){
		temp_inode->size = write->rd_write_ptr + writeLength;
	}
	// update read/write pointer
	write->rd_write_ptr += writeLength;
	// update inode table
	write_blocks(INODE_TABLE, INODE_TABLE_SIZE, inode_table);
	free(buffer);
	// returns length of written data
	return writeLength;
}
Пример #22
0
//Creates the file system
int mksfs(int fresh){
	char buf[BLOCKSIZE];
	memset(buf,0, BLOCKSIZE); //sets a block-size buffer  and set it to zero
	
	if(fresh){
		init_fresh_disk(DISK_FILE, BLOCKSIZE, TOTAL_NUM_BLOCKS); 
		
		//initialize super block
		super_block superblock;
		superblock.magic=0xAABB0005;
		superblock.block_size=BLOCKSIZE;
		superblock.file_system_size=TOTAL_NUM_BLOCKS;
		superblock.inode_table_length=NUMBER_INODES;
		superblock.root_dir_inode_number=0;	//set root directory at the first inode 
		//copy super block to buffer
		memcpy((void *)buf,(const void *) &superblock,  sizeof(super_block)); 
		//write the superblock to the first block in the disk
		write_blocks(0,1, buf);
		//initialize inode table
		memset(inodes, 0, sizeof(inodes));
		//Set first inode to root directory inode 
		INODE root_dir_inode={
			.mode=0777, 
			.link_cnt=1, 
			.uid=0, 
			.gid=0,
			.size=0,
			.pointers={14,15,16,17,18,0,0,0,0,0,0,0,0} //pointer to the first data block starting at 14
		};

		inodes[0]=root_dir_inode;
		//write inode into disk
		int inode_number = 0;
		int block_of_inode=inode_number/8+1; 
		char inode_update_buf[BLOCKSIZE];
		memset(inode_update_buf,0, BLOCKSIZE);
		read_blocks(block_of_inode, 1, inode_update_buf);
		memcpy((void *)inode_update_buf+(inode_number%8)*sizeof(INODE),(const void *) &inodes[inode_number], sizeof(INODE));
		write_blocks(block_of_inode, 1, inode_update_buf);	

		//initialize the bitmap
		memset(free_bitmap, 0, sizeof(free_bitmap));
		free_bitmap[0]=255; //superblock and first part of inodes to occupied.
		free_bitmap[1]=255; //inodes table to occupied.
		free_bitmap[2]=224; //directory entry table to occupied. 
		free_bitmap[BLOCKSIZE-1]=1; //last block for the bitmap	
		write_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap);//write the bitmap into disk

		//initialize directory table into memory
		memset(dir_table, 0, sizeof(dir_table));

		//Initialize all file's RW pointers to 0 and open to 0 
		memset(file_des_t, 0, sizeof(file_des_t));
		cur_pos=-1;
		return 0;
	}
	else{ 
		//file system already exists
		init_disk(DISK_FILE, BLOCKSIZE, TOTAL_NUM_BLOCKS);
		// set free_bitmap to zeros
		memset(free_bitmap,0, sizeof(free_bitmap));
		//load existing bitmap 
		read_blocks(TOTAL_NUM_BLOCKS-1,1,free_bitmap);
		//load existing superblock
		super_block superblock;
		read_blocks(0,1,&superblock);
		//load existing inode table
		char inodes_buffer[BLOCKS_INODES_TABLE*BLOCKSIZE];
		memset(inodes_buffer,0,sizeof(inodes_buffer));
		read_blocks(1,BLOCKS_INODES_TABLE,inodes_buffer);
		
		int n;
		for(n=0;n<NUMBER_INODES;n++){
			memcpy((void *)&(inodes[n]),(const void *)(inodes_buffer+n*(BLOCKSIZE/8)), BLOCKSIZE/8); 
		}
		
		//load existing directory table
		INODE root_directory=inodes[superblock.root_dir_inode_number];
		int i;
		
		char root_dir_buffer[BLOCKSIZE];
		
		memset(root_dir_buffer,0,BLOCKSIZE);
		
		for(i=0;i<INODE_POINTERS;i++){
			if(root_directory.pointers[i]!=0){
				read_blocks(root_directory.pointers[i],1, root_dir_buffer); 
				int j;
				for(j=0;j<NUM_ENTRIES_PERBLOCK;j++){
					if((j+NUM_ENTRIES_PERBLOCK*i) >= TOTAL_NUM_FILES){
						break;
					}
					memcpy((void *)&(dir_table[j]), (const void *)(root_dir_buffer+j*(sizeof(dir_entry))), sizeof(dir_entry));
				}
				memset(root_dir_buffer,0,BLOCKSIZE);
			}
		}
		//initialize all rw pointers to 0 and open to 0 
		memset(file_des_t, 0, sizeof(file_des_t));
		cur_pos=-1;
		return 0;
	}
}
Пример #23
0
int sfs_fwrite(int fileID, const char *buf, int length)
{
    inode_struct* inode;
    int filled, rw_pointer, blknum, blk_pointer;
    int last_block_bytes, last_full_blknum; 
    char block[BLKSIZ];
    
    // If file is not open or write exceeds maximum file size return error
    if( (fd_table[fileID].status == FREE) || (fd_table[fileID].rw_pointer + length > MAXFILESIZ) )
            return -1;
    
    inode = fd_table[fileID].inode;
    rw_pointer = fd_table[fileID].rw_pointer;
    
    blknum = rw_pointer/BLKSIZ;
    filled = rw_pointer % BLKSIZ;
    
    // If we do not need to go to another data block
    if( (filled + length) <= BLKSIZ) {
        blk_pointer = get_blk_pointer(&(inode->blk_pointers), blknum);
        if(blk_pointer == -1) return -1;
        read_blocks(blk_pointer, 1, block);
        memcpy(&block[filled], buf, length);
        write_blocks(blk_pointer, 1, block);
        
        inode->size = max(rw_pointer + length, inode->size);
        fd_table[fileID].rw_pointer = rw_pointer + length;
        return length;
    } 
    
    last_full_blknum = ((filled + length) / BLKSIZ) + blknum;
    last_block_bytes = (filled + length) % BLKSIZ;
    
    blk_pointer = get_blk_pointer(&(inode->blk_pointers), blknum);
    if(blk_pointer == -1) return -1;
    read_blocks(blk_pointer, 1, block);
    memcpy(&block[filled], buf, BLKSIZ - filled);
    write_blocks(blk_pointer, 1, block);
    
    buf += BLKSIZ - filled;
    blknum++;
    
    while(blknum < last_full_blknum) {
        blk_pointer = get_blk_pointer(&(inode->blk_pointers), blknum);
        if(blk_pointer == -1) return -1;
        memcpy(block, buf, BLKSIZ);
        write_blocks(blk_pointer, 1, block);
        
        buf += BLKSIZ;
        blknum++;
    }
    
    blk_pointer = get_blk_pointer(&(inode->blk_pointers), blknum);
    if(blk_pointer == -1) return -1;
    read_blocks(blk_pointer, 1, block);
    memcpy(block, buf, last_block_bytes);
    write_blocks(blk_pointer, 1, block);
    
    inode->size = max(rw_pointer + length, inode->size);
    fd_table[fileID].rw_pointer = rw_pointer + length;
    return length;
}
Пример #24
0
/* given logical block number, allocate a new physical block, if it does not
 * exist already, and return the physical block number that is allocated.
 * returns negative value on error. */
 static int
 testfs_allocate_block(struct inode *in, int log_block_nr, char *block)
 {
 	if (log_block_nr>4196361)
 		return -EFBIG;
 	// //printf("log_block_nr:%d\n",log_block_nr);
 	// }

 	int phy_block_nr;
 	char indirect[BLOCK_SIZE];
 	char dindirect[BLOCK_SIZE];
 	char dindirect2[BLOCK_SIZE];
 	int indirect_allocated = 0;
 	//int dindirect_allocated = 0;
 	
 	assert(log_block_nr >= 0);
 	phy_block_nr = testfs_read_block(in, log_block_nr, block);

	/* phy_block_nr > 0: block exists, so we don't need to allocate it, 
	   phy_block_nr < 0: some error */
 	if (phy_block_nr != 0)
 		return phy_block_nr;

	/* allocate a direct block */
 	if (log_block_nr < NR_DIRECT_BLOCKS) {
 		assert(in->in.i_block_nr[log_block_nr] == 0);
 		phy_block_nr = testfs_alloc_block_for_inode(in);
 		if (phy_block_nr >= 0) {
 			in->in.i_block_nr[log_block_nr] = phy_block_nr;
 		}
 		return phy_block_nr;
 	}

 	log_block_nr -= NR_DIRECT_BLOCKS;

 	if (log_block_nr >= NR_INDIRECT_BLOCKS)
 	{
 	
 		log_block_nr -= NR_INDIRECT_BLOCKS; //log block ranges from 0 ~ 4194303
 		
 		int level1_block = DIVROUNDUP(log_block_nr+1,2048) - 1;   // ranges 0~2047
 		
 		int level2_block= log_block_nr % 2048;

 		/* allocate an dindirect block */
 		if (in->in.i_dindirect == 0) 	
 		{	
 			bzero(dindirect, BLOCK_SIZE);
 			phy_block_nr = testfs_alloc_block_for_inode(in);
 			if (phy_block_nr < 0)
 				return phy_block_nr;
 			//dindirect_allocated = 1;
 			in->in.i_dindirect = phy_block_nr;
 			//printf("dindirect block #:%d\n",phy_block_nr);
 		}

 		else   /* read dindirect block */
 		{
 			read_blocks(in->sb, dindirect, in->in.i_dindirect, 1); 
 		}



 		// Allocate 2nd level indirect block
 		if (((int *)dindirect)[level1_block] == 0)
 		{
 			bzero(dindirect2, BLOCK_SIZE);
 			phy_block_nr = testfs_alloc_block_for_inode(in);
 			if (phy_block_nr < 0)
 				return phy_block_nr;
 			((int*)dindirect)[level1_block]=phy_block_nr;
	 		//printf("2nd dindirect block #:%d\n", ((int*)dindirect)[level1_block]);
 			write_blocks(in->sb, dindirect, in->in.i_dindirect,1);
 		}

 		// error here....
 		// Read 2nd level indirect block
 		else 
 		{	
 			read_blocks(in->sb, dindirect2, ((int*)dindirect)[level1_block], 1);
 		}


 		// allocate direct block */
 		phy_block_nr=testfs_alloc_block_for_inode(in);


	 	if (phy_block_nr >=0)  // update 2nd level indirect block
	 	{
	 		((int*)dindirect2)[level2_block]=phy_block_nr;
	 		//printf("Last direct block #:%d\n", ((int*)dindirect2)[level2_block]);
	 		write_blocks(in->sb, dindirect2, ((int*)dindirect)[level1_block], 1);
	 	}
	 	
	 	return phy_block_nr;
 		// Allocate 2nd-level indirect block

	 }

 	/**** Allocating in 1st level indirect blocks ****/

	if (in->in.i_indirect == 0) 	/* allocate an indirect block */
	 {	
	 	bzero(indirect, BLOCK_SIZE);
	 	phy_block_nr = testfs_alloc_block_for_inode(in);
	 	if (phy_block_nr < 0)
	 		return phy_block_nr;
	 	indirect_allocated = 1;
	 	in->in.i_indirect = phy_block_nr;
	 } 

	 else 
	{	/* read indirect block */
	 	read_blocks(in->sb, indirect, in->in.i_indirect, 1);
	}

	/* allocate direct block */
	assert(((int *)indirect)[log_block_nr] == 0);	
	phy_block_nr = testfs_alloc_block_for_inode(in);

	if (phy_block_nr >= 0) {
		/* update indirect block */
		((int *)indirect)[log_block_nr] = phy_block_nr;
		write_blocks(in->sb, indirect, in->in.i_indirect, 1);
	} 

	else if (indirect_allocated) 
	{
		/* free the indirect block that was allocated */
		testfs_free_block_from_inode(in, in->in.i_indirect);
	}

	return phy_block_nr;

}
Пример #25
0
void mksfs(int fresh){
	int freeSpace;
	int FATSize;
	int dirSize;
        int i;
        int j;
	char *buffer1;
	blockSize = BLOCK_SIZE;
	numBlocks = NUM_BLOCKS;
	maximummyfiles = MAX_myfileS;
	buffer1 = (char *) malloc(1024);

	if(fresh != 0){//create a new sfs

		init_disk("s2.dsk", blockSize, numBlocks);
		init_cache(0);
		for(i=0; i<maximummyfiles; i++){
			strcpy(directory[i].name, "empty_myfile");
			directory[i].size = 0;
			directory[i].date = 0;
			directory[i].indFAT = -1;
		}

		for(i=0; i<numBlocks; i++){
			for(j=0; j<2; j++) FAT[i][j] = -2;
			}

		for(i=0; i<numBlocks; i++){
			free_list[i] = '0';
		}
		free_list[0] = '1';
		free_list[1] = '1';
		free_list[numBlocks - 1] = '1';

		//set FDT settings
		for(i=0; i<maximummyfiles; i++){
			FDT[i].dirIndex = -1;
		}

		dirSize = sizeof(entry) * maximummyfiles;
		FATSize = sizeof(int) * numBlocks * 2;
		freeSpace = sizeof(char) * numBlocks;

		while(dirSize>0){
			if(dirSize>1024){
				memcpy(buffer1, directory, 1024);
			}
			else {
				memcpy(buffer1, directory, dirSize);
			}
			write_blocks(0, 1, buffer1);
			dirSize -= 1024;
		}

		while(FATSize>0){
			if(FATSize>1024){
				memcpy(buffer1, FAT, 1024);
			}
			else {
				memcpy(buffer1, FAT, FATSize);
			}
			write_blocks(1, 1, buffer1);
			FATSize -= 1024;
		}

		while(freeSpace>0){
			if(freeSpace>1024){
				memcpy(buffer1, free_list, 1024);
			}
			else {
				memcpy(buffer1, free_list, freeSpace);
			}
			write_blocks(1023, 1, buffer1);
			freeSpace -= 1024;
		}

		printf("SFS created successfully\n");
	}

	else{ // load existing sfs

		for(i=0; i<maximummyfiles; i++){
			FDT[i].dirIndex = -1;
		}

		read_blocks(0, 1, buffer1);
		memcpy(directory,buffer1, 1024);
		read_blocks(1, 1, buffer1);
		memcpy(FAT,buffer1, 1024);
		read_blocks(1023, 1, buffer1);
		memcpy(free_list,buffer1, 1024);
		printf("SFS loading successfull\n");


	}

	
	read_blocks(0, 1, buffer1);

	memcpy(directory,buffer1, 1024);

	read_blocks(1, 1, buffer1);
	memcpy(FAT,buffer1, 1024);

	read_blocks(1023, 1, buffer1);
	memcpy(free_list,buffer1, 1024);
}