Пример #1
0
static void sync_inode(int inode_index,INODE inode){
#ifdef DEBUG_FS
        printl("inode_index=%d(in sync_inode)\n",inode_index);
#endif
        int inode_first_index=get_inode_first_index(super_block);
        int off=inode_index*INODE_SIZE;
        u8 fsbuf[SECTOR_SIZE];
        
        inode_first_index+=off/SECTOR_SIZE;
        off=off%SECTOR_SIZE;
        
        rw_sector(INFO_FS_READ,
            ROOT_DEVICE,
            (inode_first_index)*SECTOR_SIZE,
            SECTOR_SIZE,
            TASK_FS,
            fsbuf);
        
        memcpy(fsbuf+off,&inode,INODE_SIZE);

        rw_sector(INFO_FS_WRITE,
            ROOT_DEVICE,
            (inode_first_index)*SECTOR_SIZE,
            SECTOR_SIZE,
            TASK_FS,
            fsbuf);
}
Пример #2
0
static void free_imap_bit(int bits_index){

    u8 fsbuf[SECTOR_SIZE];
    int sector_index,sector_length,bits_off;

    sector_index=get_imap_first_index(super_block)+bits_index/BITS_PER_SECTOR;
    sector_length=1;
    bits_off=bits_index%BITS_PER_SECTOR;

    //读取smap数据
    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              sector_index*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);

    /* printl("sector_index=%d sector_length=%d fsbuf=%c (in free_imap_bit)\n",sector_index,sector_length,*(char*)fsbuf[bits_off/BITS_PER_BYTE]); */
    fsbuf[bits_off/BITS_PER_BYTE] &=~(1<<bits_index%BITS_PER_BYTE); 
/* #ifdef DEBUG_FS */
    /* printl("bits_off/BITS_PER_BYTE=%d bits_index%BITS_PER_BYTE=%d fsbuf=%c(in free_imap_bit)\n",bits_off/BITS_PER_BYTE,bits_index%BITS_PER_BYTE,*(char*)fsbuf[bits_off/BITS_PER_BYTE]); */
/* #endif */
    rw_sector(INFO_FS_WRITE,
              ROOT_DEVICE,
              sector_index*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);
}
Пример #3
0
/*
first_sector_index:该文件的起始扇区编号(相对于data_block起始位置的偏移)
sector_length:分配给该文件的扇区数
*/
static BOOL new_inode(int inode_index,int file_type,int first_sector_index,int sector_length){
    int new_inode_sector_index=get_inode_first_index(super_block)+(inode_index*INODE_SIZE)/SECTOR_SIZE;
    int off=(inode_index*INODE_SIZE)%SECTOR_SIZE;
    u8 fsbuf[SECTOR_SIZE];

    /* printl("data_index=%d(in new_inode)\n",new_inode_sector_index); */

    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (new_inode_sector_index)*SECTOR_SIZE,
              SECTOR_SIZE,
              TASK_FS,
              fsbuf);

    INODE *pinode=(INODE*)(fsbuf+off);
    pinode->i_mode=file_type;
    pinode->i_size=0;
    pinode->i_start_sector_index=first_sector_index;
    pinode->i_sectors_length=sector_length;
    /* printl("first_sector_index=%d sector_length=%d (in new_inode)\n",first_sector_index,sector_length); */

    sync_sectors(new_inode_sector_index,1,fsbuf); 
    
    return TRUE;
}
Пример #4
0
//目前仅支持文件长度为1扇区固定大小,即data_sector_length=1
static int alloc_smap_bit(int dev,int data_sector_length){
    assert(data_sector_length==1,"only for data_sector_length=1 currently!");

    int smap_first_index=get_smap_first_index(super_block);
    int smap_length=get_smap_length(super_block);
    u8 fsbuf[SECTOR_SIZE];
    int off, byte_index,bit_index;

    for(off=0;off<smap_length;off++){
        memset(fsbuf,0,SECTOR_SIZE);
        
        int sector_index=(smap_first_index+off);
        rw_sector(INFO_FS_READ,
                  ROOT_DEVICE,
                  sector_index*SECTOR_SIZE,
                  SECTOR_SIZE,
                  TASK_FS,
                  fsbuf);
        for(byte_index=0;byte_index<SECTOR_SIZE;byte_index++){
            if(fsbuf[byte_index]!=0xFF)
                break;
        }
        for(bit_index=0;bit_index<BITS_PER_BYTE;bit_index++){
            if((fsbuf[byte_index] & (1<<bit_index))==0){
                fsbuf[byte_index]=fsbuf[byte_index] | (1<<bit_index);
                sync_sectors(sector_index,1,fsbuf);
                return (off*SECTOR_SIZE+byte_index)*BITS_PER_BYTE+bit_index;
            }
        }
    }
    return -1;
}
Пример #5
0
static void sync_sectors(int sector_index,int sector_length,u8 *data){
    /* printl("sector_index=%d(in sync_sectors)\n",sector_index); */
    rw_sector(INFO_FS_WRITE,
              ROOT_DEVICE,
              (sector_index)*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              data);
}
Пример #6
0
static void get_super_block(int dev,SUPER_BLOCK *super_block){
    u8 fsbuf[SECTOR_SIZE];
    int super_block_first_index=BOOT_SECTORS_LENGTH;
    /* READ_SECTOR(ROOT_DEVICE,fsbuf,super_block_first_index); */
    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (super_block_first_index)*SECTOR_SIZE,
              SUPER_BLOCK_SIZE,
              TASK_FS,
              fsbuf);
    
    memcpy(super_block,fsbuf,SUPER_BLOCK_SIZE);
}
Пример #7
0
static BOOL remove_dir_entry(const char *dir_name,int inode_index){
    INODE dir_inode;

    get_dir_inode_by_name(dir_name,&dir_inode);
    assert(dir_inode.i_mode==I_DIRECTORY,"must be directory");

    DIR_ENTRY *dir_entry;
    int length=dir_inode.i_size;
    int sector_length=(length+SECTOR_SIZE-1)/SECTOR_SIZE;
    int dir_entry_count=(dir_inode.i_size)/DIR_ENTRY_SIZE;
    int dir_entry_index;
    u8 fsbuf[SECTOR_SIZE*2];
    
    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (dir_inode.i_start_sector_index)*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);
    
    for(dir_entry_index=0;dir_entry_index<dir_entry_count;dir_entry_index++){
        dir_entry=(DIR_ENTRY *)(fsbuf+dir_entry_index*DIR_ENTRY_SIZE);
/* #ifdef DEBUG_FS */
/*         printl("dir_entry->inode_index=%d ",dir_entry->inode_index); */
/* #endif */
        if(dir_entry->inode_index==inode_index){/*目录项inode_index=0表示该目录项为空*/
            dir_entry->inode_index=0;
            rw_sector(INFO_FS_WRITE,
                      ROOT_DEVICE,
                      (dir_inode.i_start_sector_index)*SECTOR_SIZE,
                      sector_length*SECTOR_SIZE,
                      TASK_FS,
                      fsbuf);
            return TRUE;
        }
    }
    return FALSE;
}
Пример #8
0
static BOOL new_dir_entry(const char *dir_name,int inode_index,const char *filename){

    INODE dir_inode;
    int dir_inode_index;
    dir_inode_index=get_dir_inode_by_name(dir_name,&dir_inode);

    assert(dir_inode.i_mode==I_DIRECTORY,"must be directory");

    DIR_ENTRY *dir_entry;
    int length=dir_inode.i_size;
    int sector_length=(length+SECTOR_SIZE-1)/SECTOR_SIZE;
    int dir_entry_count=(dir_inode.i_size)/DIR_ENTRY_SIZE;
    int dir_entry_index;
    u8 fsbuf[SECTOR_SIZE*2];
    BOOL find=FALSE;
    
    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (dir_inode.i_start_sector_index)*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);
    
    for(dir_entry_index=0;dir_entry_index<dir_entry_count;dir_entry_index++){
        dir_entry=(DIR_ENTRY *)(fsbuf+dir_entry_index*DIR_ENTRY_SIZE);
/* #ifdef DEBUG_FS */
/*         printl("dir_entry->inode_index=%d ",dir_entry->inode_index); */
/* #endif */
        if(dir_entry->inode_index==0){/*目录项inode_index=0表示该目录项为空*/
            find=TRUE;
            break;
        }
    }
    
    if((!find) && 
       ((dir_inode.i_size+DIR_ENTRY_SIZE) <= (dir_inode.i_sectors_length*SECTOR_SIZE))){
        dir_entry=(DIR_ENTRY *)(fsbuf+dir_entry_index*DIR_ENTRY_SIZE);
        dir_inode.i_size=dir_inode.i_size+DIR_ENTRY_SIZE;
        sync_inode(dir_inode_index,dir_inode);
        find=TRUE;
    }
    if(find){
        dir_entry->inode_index=inode_index;
        strcpy(dir_entry->name,filename);
        sync_sectors(dir_inode.i_start_sector_index,sector_length,fsbuf);//更新硬盘数据
        
        return TRUE;
    }
    return FALSE;
}
Пример #9
0
/*
根据inode_index获得对应的inode
*/
static int get_inode_by_index(int inode_index,INODE *p_inode){
    int inode_first_index=get_inode_first_index(super_block);
    int off=inode_index*INODE_SIZE;
    u8 fsbuf[SECTOR_SIZE];

    inode_first_index+=off/SECTOR_SIZE;
    off=off%SECTOR_SIZE;
    
    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (inode_first_index)*SECTOR_SIZE,
              SECTOR_SIZE,
              TASK_FS,
              fsbuf);
    memcpy(p_inode,fsbuf+off,INODE_SIZE);
    
    return inode_index;
}
Пример #10
0
//有问题:调用的rw_sector中读取数据长度必须为SECTOR_SIZE的整数倍
//该函数还发现一个问题:如果fsbuf为全局静态变量,由于开始读目录内容填充了fsbuf,然后在比较的时候又读取了硬盘,再次填充了fsbuf,导致之前的数据被覆盖。所以fsbuf还是设定成局部变量。
//切忌:尽量减少全局变量的使用。
static int get_inode_by_name(const char *dir_name,const char *file_name,int file_type,INODE *p_inode){
    INODE dir_inode;
    DIR_ENTRY *dir_entry;
    int dir_entry_index;
    int dir_entry_count;
    u8 fsbuf[SECTOR_SIZE*2];
    
    if(get_dir_inode_by_name(dir_name,&dir_inode)<0){
        set_error_index(DIR_NOT_EXIST);
        return -1;
    }
    dir_entry_count=dir_inode.i_size/DIR_ENTRY_SIZE; 

    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (dir_inode.i_start_sector_index)*SECTOR_SIZE,
              dir_inode.i_size,
              TASK_FS,
              fsbuf);

    for(dir_entry_index=0;dir_entry_index<dir_entry_count;dir_entry_index++){
        dir_entry=(DIR_ENTRY *)(fsbuf+dir_entry_index*DIR_ENTRY_SIZE);

/* #ifdef DEBUG_FS */
/*         printl("dir_index=%d dir_name=%s filename=%s cmp=%d\n", */
/*                dir_entry->inode_index, */
/*                dir_entry->name, */
/*                file_name, */
/*                strcmp(dir_entry->name,file_name)==0); */
/* #endif */
        //此处的dir_entry->inode_index=0:表示该文件建立后删除了
        if(dir_entry->inode_index>0 && strcmp(dir_entry->name,file_name)==0){
            if(get_inode_by_index(dir_entry->inode_index,p_inode)){
                if((p_inode->i_mode & file_type) !=0){
                    /* printl("get inode by name data_sector_index=%d\n",p_inode->i_start_sector_index); */
                    return dir_entry->inode_index;
                }
            }
        }
    }
    set_error_index(FILE_NOT_EXIST);
    return -1;
}
Пример #11
0
static void/* int */ do_read(MESSAGE *message){
    char fsbuf[SECTOR_SIZE*DEFAULT_FILE_SECTOR_LENGTH];
    char *buf;
    int start_position,sector_length,length,data_sector_index;
    PROCESS *process;
    struct s_file_descriptor* pfd;

    process=pid2process(message->source_pid);
    pfd=process->file_descriptor[message->fd];
    if((pfd->fd_op_mode & O_RDONLY)==0 && (pfd->fd_op_mode & O_RDWR)==0){
        set_error_index(FILE_CANNOT_READ);
        message->length=-1;
        return;
    }
    buf=message->res_pointer;
    start_position=pfd->fd_position;
    if(start_position > pfd->fd_inode->i_size){
        set_error_index(END_OF_FILE);
        message->length=-1;
        return;
    }
    assert(start_position<=pfd->fd_inode->i_size,"file read over");
    length=min(start_position+message->length,pfd->fd_inode->i_size);
    sector_length=(length+SECTOR_SIZE-1)/SECTOR_SIZE;
    data_sector_index=pfd->fd_inode->i_start_sector_index;
    
    /* printl("data_sector_index=%d sector_length=%d\n",data_sector_index,sector_length); */

    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (data_sector_index)*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);
    strncpy(buf,fsbuf+start_position,length-start_position);

    pfd->fd_position=length;
    
    message->length=length-start_position;  
}
Пример #12
0
/*
返回目录下文件/目录的个数
*/
static int get_filename_in_dir(const char* dir_name,char *files){
    INODE dir_inode;
    DIR_ENTRY *dir_entry;
    int dir_entry_index;
    int dir_entry_count;
    int files_index,files_off;
    u8 fsbuf[SECTOR_SIZE*2];
    
    if(get_dir_inode_by_name(dir_name,&dir_inode)<0){
        set_error_index(DIR_NOT_EXIST);
        return -1;
    }
    dir_entry_count=dir_inode.i_size/DIR_ENTRY_SIZE; 

    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              (dir_inode.i_start_sector_index)*SECTOR_SIZE,
              dir_inode.i_size,
              TASK_FS,
              fsbuf);

    files_off=0;
    files_index=0;
    for(dir_entry_index=0;dir_entry_index<dir_entry_count;dir_entry_index++){
        dir_entry=(DIR_ENTRY *)(fsbuf+dir_entry_index*DIR_ENTRY_SIZE);
        //此处的dir_entry->inode_index=0:表示该文件建立后删除了
        if(dir_entry->inode_index>0){
            strcpy(files+files_off,dir_entry->name);
#ifdef DEBUG_FS
            printl("%d:%s\n",files_index,files+files_off);
#endif
            files_off+=strlen(dir_entry->name)+1;
            files_index++;
        }
    }
    return files_index;
}
Пример #13
0
/**
 * Read/Write file and return byte count read/written.
 *
 * Sector map is not needed to update, since the sectors for the file have been
 * allocated and the bits are set when the file was created.
 * 
 * @return How many bytes have been read/written.
 *****************************************************************************/
PUBLIC int do_rdwt(MESSAGE * msg,struct TASK *pcaller)
{
	MESSAGE fs_msg = *msg;
	int fd = msg->FD;	/**< file descriptor. */
	void * buf = fs_msg.BUF;/**< r/w buffer */
	int len = fs_msg.CNT;	/**< r/w bytes */

	int src = fs_msg.source;		/* caller proc nr. */
	debug("pos of fd[%d] = %d, inode_number = %d",fd,pcaller->filp[fd]->fd_pos,pcaller->filp[fd]->fd_inode->i_num);
	//sprintf(str,"fd = %d, len = %d", fd, len);
	assert((pcaller->filp[fd] >= &f_desc_table[0]) &&
	       (pcaller->filp[fd] < &f_desc_table[NR_FILE_DESC]));

	//if (!(pcaller->filp[fd]->fd_mode & O_RDWR))
	//	return -1;

	int pos = pcaller->filp[fd]->fd_pos;

	struct inode * pin = pcaller->filp[fd]->fd_inode;
	debug("pin->i_size = %d",pin->i_size);
	//int imode = pin->i_mode & I_TYPE_MASK;
	debug("imode = %d", pin->i_mode);
	assert( (pin >= &inode_table[0] && pin < &inode_table[NR_INODE]) || pin->i_mode == I_CHAR_SPECIAL );
	
	if (pin->i_mode == I_CHAR_SPECIAL) {
		assert((fs_msg.type == READ) || (fs_msg.type == WRITE));

		struct CONSOLE *cons = pcaller->cons;
		if(cons == NULL)
			return 0;

		struct SHEET *sht = cons->sht;
		if(sht == NULL)
			return 0;

		if(fs_msg.type == READ){
			char *charBuf = (char *)buf;
			int ch = read_from_keyboard(pcaller, 1);
			if( ch == -1){
				charBuf[0] = 0;
			}else{
				charBuf[0] = ch;
				charBuf[1] = 0;
			}
		}else{
			
			char *msg = (char *)buf;
			msg[len] = 0;
			cons_putstr0(cons, msg);
		}
		return strlen(buf);
	}
	else {
		assert(pin->i_mode == I_REGULAR || pin->i_mode == I_DIRECTORY);
		assert((fs_msg.type == READ) || (fs_msg.type == WRITE));

		int pos_end;
		if (fs_msg.type == READ){
			if( pos == pin->i_size)
				return -1;
			pos_end = min(pos + len, pin->i_size);
		}
		else		/* WRITE */
			pos_end = min(pos + len, pin->i_nr_sects * SECTOR_SIZE);

		debug("pin->i_size = %d, pos_end = %d",pin->i_size, pos_end);
		
		int off = pos % SECTOR_SIZE;
		int rw_sect_min=pin->i_start_sect+(pos>>SECTOR_SIZE_SHIFT);
		int rw_sect_max=pin->i_start_sect+(pos_end>>SECTOR_SIZE_SHIFT);

		int chunk = min(rw_sect_max - rw_sect_min + 1,
				FSBUF_SIZE >> SECTOR_SIZE_SHIFT);

		int bytes_rw = 0;
		int bytes_left = len;
		int i;

		for (i = rw_sect_min; i <= rw_sect_max; i += chunk) {
			/* read/write this amount of bytes every time */
			int bytes = min(bytes_left, chunk * SECTOR_SIZE - off);
			debug("bytes = %d",bytes);
			rw_sector(DEV_READ,
				  pin->i_dev,
				  i * SECTOR_SIZE,
				  chunk * SECTOR_SIZE,
				  -1,
				  fsbuf);

			if (fs_msg.type == READ) {
				phys_copy((void*)va2la(src, buf + bytes_rw),
					  (void*)va2la(-1, fsbuf + off),
					  bytes);
			}
			else {	/* WRITE */
				
				phys_copy((void*)va2la(-1, fsbuf + off),
					  (void*)va2la(src, buf + bytes_rw),
					  bytes);

				rw_sector(DEV_WRITE,
					  pin->i_dev,
					  i * SECTOR_SIZE,
					  chunk * SECTOR_SIZE,
					  -1,
					  fsbuf);
			}
			off = 0;
			bytes_rw += bytes;
			pcaller->filp[fd]->fd_pos += bytes;
			debug("pos of fd[%d] = %d",fd,pcaller->filp[fd]->fd_pos);
			
			bytes_left -= bytes;
		}

		if (pcaller->filp[fd]->fd_pos > pin->i_size) {
			/* update inode::size */
			pin->i_size = pcaller->filp[fd]->fd_pos;

			/* write the updated i-node back to disk */
			sync_inode(pin);
		}
		
		pcaller->filp[fd]->fd_pos += bytes_rw;
		return bytes_rw;
	}
}
Пример #14
0
static void free_smap_bit(int bits_index,int bits_length){
    assert(bits_length==1,"only for sector_length=1 currently!");

#ifdef DEBUG_FS
    printl("bits_index=%d bits_length=%d(int free_smap_bit)\n",bits_index,bits_length);
#endif

    u8 fsbuf[SECTOR_SIZE];
    int sector_index,sector_length,bits_off, bytes_index,bytes_start,bytes_end;

    sector_index=get_smap_first_index(super_block)+bits_index/BITS_PER_SECTOR;
    sector_length=(bits_index+bits_length+BITS_PER_SECTOR-1)/BITS_PER_SECTOR;
    bits_off=bits_index%BITS_PER_SECTOR;
    bytes_start=(bits_off+BITS_PER_BYTE-1)/BITS_PER_BYTE;
    bytes_end=(bits_off+bits_length)/BITS_PER_BYTE;
#ifdef DEBUG_FS
    printl("bytes_start=%d bytes_end=%d (in fre_smap_bit)\n",bytes_start,bytes_end);
#endif    

    //读取smap数据
    rw_sector(INFO_FS_READ,
              ROOT_DEVICE,
              sector_index*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);
    /*分为三步处理:
      bits:           -------------------------------------------------
                         |  |  |                          |   |   |
      bits_index         8m ^   8(m+1)                   8n   ^   8(n+1)
      step:                | 1|            2             | 3 |
     */
    for(bits_index=bits_off;bits_index%BITS_PER_BYTE!=0 && bits_index<bits_off+bits_length;bits_index++){
#ifdef DEBUG_FS
        printl("bits_index=%d(step 1. in fre_smap_bit)",bits_index);
#endif
        fsbuf[bits_index/BITS_PER_BYTE] &=~(1<<bits_index%BITS_PER_BYTE); 
    }
#ifdef DEBUG_FS
    printl("\n");
#endif
    for(bytes_index=bytes_start;bytes_index<bytes_end;bytes_index++){
#ifdef DEBUG_FS
        printl("bytes_index=%d(step 2. in fre_smap_bit)",bytes_index);
#endif
        fsbuf[bytes_index]=0;
    }
#ifdef DEBUG_FS
    printl("\n");
#endif
    if(bytes_start<bytes_end){/*需要step3操作的情况*/
        for(bits_index=bytes_end*BITS_PER_BYTE;bits_index<bits_off+bits_length;bits_index++){
#ifdef DEBUG_FS
            printl("bits_index=%d(step 3. in fre_smap_bit)",bits_index);
#endif
            fsbuf[bits_index/BITS_PER_BYTE] &=~(1<<bits_index%BITS_PER_BYTE); 
        }
    }
/* #ifdef DEBUG_FS */
    printl("\n");
/* #endif */

    //更新smap数据
    rw_sector(INFO_FS_WRITE,
              ROOT_DEVICE,
              sector_index*SECTOR_SIZE,
              sector_length*SECTOR_SIZE,
              TASK_FS,
              fsbuf);
}
Пример #15
0
static /* int */void do_write(MESSAGE *message){
    u8 fsbuf[SECTOR_SIZE*DEFAULT_FILE_SECTOR_LENGTH];
    const char *buf;
    int start_position,sector_length,length,data_sector_index;
    PROCESS *process;
    struct s_file_descriptor* pfd;

    process=pid2process(message->source_pid);
    if(message->fd==STDOUT && process->file_descriptor[message->fd]==NULL){
#ifdef DEBUG_FS
        printl("pid=%d (in do_write)\n",message->source_pid);
#endif
/*pfd->fd_inode->i_mode & I_CHAR_SPECIAL !=0*/
        /* int device=pfd->fd_inode->i_start_sector_index; */
        message->process_index=message->source_pid;
        send_receive(SEND,TASK_TTY/* dd_map[DRIVER(device)] */,message);
        /* message->type=INFO_SUSPEND_PROCESS; */
    }else{
        
        pfd=process->file_descriptor[message->fd];
        if((pfd->fd_op_mode & O_WRONLY)==0 && (pfd->fd_op_mode & O_RDWR)==0){
            set_error_index(FILE_CANNOT_WRITE);
            message->length=-1;
            return;
        }
        buf=message->arg_pointer;
        
        start_position=pfd->fd_position;
        if(start_position >= pfd->fd_inode->i_sectors_length*SECTOR_SIZE){
            set_error_index(FILE_ALLOC_MEM_USEUP);
            message->length=-1;
            return;
        }
        length=min(start_position+message->length,pfd->fd_inode->i_sectors_length*SECTOR_SIZE);
        sector_length=(length+SECTOR_SIZE-1)/SECTOR_SIZE;
        data_sector_index=pfd->fd_inode->i_start_sector_index;
        
#ifdef DEBUG_FS
        /* printl("1 %d %d length=%d\n",start_position,message->length,length); */
        printl("sector_index=%d sector_length=%d(in do_write)\n",data_sector_index,sector_length);
#endif
        rw_sector(INFO_FS_READ,
                  ROOT_DEVICE,
                  (data_sector_index)*SECTOR_SIZE,
                  sector_length*SECTOR_SIZE,
                  TASK_FS,
                  fsbuf);
        memcpy(fsbuf+start_position,buf,length-start_position);
        /* printl("2 %d %d\n",data_sector_index,length); */
        rw_sector(INFO_FS_WRITE,
                  ROOT_DEVICE,
                  (data_sector_index)*SECTOR_SIZE,
                  sector_length*SECTOR_SIZE,
                  TASK_FS,
                  fsbuf);
        
        /* printl("3 inode.i_size=%d\n",pfd->fd_inode->i_size); */
        pfd->fd_inode->i_size=length;
        /* printl("inode_index=%d\n",pfd->fd_inode->i_inode_index); */
        sync_inode(pfd->fd_inode->i_inode_index,*(pfd->fd_inode));
        
        pfd->fd_position=length;  
        message->length=length-start_position;
    }
}
Пример #16
0
/**
 * <Ring 1> This routine handles the DEV_LOG message.
 * 
 * @param p  Ptr to the MESSAGE.
 *****************************************************************************/
PUBLIC int disklog(char * logstr)
{
	int device = root_inode->i_dev;
	struct super_block * sb = get_super_block(device);
	int nr_log_blk0_nr = sb->nr_sects - NR_SECTS_FOR_LOG; /* 0x9D41-0x800=0x9541 */

	static int pos = 0;
	if (!pos) { /* first time invoking this routine */

#ifdef SET_LOG_SECT_SMAP_AT_STARTUP
		/*
		 * set sector-map so that other files cannot use the log sectors
		 */

		int bits_per_sect = SECTOR_SIZE * 8; /* 4096 */

		int smap_blk0_nr = 1 + 1 + sb->nr_imap_sects; /* 3 */
		int sect_nr  = smap_blk0_nr + nr_log_blk0_nr / bits_per_sect; /* 3+9=12 */
		int byte_off = (nr_log_blk0_nr % bits_per_sect) / 8; /* 168 */
		int bit_off  = (nr_log_blk0_nr % bits_per_sect) % 8; /* 1 */
		int sect_cnt = NR_SECTS_FOR_LOG / bits_per_sect + 2; /* 1 */
		int bits_left= NR_SECTS_FOR_LOG; /* 2048 */

		int i;
		for (i = 0; i < sect_cnt; i++) {
			RD_SECT(device, sect_nr + i); /* RD_SECT(?, 12) */

			for (; byte_off < SECTOR_SIZE && bits_left > 0; byte_off++) {
				for (; bit_off < 8; bit_off++) { /* repeat till enough bits are set */
					assert(((fsbuf[byte_off] >> bit_off) & 1) == 0);
					fsbuf[byte_off] |= (1 << bit_off);
					if (--bits_left  == 0)
						break;
				}
				bit_off = 0;
			}
			byte_off = 0;
			bit_off = 0;

			WR_SECT(device, sect_nr + i);

			if (bits_left == 0)
				break;
		}
		assert(bits_left == 0);
#endif /* SET_LOG_SECT_SMAP_AT_STARTUP */

		pos = 0x40;

#ifdef MEMSET_LOG_SECTS
		/* write padding stuff to log sectors */
		int chunk = min(MAX_IO_BYTES, FSBUF_SIZE >> SECTOR_SIZE_SHIFT);
		assert(chunk == 256);
		int sects_left = NR_SECTS_FOR_LOG;
		for (i = nr_log_blk0_nr;
		     i < nr_log_blk0_nr + NR_SECTS_FOR_LOG;
		     i += chunk) {
			memset(fsbuf, 0x20, chunk*SECTOR_SIZE);
			rw_sector(DEV_WRITE,
				  device,
				  i * SECTOR_SIZE,
				  chunk * SECTOR_SIZE,
				  TASK_FS,
				  fsbuf);
			sects_left -= chunk;
		}
		if (sects_left != 0)
			panic("sects_left should be 0, current: %d.", sects_left);
#endif /* MEMSET_LOG_SECTS */
	}
Пример #17
0
/**
 * Read/Write file and return byte count read/written.
 *
 * Sector map is not needed to update, since the sectors for the file have been
 * allocated and the bits are set when the file was created.
 * 
 * @return How many bytes have been read/written.
 *****************************************************************************/
PUBLIC int do_rdwt()
{
	int fd = fs_msg.FD;	/**< file descriptor. */
	void * buf = fs_msg.BUF;/**< r/w buffer */
	int len = fs_msg.CNT;	/**< r/w bytes */

	int src = fs_msg.source;		/* caller proc nr. */

	assert((pcaller->filp[fd] >= &f_desc_table[0]) &&
	       (pcaller->filp[fd] < &f_desc_table[NR_FILE_DESC]));

	if (!(pcaller->filp[fd]->fd_mode & O_RDWR))
		return -1;

	int pos = pcaller->filp[fd]->fd_pos;

	struct inode * pin = pcaller->filp[fd]->fd_inode;

	assert(pin >= &inode_table[0] && pin < &inode_table[NR_INODE]);

	int imode = pin->i_mode & I_TYPE_MASK;

	if (imode == I_CHAR_SPECIAL) {
		int t = fs_msg.type == READ ? DEV_READ : DEV_WRITE;
		fs_msg.type = t;

		int dev = pin->i_start_sect;
		assert(MAJOR(dev) == 4);

		fs_msg.DEVICE	= MINOR(dev);
		fs_msg.BUF	= buf;
		fs_msg.CNT	= len;
		fs_msg.PROC_NR	= src;
		assert(dd_map[MAJOR(dev)].driver_nr != INVALID_DRIVER);
		send_recv(BOTH, dd_map[MAJOR(dev)].driver_nr, &fs_msg);
		assert(fs_msg.CNT == len);

		return fs_msg.CNT;
	}
	else {
		assert(pin->i_mode == I_REGULAR || pin->i_mode == I_DIRECTORY);
		assert((fs_msg.type == READ) || (fs_msg.type == WRITE));

		//讀寫不能超過檔案大小
		int pos_end;
		if (fs_msg.type == READ)
			pos_end = min(pos + len, pin->i_size);
		else		/* WRITE */
			pos_end = min(pos + len, pin->i_nr_sects * SECTOR_SIZE);


		//secNum的offset
		int off = pos % SECTOR_SIZE;

		//哪一個sector
		int rw_sect_min=pin->i_start_sect+(pos>>SECTOR_SIZE_SHIFT);

		//結束在那個sector
		int rw_sect_max=pin->i_start_sect+(pos_end>>SECTOR_SIZE_SHIFT);

		//扇區讀寫使用chunk為單位,如果一次buf傳的完的話,就使用rw_sect_max - rw_sect_min + 1
		int chunk = min(rw_sect_max - rw_sect_min + 1,
				FSBUF_SIZE >> SECTOR_SIZE_SHIFT);

		int bytes_rw = 0;
		int bytes_left = len;
		int i;

		for (i = rw_sect_min; i <= rw_sect_max; i += chunk) {
			/* read/write this amount of bytes every time */
			int bytes = min(bytes_left, chunk * SECTOR_SIZE - off);
			rw_sector(DEV_READ,
				  pin->i_dev,
				  i * SECTOR_SIZE,
				  chunk * SECTOR_SIZE,
				  TASK_FS,
				  fsbuf);

			if (fs_msg.type == READ) {
				phys_copy((void*)va2la(src, buf + bytes_rw),
					  (void*)va2la(TASK_FS, fsbuf + off),
					  bytes);
			}
			else {	/* WRITE */
				phys_copy((void*)va2la(TASK_FS, fsbuf + off),
					  (void*)va2la(src, buf + bytes_rw),
					  bytes);

				rw_sector(DEV_WRITE,
					  pin->i_dev,
					  i * SECTOR_SIZE,
					  chunk * SECTOR_SIZE,
					  TASK_FS,
					  fsbuf);
			}
			off = 0;
			bytes_rw += bytes;
			pcaller->filp[fd]->fd_pos += bytes;
			bytes_left -= bytes;
		}

		if (pcaller->filp[fd]->fd_pos > pin->i_size) {
			/* update inode::size */
			pin->i_size = pcaller->filp[fd]->fd_pos;

			/* write the updated i-node back to disk */
			sync_inode(pin);
		}

		return bytes_rw;
	}
}
Пример #18
0
PUBLIC int do_rdwt()
{
    int fd = fs_msg.FD;
    void *buf = fs_msg.BUF;
    int len = fs_msg.CNT;
    int src = fs_msg.source;

    /* 保证 fd 指向的是合法文件描述符 */
    assert((pcaller->filp[fd] >= &f_desc_table[0]) && 
           (pcaller->filp[fd] <  &f_desc_table[NR_FILE_DESC]));

    if (!(pcaller->filp[fd]->fd_mode & O_RDWR))
        return -1;

    int pos = pcaller->filp[fd]->fd_pos;

    struct inode *pin = pcaller->filp[fd]->fd_inode;

    /* 保证 fd 指向的是合法 inode */
    assert(pin >= &inode_table[0] && pin < &inode_table[NR_INODE]);

    int imode = pin->i_mode & I_TYPE_MASK;

    /* 如果是字符设备则交给该设备的驱动处理 */
    if (imode == I_CHAR_SPECIAL) {
        int t = fs_msg.type == READ ? DEV_READ : DEV_WRITE;
        fs_msg.type = t;

        int dev = pin->i_start_sect;
        assert(MAJOR(dev) == 4);

        fs_msg.DEVICE = MINOR(dev);
        fs_msg.BUF = buf;
        fs_msg.CNT = len;
        fs_msg.PROC_NR = src;
        assert(dd_map[MAJOR(dev)].driver_nr != INVALID_DRIVER);
        send_recv(BOTH, dd_map[MAJOR(dev)].driver_nr, &fs_msg);
        assert(fs_msg.CNT == len);

        return fs_msg.CNT;
    }
    /* 普通文件或目录 */
    else {
        assert(pin->i_mode == I_REGULAR || pin->i_mode == I_DIRECTORY);
        assert((fs_msg.type == READ) || (fs_msg.type == WRITE));

        int pos_end;
        if (fs_msg.type == READ)
            pos_end = min(pos + len, pin->i_size);
        else
            pos_end = min(pos + len, pin->i_nr_sects * SECTOR_SIZE);

        int off = pos % SECTOR_SIZE;
        int rw_sect_min = pin->i_start_sect + (pos >> SECTOR_SIZE_SHIFT);
        int rw_sect_max = pin->i_start_sect + (pos_end >> SECTOR_SIZE_SHIFT);

        int chunk = min(rw_sect_max - rw_sect_min + 1, FSBUF_SIZE >> SECTOR_SIZE_SHIFT);

        int bytes_rw = 0;
        int bytes_left = len;
        for (int i = rw_sect_min; i <= rw_sect_max; i += chunk) { // 逐块
            int bytes = min(bytes_left, chunk * SECTOR_SIZE - off);
            rw_sector(
                DEV_READ,
                pin->i_dev,
                i * SECTOR_SIZE,
                chunk * SECTOR_SIZE,
                TASK_FS,
                fsbuf
            );

            if (fs_msg.type == READ) {
                phys_copy(
                    (void *)va2la(src, buf + bytes_rw),
                    (void *)va2la(TASK_FS, fsbuf + off),
                    bytes
                );
            }
            else {
                phys_copy(
                    (void *)va2la(TASK_FS, fsbuf + off),
                    (void *)va2la(src, buf + bytes_rw),
                    bytes
                );
                rw_sector(
                    DEV_WRITE,
                    pin->i_dev,
                    i * SECTOR_SIZE,
                    chunk * SECTOR_SIZE,
                    TASK_FS,
                    fsbuf
                );
            }
            off = 0;
            bytes_rw += bytes;
            pcaller->filp[fd]->fd_pos += bytes;
            bytes_left -= bytes;
        }

        if (pcaller->filp[fd]->fd_pos > pin->i_size) {
            pin->i_size = pcaller->filp[fd]->fd_pos;
            sync_inode(pin);
        }

        return bytes_rw;
    }

    return 0;
}