/* 新建文件: 1.分配inode,设置imap 2.分配data_sector,设置smap 3.新建目录项,更新目录项内容(inode_index,filename) 4.新建inode,更新inode的内容 */ static int create_file(const char *dir_name,const char *file_name,int file_type){ int inode_index=alloc_imap_bit(0); if(inode_index<0){ set_error_index(IMAP_NOT_ENOUGH); return -1; } #ifdef DEBUG_FS printl("inode_index=%d(in create_file)\n",inode_index); #endif int data_index=alloc_smap_bit(0,DEFAULT_FILE_SECTOR_LENGTH);//相对于数据区的sector_index if(data_index<0){ set_error_index(SMAP_NOT_ENOUGH); return -1; } #ifdef DEBUG_FS printl("data_index=%d(in create_file)\n",data_index); #endif data_index+=get_data_block_first_index(super_block);//绝对sector_index #ifdef DEBUG_FS printl("data_index=%d(in create_file)\n",data_index); #endif if(!new_dir_entry(dir_name,inode_index,file_name)){ set_error_index(DIR_CREATE_ERROR); return -1; } if(!new_inode(inode_index,file_type,data_index,DEFAULT_FILE_SECTOR_LENGTH)){ set_error_index(INODE_CREATE_ERROR); return -1; } return inode_index; }
// callback : have received a Pdu from the target host with given read comm str // this is really simplistic, but gives the general idea int agent_impl::handle_get( Pdu &pdu, UdpTarget &target) { ACE_TRACE("agent_impl::handle_get"); OctetStr mgr_rd_str, agent_rd_str; target.get_read_community(mgr_rd_str); // requster's read community string tgt_.get_read_community(agent_rd_str); // this agent's read community string // 1. verify we have a valid read string else drop pdu (no response to caller) if (mgr_rd_str != agent_rd_str) { ACE_DEBUG((LM_DEBUG, "agent_impl::handle_get: invalid read community recvd\n")); return 0; } // 2. iterate over each varbind in the pdu, filling providing responses int fdone = 0; for (int i = 0; (i < pdu.get_vb_count()) && !fdone; i++) { Vb vb; pdu.get_vb(vb, i); if (get_response(vb)) { // set a value for the oid if we can else set_error_status(&pdu, SNMP_ERROR_NO_SUCH_NAME); // these ought to be member set_error_index(&pdu, i); // functions but are not yet... fdone++; // trigger flag to exit loop early } else // failed, return noSuch error pdu.set_vb(vb, i); } // 3. lastly, return the pkt to the caller return respond(pdu, target); }
// return a pdu from a buffer int wpdu::get_pdu(Pdu& pdu, snmp_version& version) { if (iovec_.iov_len == 0) return -1; // NO DATA snmp_pdu *raw_pdu; raw_pdu = cmu_snmp::pdu_create(0); if (!raw_pdu) { return SNMP_CLASS_RESOURCE_UNAVAIL; } // max value a client can send us - TODO: replace this with an // api to get actual string length int status = cmu_snmp::parse( raw_pdu, (unsigned char *)iovec_.iov_base, community_name, comm_len, version, iovec_.iov_len); if (status != 0) return SNMP_CLASS_INTERNAL_ERROR; community_name[comm_len] = 0; // set null based on returned length set_request_id( &pdu, raw_pdu->reqid); set_error_status( &pdu, (int) raw_pdu->errstat); set_error_index( &pdu, (int) raw_pdu->errindex); pdu.set_type( raw_pdu->command); if (restore_vbs(pdu, raw_pdu)) { cmu_snmp::free_pdu(raw_pdu); return SNMP_CLASS_INTERNAL_ERROR; } cmu_snmp::free_pdu(raw_pdu); return 0; }
static BOOL do_create(MESSAGE *message){ const char *path; char dirname[MAX_FILENAME_LENGTH]={0}; char filename[MAX_FILENAME_LENGTH]={0}; int flags,inode_index; path=message->arg_pointer; flags=message->flags; //分离父目录路径和文件名 if(!strip_path(path,dirname,filename)){ return FALSE; } inode_index=search_file(dirname,filename,GET_FILE_TYPE(flags)); if(inode_index<0){ inode_index=create_file(dirname,filename,GET_FILE_TYPE(flags)); if(inode_index<0){ return FALSE; } } else{ set_error_index(FILE_EXIST); return FALSE; } return TRUE; }
//有问题:调用的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; }
static BOOL do_unlink(MESSAGE *message){ int inode_index,flags,sector_index,sector_length; const char *path; char dir_name[MAX_FILENAME_LENGTH]={0}; char file_name[MAX_FILENAME_LENGTH]={0}; INODE inode; flags=message->flags; path=message->arg_pointer; //分离父目录路径和文件名 if(!strip_path(path,dir_name,file_name)){ return FALSE; } //1.get inode_index,and remove the dir_entry inode_index=search_file(dir_name,file_name,GET_FILE_TYPE(flags)); #ifdef DEBUG_FS printl("inode_index=%d(in do_unlink)\n",inode_index); #endif if(inode_index<0){ set_error_index(FILE_NOT_EXIST); return FALSE; } if(!remove_dir_entry(dir_name,inode_index)){ set_error_index(FILE_NOT_EXIST); return FALSE; } //2.get file inode by inode_index get_inode_by_index(inode_index,&inode); //3.clear imap by inode_index free_imap_bit(inode_index); //4.clear smap inode sector_index=inode.i_start_sector_index-get_data_block_first_index(super_block); sector_length=inode.i_sectors_length; /* printl("sector_index=%d sector_length=%d data_first_index=%d\n",inode.i_start_sector_index,sector_length,get_data_block_first_index(super_block)); */ free_smap_bit(sector_index,sector_length); return TRUE; }
static BOOL strip_path(const char *path,char *dir_name,char *file_name){ if(*path!='/'){ set_error_index(FILE_NAME_ERROR); return FALSE; }else{ //获得父目录地址 *dir_name++=*path++; *dir_name=0; //获得文件名 while(*path!=0){ if(*path=='/'){//目前只处理但目录结构 set_error_index(FILE_NAME_ERROR); return FALSE; } *file_name++=*path++; } *file_name=0; return TRUE; } }
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; }
static int do_close(MESSAGE *message){ PROCESS *process=pid2process(message->source_pid); int fd=message->fd; if(process->file_descriptor[fd]!=NULL && process->file_descriptor[fd]->fd_inode!=NULL && process->file_descriptor[fd]->fd_inode->i_share_count>0 ){ free_inode(process->file_descriptor[fd]->fd_inode); free_fd(process->file_descriptor[fd]); process->file_descriptor[fd]=NULL; return 0; } else{ set_error_index(FILE_NOT_OPEN); return -1; } }
/* 返回目录下文件/目录的个数 */ 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; }
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; } }
static int do_open(MESSAGE *message){ int i,fd=-1; const char *path; char dirname[MAX_FILENAME_LENGTH]={0}; char filename[MAX_FILENAME_LENGTH]={0}; int flags; int inode_index; struct s_file_descriptor *pfd=NULL; struct s_inode *pinode=NULL; /* struct s_inode parent_dir_inode; */ PROCESS *process; path=message->arg_pointer; flags=message->flags; process=pid2process(message->source_pid); pfd=get_free_fd_from_table(); pinode=get_free_inode_from_table(); if(pfd==NULL || pinode==NULL){ set_error_index(NO_FD_INODE); return -1; } //分离父目录路径和文件名 if(!strip_path(path,dirname,filename)){ return -1; } #ifdef DEBUG_FS printl("dir_name=%s file_name=%s\n",dirname,filename); #endif //搜索文件 inode_index=search_file(dirname,filename,GET_FILE_TYPE(flags)); if(inode_index<0){ if((flags & O_CREATE)==0){ return -1; } inode_index=create_file(dirname,filename,GET_FILE_TYPE(flags)); if(inode_index<0){ return -1; } } assert(inode_index>=0,""); get_inode_by_index(inode_index,pinode); #ifdef DEBUG_FS printl("pinode.start_index=%d(in do_open)",pinode->i_start_sector_index); #endif /*SDTIN=0,STDOUT=1,STDERROR=2*/ for(i=3;i<FILE_COUNT;i++){ if(process->file_descriptor[i]==NULL){ fd=i; break; } } if(fd>=0){ process->file_descriptor[fd]=pfd; pfd->fd_inode=pinode; pfd->fd_op_mode=GET_FILE_OP(flags); pfd->fd_position=0; pinode->i_inode_index=inode_index; #ifdef DEBUG_FS printl("inode_index=%d(in do_open)\n",pinode->i_inode_index); printl("data_sector_index=%d data_sector_length=%d\n",process->file_descriptor[fd]->fd_inode->i_start_sector_index,process->file_descriptor[fd]->fd_inode->i_sectors_length); #endif return fd; }else{ set_error_index(PROCESS_FD_POINTER_NOT_ENOUGH); return -1; } }