📄 fs.c
字号:
* 入口参数:待写文件的inode 指针
* 出口参数:写文件成功与否的信息
* 函数功能:往已打开文件写内容
*********************************************/
unsigned int twrite(struct inode * pnode,const char * buf, unsigned int len, unsigned int mode)
{
unsigned int i,freeblk,pblk;
unsigned int offset,rwx;
//struct inode * pn
/** 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 check */
i=cur_usernum;
if(pnode->i_uid!=psp->users[i].uid){
printf("User illegal!");
return PRI_ERR;
}
/* file mode check */
rwx=pnode->i_mode.rwx;
if(((rwx<<1)>>2)==0){
printf("Read only!");
return MOD_ERR;
}
/* over write check */
if(pnode->flag==1){
printf("File is beening writen! \n");
return OVERW_ERR;
}
/* write mode check */
if(mode!=SEEK_CUR&&mode!=SEEK_SET&&mode!=SEEK_END){
printf("ERROR:Unrecognizable write mode!\n");
return MOD_ERR;
}
/* update inode of file */
pnode->flag=1; //set write flag
pnode->f_length=len;
pnode->f_blktotal=len/BLOCK_SIZE+1;
/* malloc block to write file */
for(i=0;i<pnode->f_blktotal;i++){
pblk=psp->freblkstart;
freeblk=psp->free_blks[pblk].next_blknum;
pnode->f_blknums[i]=freeblk;
offset=BLOCK_SIZE*pblk; //notice:don't care one a file in many block
fseek(fd,len,SEEK_SET);
fwrite((char *)buf,sizeof(struct dir),1,fd);
/* pass all check then write buferr to fd */
}
pnode->flag=0; //set write flag
return OK;
}
unsigned int tread(struct inode * pnode,char * buf, unsigned int len)
{
unsigned int i,freeblk,pblk;
unsigned int offset,rwx;
//struct inode * pn
/** 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 check */
i=cur_usernum;
if(pnode->i_uid!=psp->users[i].uid){
printf("User illegal!");
return PRI_ERR;
}
/* file mode check */
rwx=pnode->i_mode.rwx;
if((rwx>>2)==0){
printf(" Can't Read ! \n");
return MOD_ERR;
}
/* read modle check
if((mode!=SEEK_CUR)&&(mode!=SEEK_SET)&&(mode!=SEEK_END)){
printf("ERROR:Unrecognizable write mode!\n");
return MOD_ERR;
} */
/* update inode of file */
pnode->flag=1; //set write flag
pnode->f_length=len;
pnode->f_blktotal=len/BLOCK_SIZE+1;
/* malloc block to write file */
for(i=0;i<pnode->f_blktotal;i++){
pblk=psp->freblkstart;
freeblk=psp->free_blks[pblk].next_blknum;
pnode->f_blknums[i]=freeblk;
offset=BLOCK_SIZE*pblk; //notice:don't care one a file in many block
fseek(fd,len,SEEK_SET);
fread((char *)buf,sizeof(struct dir),1,fd);
}
printf("\n Success!");
return OK;
}
/**********************************************
** 函数入口:文件pnode指针
** 函数出口:OK
** 函数功能:关闭文件
**********************************************/
unsigned int tlose(struct inode * pnod)
{
//* 引用计数器应当减1
pnod=NULL;
return OK;
}
/**********************************************
** 函数入口:待建目录名和父目录名
** 函数出口:创建信息
** 函数功能: 创建目录
**********************************************/
unsigned int tmkdir(const char * fdir,const char * dname)
{
unsigned int i,j;
unsigned int nodnum ,next,rwx,num,recnum;
unsigned int offset;
struct inode * pnode;
struct inode * 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 */
if(psp->freblkstart==BLOCK_OUT){
printf("Disk space isn't enough!\n");
return SPANOELV_ERR;
}
/* Notice: getinode(fname) return inode index of file's dictionary with name fname */
/* possibility check */
if((nodnum=getinode(fdir))<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("Crea without priority!");
return PRI_ERR;
}
/* dir mode check */
rwx=pnode->i_mode.rwx;
if(((rwx<<1)>>2)==0){
printf("Read only!");
return MOD_ERR;
}
/* dir name check */
/* read out dir content from disk at first */
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);
fwrite((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,dname)==0){
printf("Error:%s already exit!\n",dname);
return PATH_ERR;
}
}
/* pass all check then creat new file
* 1. modify father dictionary
* 2. rewrite dir file
* 3. rewrite its inode information
* 4. modify super_block free block information
**/
/* creat new inode of dir */
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=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_len =0 ?
pdir->rectables[0].flag=1;
strcpy(pdir->rectables[0].rec_name,dname);
pdir->rectables[0].rec_idnum=psp->freenod_start; //save inode of currrent dir
/* 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,dname);
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++){
unsigned int 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;
}
/**********************************************
** 函数入口:文件pnode指针
** 函数出口:OK
** 函数功能:关闭文件
**********************************************/
unsigned int trmdir(const char * fdir,const char * dname)
{
unsigned int i,j,idnum,offset;
unsigned int nodnum,rwx,fnum,temnod;
unsigned int blknum,temblk,blklen;
struct inode * pnode,* ptemnod,* subpnd,*pnd;
struct dir * pdir,* pbasedir;
/** 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;
}
/* Notice: getinode(fname) return inode index of file's dictionary with name fname */
/* possibility check */
if((nodnum=getinode(fdir))<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 *)(char *)pnode,sizeof(struct inode),1,fd);
/* user priority check */
i=cur_usernum;
if(pnode->i_uid!=psp->users[i].uid){
printf("User without priority!");
return PRI_ERR;
}
/* dir mode check */
rwx=pnode->i_mode.rwx;
if(((rwx<<1)>>2)==0){
printf("No write promission !");
return MOD_ERR;
}
/* 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_num;
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 *)pdir+offset-BLOCK_SIZE,sizeof(struct dir),1,fd);
}
/* now update the dictionary of the dir
* 1. search the rectables to find dir's record position
* 2. free block area of all records in the dir
* 3. uopdate this dir's father dictionary
* 4. free all used i-node area
**/
// search the rectables to find dir's record position
for(j=0,i=0;(i<MAX_RECTOTAL)&&(j<pdir->rec_len);i++){
if(pdir->rectables[i].flag==0)
continue;
else { j++;
if((strcmp(pdir->rectables[i].rec_name,dname))==0)
break;
}
}
if(i== MAX_RECTOTAL||j==pdir->rec_len){
printf("Dir %s not exit! \n",dname);
return NOF_ERR;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -