📄 fs.c
字号:
if(ch!='/'){
printf("Path error! \n");
return PATH_ERR;
}
i++;
leng=strlen(rname);
while(ch!=' '){
ch=*(rname+i++);
if(ch!='/')
buf[j++]=ch;
else { /* get sub dir name from file and path name*/
for(k=0;k<j;k++)
*(subname+k)=buf[k];
j=0; // resolve sub dir name
/* open boot dir file and check one by one,return the inodenum of the file
* . read out inode conten from disk by nodnum
* . read out dir content pointed by nodnum
* . find the inode number of subdir */
/* read out itself inode */
offset=BLOCK_SIZE+sizeof(struct inode)*nodnum;
fseek(fd,offset,SEEK_SET);
fread((char *)pnode,sizeof(struct inode),1,fd);
/* read out dictionary content from disk to dir struct */
blklen=pnode->f_blktotal;
for(i=0;i<blklen;i++){
blknum=pnode->f_blknums[i];
offset=BLOCK_SIZE*blknum;
/* read out dictionary dir content to a dir struct point*/
fseek(fd,offset,SEEK_SET);
fread((char *)pdir,sizeof(struct dir),blklen,fd);
}
for(i=0;i<pdir->rec_len;i++){
if(strcmp(subname,pdir->rectables[i].rec_name)!=0)
continue;
else break;
}
if(i==pdir->rec_len){
printf("Path error!");
return PATH_ERR;
}
nodnum=pdir->rectables[i].rec_idnum;
}
}
printf("\n Success!");
return nodnum;
}
/****************************************************
* 入口参数:代创建文件目录和名称
* 出口参数:错误代码或完成信息
* 实现过程:
****************************************************/
unsigned int tcreat(const char * dir,const char * fname)
{
unsigned int i,j,num;
unsigned int nodnum,next,recnum,blknum;
unsigned int offset;
struct inode * pnode ,* newinode;
struct dir * pdir;
/** read out super block area at first **/
if(psp==NULL){ //第一次进入则需读出 super block 结构
psp=(struct super_block *)malloc(sizeof(struct super_block));
if(psp==NULL){
printf("Initiate global variable psp error! \n");
return MAL_ERR;
}
/* read out super block */
fread(psp,sizeof(struct super_block),1,fd);
}
pnode=(struct inode *)malloc(sizeof(struct inode));
if(pnode==NULL){
printf("malloc error \n");
return MAL_ERR;
}
/* begin systmily check
* 1. disk space check
* 2. user priority check
* 3. operation mode check
* 4. max record limit check
* 5. name collision check
**/
/* disk space check */
/* psp->freblkstart==0 might not idicate space full in detail */
if(psp->freblkstart==BLOCK_OUT){
printf("Disk space isn't enough!\n");
return SPANOELV_ERR;
}
/* Notice: getinode(fname) return inode index of the dictionary of fname */
/* possibility check */
if((nodnum=getinode(dir))<0){
printf("Dictionary not exit!");
return NOD_ERR;
}
/* read out cordirate i_niode content from disk */
offset=BLOCK_SIZE+nodnum*sizeof(struct inode);
fseek(fd,offset,SEEK_SET);
fread((char *)pnode,sizeof(struct inode),1,fd);
/* user priority check */
i=cur_usernum;
if(pnode->i_uid!=psp->users[i].uid){
printf("Creat without priority!");
return PRI_ERR;
}
/* file mode check */
if((pnode->i_mode.rwx==4)||(pnode->i_mode.rwx==5)){
printf("Read only!");
return MOD_ERR;
}
/* file name check */
for(i=0;i<pnode->f_blktotal;i++){ //notice: if dir file have more than two block ,here will make mistake
pdir=(struct dir *)malloc(sizeof(struct dir));
if(pdir==NULL){
printf("malloc error \n");
return MAL_ERR;
}
offset=BLOCK_SIZE*(pnode->f_blknums[i]);
fseek(fd,offset,SEEK_SET);
fread((char *)pdir,sizeof(struct inode),1,fd);
/* max file total limit check */
if(pdir->rec_len>=MAX_RECTOTAL){
printf("Error:the dictonary already full!\n");
return RFULL_ERR;
}
/* check file name colicltion one by one */
for(j=0;j<pdir->rec_len;j++)
if(strcmp(pdir->rectables[j].rec_name,fname)==0){
printf("Error:%s already exit!\n",fname);
return PATH_ERR;
}
/* pass all check then creat new file
* 1. malloc block area
* 2. modify father dictionary
* 3. rewrite dir file
* 4. rewrite its inode information
* 5. modify super_block free block information
**/
// rec_name[pdir->rec_len]=fname;
/* creat new inode of file*/
newinode=(struct inode * )malloc(sizeof(struct inode));
if(newinode==NULL){
printf("malloc new inode error!");
return MAL_ERR;
}
/* malloc a free inode here */
nodnum=psp->freenod_start;
newinode->i_num=psp->free_inodes[nodnum].next_nodnum;
/* update psp->freenod_start and psp->free_nods[] */
next=psp->free_inodes[nodnum].next_nodnum;
psp->free_inodes[nodnum].next_nodnum=psp->free_inodes[next].next_nodnum;
psp->freenod_start=psp->free_inodes[next].next_nodnum; //freenod_start point to next free inode
newinode->i_mode.rwx=6;
newinode->i_mode.pri=(cur_usernum==0)?0:1;
newinode->i_mode.typ=1;
num=cur_usernum;
newinode->i_uid=psp->users[num].uid;
newinode->i_father=pnode->i_num;
newinode->flag=0; //no body is reading
newinode->f_length=0;
newinode->f_blktotal=0;
newinode->f_blknums[0]=psp->freblkstart;
/* rewrite new inode to disk */
offset=BLOCK_SIZE+sizeof(struct inode)*nodnum;
fseek(fd,offset,SEEK_SET);
fwrite((char *)newinode,sizeof(struct inode),1,fd);
/* update its dictionary file */
recnum=pdir->rec_len;
/* if dictionary file is empty at begining */
if(recnum==0){ //deal if new file is the first file in the dictinary Notice:how to intiate rec_ken =0 ?
pdir->rectables[0].flag=1;
strcpy(pdir->rectables[0].rec_name,fname);
pdir->rectables[0].rec_idnum=psp->freenod_start; //save inode of currrent file
/* now initate all below flag to zear in this dictinary */
for(i=1;i<MAX_RECTOTAL;i++)
pdir->rectables[i].flag=0;
pdir->rec_len=1;
}
/* if dictionary file isn't empty at begining */
else{
for(i=1;i<MAX_RECTOTAL;i++) //search free record space */
if(pdir->rectables[i].flag==0)
break;
if(i==MAX_RECTOTAL){
printf("NO RECORD SPACE! \n");
return RFULL_ERR;
}
pdir->rectables[i].flag=1;
strcpy(pdir->rectables[i].rec_name,fname);
pdir->rectables[i].rec_idnum=psp->freenod_start; //save inode of currrent file
pdir->rec_len++;
}
/* rewrite dir file */
for(i=1;i<=pnode->f_blktotal;i++){
blknum=pnode->f_blknums[i];
offset=BLOCK_SIZE*blknum;
fseek(fd,offset,SEEK_SET);
fwrite((char *)pdir+(i-1)*sizeof(struct dir),sizeof(struct dir),1,fd);
}
}
printf("\n Success!");
return OK;
}
/***************************************
* 入口参数:文件的名称
* 出口参数:文件对应的inode指针
* 函数功能:根据文件名,逐级检索目录文
* 件,找到他的inode 指针
***************************************/
struct inode * topen (const char * fname)
{
unsigned int offset,nodnum;
struct inode * pnode;
/** read out super block area at first **/
if(psp==NULL){ //第一次进入则需读出 super block 结构
psp=(struct super_block *)malloc(sizeof(struct super_block));
if(psp==NULL){
printf("Initiate global variable psp error! \n");
// return MAL_ERR;
}
/* read out super block */
fread(psp,sizeof(struct super_block),1,fd);
}
/* Notice: getinode(fname) return inode index of file with name fname */
/* possibility check */
if((nodnum=getinode(fname))<0){
printf("Dictionary not exit!");
// return NOD_ERR;
}
pnode=(struct inode * )malloc(sizeof(struct inode));
if(pnode==NULL){
printf("malloc new inode error!");
//return MAL_ERR;
}
/* read out cordirate i_niode content */
offset=BLOCK_SIZE+nodnum*sizeof(struct inode);
fseek(fd,offset,SEEK_SET);
fread((char *)pnode,sizeof(struct inode),1,fd);
printf("\n Success!");
return pnode;
}
/***************************************
* 入口参数:文件的名称
* 出口参数:文件对应的inode指针
* 函数功能:根据文件名,逐级检索目录文
* 件,找到他的inode 指针
***************************************/
unsigned int tclose (struct inode * pnod)
{
unsigned int offset;
pnod->flag=0;
/* rewrite new inode to disk */
offset=BLOCK_SIZE+sizeof(struct inode)*pnod->i_num;
fseek(fd,offset,SEEK_SET);
fwrite((char *)(char *)pnod,sizeof(struct inode),1,fd);
printf("\n Success!");
return OK;
}
/***************************************
* 入口参数:文件的inode指针
* 出口参数:返回信息
* 函数功能:删除inode所指向的文件,且
* 相应地修改目录,回收磁盘块
***************************************/
unsigned int tdelet(struct inode * pnode)
{
unsigned int i,j,fnum,offset,blklen;
unsigned int nodnum,temnod;
unsigned int blknum,temblk;
struct inode * pnd;
struct dir * pdir;
/** read out super block area at first **/
if(psp==NULL){ //第一次进入则需读出 super block 结构
psp=(struct super_block *)malloc(sizeof(struct super_block));
if(psp==NULL){
printf("Initiate global variable psp error! \n");
return MAL_ERR;
}
/* read out super block */
fread(psp,sizeof(struct super_block),1,fd);
}
/* user priority check */
i=cur_usernum;
if(pnode->i_uid!=psp->users[i].uid){
printf("Crea without priority!");
return PRI_ERR;
}
/* delet file mode check */
if((pnode->i_mode.rwx==5)||(pnode->i_mode.rwx==4)){
printf("Read only!");
return MOD_ERR;
}
/* update sup_block struct */
for(i=1;i<(pnode->f_blktotal);i++){
blknum=pnode->f_blknums[i];
temblk=psp->freblkstart;
psp->free_blks[blknum].next_blknum=psp->free_blks[temblk].next_blknum;
psp->free_blks[temblk].next_blknum=psp->free_blks[blknum].next_blknum;
}
/* update the dictionary of the file to delet according inode
* 1. read out the dictionary of the file
* 2. search the record number of the file
* 3. update the dictionary record
*/
pnd=(struct inode *)malloc(sizeof(struct inode));
if(pnd==NULL){
printf("Malloc inode struct error!\n");
return MAL_ERR;
}
fnum=pnode->i_father;
offset=BLOCK_SIZE+sizeof(struct inode)*fnum;
/* read out dictionary inode */
fseek(fd,offset,SEEK_SET);
fread((char *)pnd,sizeof(struct inode),1,fd);
/* read out dictionary content from disk to dir struct */
pdir=(struct dir *)malloc(sizeof(struct dir));
if(pdir==NULL){
printf("Malloc dir struct error!\n");
return MAL_ERR;
}
blklen=pnd->f_blktotal;
for(i=0;i<blklen;i++){
blknum=pnd->f_blknums[i];
offset=BLOCK_SIZE*(blknum+1);
/* read out dictionary dir content to a dir struct point*/
fseek(fd,offset,SEEK_SET);
fread((char *)(char *)pdir,sizeof(struct dir),1,fd);
}
/* now update the dictionary of the file
* 1. search the rectables to find file's record position
* 2. update filetable struct of the position
*/
for(j=0,i=0;(i<MAX_RECTOTAL)&&(j<pdir->rec_len);i++){
if(pdir->rectables[i].flag==0)
continue;
else { j++;
if(pdir->rectables[i].rec_idnum == pnode->i_num)
break;
else continue;
}
}
if(i== MAX_RECTOTAL||j==pdir->rec_len){
printf("File not exit! \n");
return NOF_ERR;
}
pdir->rectables[i].flag=0;
/* now rewrite dir file content to its disk */
blklen=pnd->f_blktotal;
for(i=0;i<blklen;i++){
blknum=pnd->f_blknums[i];
offset=BLOCK_SIZE*(blknum+1);
/* read out dictionary dir content to a dir struct point*/
fseek(fd,offset,SEEK_SET);
fwrite((char *)(char *)pdir,sizeof(struct dir),1,fd);
}
/* free the inode of file to delet */
/* update psp->free_nod[] */
/* update sup_block struct */
for(i=0;i<pdir->rec_len;i++){
nodnum=pdir->rectables[i].rec_idnum;
temnod=psp->freenod_start;
psp->free_inodes[blknum].next_nodnum=psp->free_inodes[temnod].next_nodnum;
psp->free_inodes[temnod].next_nodnum=psp->free_inodes[nodnum].next_nodnum;
}
printf("\n Success!");
return OK;
}
/*********************************************
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -