int tfs_mkdir(struct inode *parent_dir, const char *dname) { struct inode *dir; int dirty; int err = 0; dir = tfs_mknod(parent_dir, dname, TFS_DIR); if (IS_ERR(dir)) { free_inode(parent_dir); return PTR_ERR(dir); } err = tfs_add_entry(dir, ".", dir->i_ino, &dirty); if (err) goto out; err = tfs_add_entry(dir, "..", parent_dir->i_ino, &dirty); if (err < 0) goto out; if (dirty) err = tfs_iwrite(dir); out: free_inode(dir); free_inode(parent_dir); return err; }
/* * Looking for an inode with the given path * * returns NULL for -ENOENT, ERROR for errors happend * and inode for finding responding file or directory. */ struct inode * namei(const char *name, uint32_t flag) { struct inode *inode; struct inode *parent; char part[256]; char *p; FS_DEBUG("trying to open path: %s\n", name); if (*name == '/') { inode = root_fs()->root; if (IS_ERR(inode)) panic("namei: Read root inode error!\n"); while (*name == '/') name++; } else { inode = root_fs()->pwd; FS_DEBUG("pwd->inode: %d\n", inode->i_ino); } parent = inode; while (*name) { p = part; while (*name && *name != '/') { if (p >= part + MAX_NAME_LEN) return ERR_PTR(-ENAMETOOLONG); *p++ = *name++; } *p = '\0'; while (*name && *name == '/') name++; if (!*name && (flag & LOOKUP_PARENT)) return parent; FS_DEBUG("Looking for part: %s, parent->inode: %d\n", part, parent->i_ino); inode = iget(part, parent); if (IS_ERR_OR_NULL(inode)) break; free_inode(parent); parent = inode; if (!*name) break; } if (PTR_ERR(inode) == -ENOENT && flag & LOOKUP_CREATE) { inode = parent->i_op->mknod(parent, part, TFS_FILE); free_inode(parent); if (IS_ERR(inode)) return ERR_CAST(inode); if (inode->i_op->iwrite(inode)) { free_inode(inode); return ERR_PTR(-EIO); } } return inode; }
/*递归删除文件夹*/ int del_file(int inode, char* name, int deepth) { int child, i, t; Inode temp; if (!strcmp(name, ".") || !strcmp(name, "..")) { /*不允许删除.和..*/ printf("rmdir: failed to remove '%s': Invalid argument\n", name); return -1; } child = check_name(inode, name); /*读取当前子目录的Inode结构*/ fseek(Disk, InodeBeg + sizeof(Inode)*child, SEEK_SET); fread(&temp, sizeof(Inode), 1, Disk); if (temp.type == File) { /*如果是文件则释放相应Inode即可*/ free_inode(child); /*若是最上层文件,需调整目录*/ if (deepth == 0) { adjust_dir(name); } return 1; } else { /*否则进入子目录*/ enter_child_dir(inode, name); } for (i = 2; i<dir_num; ++i) { del_file(child, dir_table[i].name, deepth + 1); } enter_child_dir(child, "..");//返回上层目录 free_inode(child); if (deepth == 0) { /*删除自身在目录中的内容*/ if (dir_num / DirPerBlk != (dir_num - 1) / DirPerBlk) { /*有磁盘块可以释放*/ curr_inode.blk_num--; t = curr_inode.blk_identifier[curr_inode.blk_num]; free_blk(t);//释放相应的磁盘块 } adjust_dir(name);//因为可能在非末尾处删除,因此要移动dir_table的内容 }/*非初始目录直接释放Inode*/ return 1; }
struct fs_Inode* fs_inode_open(size_t inode) { for (size_t i = 0; i < MAX_OPEN_INODES; i++) { if (inodeTable[i]) { if (inodeTable[i]->refCount <= 0) { kprintf("Inode %u in entry %u is broken.\n", inodeTable[i]->number, i); while (1); } } } for (size_t i = 0; i < MAX_OPEN_INODES; i++) { if (inodeTable[i] != NULL && inodeTable[i]->number == inode) { inodeTable[i]->refCount++; return inodeTable[i]; } } struct fs_Inode* node = ext2_read_inode(fs, inode); node->extra = NULL; if (node == NULL) { return NULL; } node->refCount = 1; for (size_t i = 0; i < MAX_OPEN_INODES; i++) { if (inodeTable[i] == NULL) { inodeTable[i] = node; return node; } } free_inode(node); return NULL; }
void initiate_inode_list() { int arr[512]; memset(arr,0 ,sizeof(arr)); int i; uint max_inode_block = 1 + curr_superblock.isize; for(i = 2; i <= max_inode_block; i++) write_block(i, arr, sizeof(arr)); //int brr[512]; //read_block(20,brr,512); uint inode_number = curr_superblock.isize * INODES_PER_BLOCK; for(i = 2; i <= inode_number; i++) { if(curr_superblock.ninode == MAX_SIZE) break; struct inode ino; read_inode(i, &ino); if(check_allocation(&ino) != 1) { free_inode(i); } } if(curr_superblock.ninode == 0){ fprintf(stderr,"Error: the inode blocks are full, allocation falure!"); exit(-1); } }
/*将 rmfile 这个文件删除,而且目前只能删除文件*/ void do_rm() { struct inode cur_dir,item; struct dir_ent ent,emptyent; char *filename; char buf[MAXBUF]; memset(&emptyent,0,sizeof(emptyent)); int i,j; if (!rmfile[0]) scanf("%s",rmfile); if(!strcmp(rmfile,".") || !strcmp(rmfile,"..")) { printf("Can not remove this file.\n"); _clear(rmfile); return ; } strcpy(buf,rmfile); j=-1; for(i=0;rmfile[i];i++) if(rmfile[i]=='/') j=i; if(j==0){// case /dir buf[1]='\0'; filename=rmfile+1; }else if(j>0){ //case /dir1/dir2 or ab/cd buf[j]='\0'; filename=rmfile+j+1; }else { //case ab strcpy(buf,"."); filename=rmfile; } get_inode_bypath(buf,&cur_dir); if(cur_dir.i_num==-1) { printf("No such file.\n"); _clear(rmfile); return ; } // get_inode(pwd,&cur_dir); fseek(fimg,cur_dir.i_start_sect*SECTOR_SIZE,SEEK_SET); //将逐个清空rmfile所占用的扇区 for(i=0;i<cur_dir.i_size;i++) { fread(&ent,sizeof(struct dir_ent),1,fimg); if(strcmp(filename,ent.name)==0){ get_inode(ent.i_num,&item); if(item.i_mode==1){ fseek(fimg,-sizeof(struct dir_ent),SEEK_CUR); fwrite(&emptyent,sizeof(struct dir_ent),1,fimg);//删除该目录项,只能删除文件 free_inode(item.i_num); u32 sector=item.i_start_sect; while(sector!=0){ free_sector(sector); fseek(fimg,sector*SECTOR_SIZE+SECTOR_SIZE-sizeof(u32),SEEK_SET); fread(§or,sizeof(u32),1,fimg); } }else printf("Can not remove directory\n"); _clear(rmfile); return ; } } _clear(rmfile); printf("No such file.\n"); }
void free_socket(struct inode *inode) { struct pxe_pvt_inode *socket = PVT(inode); free(socket->tftp_pktbuf); /* If we allocated a buffer, free it now */ free_inode(inode); }
void tfs_close(struct file *file) { if (file) { free_inode(file->inode); free(file); } }
void tfs_closedir(DIR *dir) { if (dir) { free_inode(dir->dd_dir->inode); free(dir->dd_dir); free(dir); } }
static int dentry_remove(uint8_t *fs, int dir_inum, int target_inum) { struct ext2_inode *dir = get_inode(fs, dir_inum); void *block = get_block(fs, dir->i_block[0]); ssize_t blocksize = get_block_size(fs); // find target dentry struct ext2_dir_entry_2 *dentry = (struct ext2_dir_entry_2 *)block; struct ext2_dir_entry_2 *target = NULL; struct ext2_dir_entry_2 *prev = NULL; int count = 0; blocksize -= dentry-> rec_len; while (blocksize > 0) { prev = dentry; dentry = (struct ext2_dir_entry_2*)((uint8_t*)dentry + dentry->rec_len); blocksize -= dentry->rec_len; //DEBUG("Dir Remove: dentry %p, inode %d, length %d, lenex %d, cursize %d", dentry, dentry->inode, dentry->rec_len, ext2_dentry_find_len(dentry), blocksize); if (dentry->inode == target_inum) { target = dentry; //DEBUG("Dir Remove: Found dentry"); } } if (blocksize) { //ERROR("DIR REMOVE FILE: rec_len values not aligned %d", blocksize); } int is_target_end = 0; if (target == dentry) { is_target_end = 1; //DEBUG("DIR REMOVE: End target"); } //DEBUG("Dir Remove: size %d", blocksize); if (target == NULL) { ERROR("Dir Remove: Did not find dentry!"); return 0; } size_t dir_size = (uint64_t)dentry - (uint64_t)block + ext2_dentry_find_len(dentry); //DEBUG("Dir Remove: last reclen %d", ext2_dentry_find_len(dentry)); //DEBUG("Dir Remove: dir_size %d, %x", dir_size, dir_size); if (is_target_end) { prev->rec_len += target->rec_len; } else { // move remaining dentries back dentry->rec_len += target->rec_len; void *move_dst = (void*)((uint8_t*)target); void *move_src = (void*)((uint8_t*)target + target->rec_len); size_t move_len = (uint64_t)block + dir_size - (uint64_t)move_src; //DEBUG("Dir Remove: move %p %p", move_dst, move_src); //DEBUG("Dir Remove: move len %d", move_len); memmove(move_dst, move_src, move_len); } // update terminator dir_size -= target->rec_len; dir->i_size -= dir_size; free_inode(fs, target_inum); return 1; }
static void put_inode_itable( struct m_inode *inode ) { struct buffer_head *bh = bread( inode->dev, inode->start_itable_sect, 0 ); struct d_inode *tmp = (struct d_inode *)(bh->pdata ); tmp = tmp + (inode->start_itable_sect - inode->zone_first_inode_num)%8; *tmp = *((struct d_inode *)inode); free_inode( inode ); bwrite( bh ); }
int sys_chdir(const char *pathname) { struct inode * inode; char *cwd; while (*pathname && *pathname == '.' && *(pathname + 1) == '/') pathname += 2; /* If we are changing to current dir, then just do nothing */ if (*pathname == '.' && !*(pathname + 1)) return 0; inode = namei(pathname, 0); if (IS_ERR_OR_NULL(inode)) return inode ? PTR_ERR(inode) : -ENOENT; if (!IS_DIR(inode)) { free_inode(inode); return -ENOTDIR; } free_inode(root_fs()->pwd); root_fs()->pwd = inode; cwd = root_fs()->cwd; if (*pathname == '/') { strcpy(cwd, pathname); } else if (strcmp(pathname, "..") == 0) { char *p = strrchr(cwd, '/'); /* At least we have a '/' char */ if (!p) return -EINVAL; if (p == cwd) *(p + 1) = '\0'; else *p = '\0'; } else { strcat(cwd, pathname); } return 0; }
int tfs_rmdir(struct inode *dir, const char *dname) { struct inode *inode; struct cache_struct *cs; struct tfs_dir_entry *de; struct tfs_sb_info *sbi = TFS_SBI(dir->i_fs); int err; cs = tfs_find_entry(dir, dname, &de); if (IS_ERR_OR_NULL(cs)) { err = cs ? PTR_ERR(cs) : -ENOENT; goto out; } inode = tfs_iget_by_inr(dir->i_fs, de->d_inode); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto out; } if (inode->i_mode != TFS_DIR) { err = -ENOTDIR; goto error; } err = is_empty_dir(inode); if (err == 0) { err = -ENOTEMPTY; goto error; } else if (err == -1) { printk("%s: path correupted: the size is less than two direntry!\n", dname); err = -EINVAL; goto error; } dir->i_size -= sizeof(struct tfs_dir_entry); err = tfs_iwrite(dir); if (err) goto error; de->d_inode = 0; err = tfs_bwrite(sbi, cs->block, cs->data); if (err) goto error; err = tfs_release_inode(sbi, inode); goto out; error: free_inode(inode); out: return err; }
int ext2_rmdir(inode_t *dir, dentry_t *dentry) { if (S_ISDIR(dentry->d_inode->i_mode)) { remove_dir_entry((ext2_fs_instance_t*)dir->i_instance, dir->i_ino, dentry->d_name); free_inode((ext2_fs_instance_t*)dir->i_instance, dentry->d_inode->i_ino); return 0; } else { return -ENOTDIR; } // TODO: Check is empty. // TODO: Call rmdir_inode! // décompter link! }
void fs_inode_close(struct fs_Inode* inode) { inode->refCount--; if (inode->refCount == 0) { for (size_t i = 0; i < MAX_OPEN_INODES; i++) { if (inodeTable[i] == inode) { free_inode(inode); inodeTable[i] = NULL; return; } } } }
/* * Lookup the parent inode * * NOTE: the parent should be directory! */ struct inode *namei_parent(const char *pathname) { struct inode *dir = namei(pathname, LOOKUP_PARENT); if (!IS_ERR_OR_NULL(dir)) return dir ? ERR_CAST(dir) : ERR_PTR(-ENOENT); if (!IS_DIR(dir)) { free_inode(dir); return ERR_PTR(-ENOTDIR); } return dir; }
/** Borra l'entrada de directori especificada y en cas de que sigui l'últim * enllaç existent borra el propi fitxer/directori. Té control de concurrència. * @path: ruta del fitxer/directori * @return: 0 si correctament * -1 en cas d'error. */ int emofs_unlink(const char *path) { int p_inode = 0; int p_dir_inode = 0; int p_entry = 0; emofs_inode inode; emofs_dir_entry *last_dir_entry; if(!mutex){ emofs_sem_get(&mutex); } emofs_sem_wait(mutex); if (emofs_find_entry(path, &p_dir_inode, &p_inode, &p_entry) == -1) { puts("EmoFS_UnLink: El fitxer o directori font no existeix"); emofs_sem_signal(mutex); return -1; } read_inode(p_dir_inode, &inode); /* Borram entrada de directori */ if (inode.size > sizeof(emofs_dir_entry)) { /* Hi ha més entrades posam l'última al lloc de la que volem * borrar. */ read_file(p_dir_inode, (void *)&last_dir_entry, \ inode.size-sizeof(emofs_dir_entry), \ sizeof(emofs_dir_entry)); write_file(p_dir_inode, last_dir_entry, \ p_entry*sizeof(emofs_dir_entry), \ sizeof(emofs_dir_entry)); } free(last_dir_entry); /* Truncam per l'ultima entrada, si sols hi ha la que volem borrar be * sino llevam l'ultima que ara estara copiada al lloc de la que voliem * borrar. */ truncate_file(p_dir_inode, inode.size-sizeof(emofs_dir_entry)); read_inode(p_inode, &inode); if (inode.link_count == 0) { /* Hem de alliberar blocs de dades i inode */ truncate_file(p_inode, 0); free_inode(p_inode); } else { inode.link_count--; write_inode(p_inode, &inode); } emofs_sem_signal(mutex); return 0; }
int sys_mkdir(const char *pathname) { int err; struct inode *dir = namei_parent(pathname); if (IS_ERR(dir)) return PTR_ERR(dir); err = -ENOSYS; if (dir->i_op && dir->i_op->mkdir) err = dir->i_op->mkdir(dir, get_base_name(pathname)); free_inode(dir); return err; }
int sys_dirstat(char *dir, unsigned num, char *namebuf, struct stat *statbuf) { if(!namebuf || !statbuf || !dir) return -EINVAL; struct inode *i = read_dir(dir, num); if(!i) return -ESRCH; do_stat(i, statbuf); strncpy(namebuf, i->name, 128); if(i->dynamic) { rwlock_acquire(&i->rwl, RWL_WRITER); free_inode(i, 0); } return 0; }
int remove_file(struct inode *dir, const char *name){ /*判断目录是否有效*/ if(dir->ext2_inode.i_block[0] != UINT_MAX){ perror("inode_operations.c: remove_file error! current dir is a file!\n"); return -1; } /*判断名字是否有效*/ if(checkname(name) == -1){ perror("inode_operations.c: remove_file error! filename is illegal!\n"); return -1; } char buf[BLOCK_SIZE]; struct ext2_dir_entry_2 *pentry; int dir_datablocks = dir->ext2_inode.i_blocks;/*数据块个数*/ int i = 1; int j = 0; int num = BLOCK_SIZE/sizeof(struct ext2_dir_entry_2); while(i <= dir_datablocks){ /*取出目录节点中第i块逻辑块所在的物理块的数据,放入buf*/ get_block_data(dir->ext2_inode.i_block[i],buf); pentry = (struct ext2_dir_entry_2 *)buf; //printf("inode_operations.c: check : dir_datablocks: %d\n",i); /*比较每一项*/ while(j<num){ //printf("inode_operations.c: check : entry: %d\n",j); /*比较pentry->inode不为0的每一项*/ if(pentry->inode && !strcmp(pentry->name,name)){ if(free_inode(pentry->inode) == -1){ perror("节点释放失败!\n"); return -1; }; /*清空该目录项*/ memset(pentry,'\0',sizeof(struct ext2_dir_entry_2)); /*写回磁盘,更新数据*/ write_block_data(dir->ext2_inode.i_block[i],buf); return 1; } j++; pentry++; } i++; } printf("no such file,please check your filename!\n"); return -1; }
/** * Reset a file. Free memory if possible. * * @param fd file descriptor */ void free_file(file_nr fd) { file *f = get_file(fd); if (f != NULL){ if (f->f_count > 0) { f->f_count--; } if (f->f_count == 0) { f->f_desc = NIL_FILE; free(f->f_name); f->f_name = NULL; if (f->f_inode->i_adr != ROOT_INODE_BLOCK) free_inode(f->f_inode->i_num); } } }
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; } }
int sys_dirstat_fd(int fd, unsigned num, char *namebuf, struct stat *statbuf) { if(!namebuf || !statbuf) return -EINVAL; struct file *f = get_file_pointer((task_t *)current_task, fd); if(!f) return -EBADF; struct inode *i = read_idir(f->inode, num); fput((task_t *)current_task, fd, 0); if(!i) return -ESRCH; do_stat(i, statbuf); strncpy(namebuf, i->name, 128); if(i->dynamic) { rwlock_acquire(&i->rwl, RWL_WRITER); free_inode(i, 0); } return 0; }
/*===========================================================================* * fs_newnode * *===========================================================================*/ int fs_newnode(message *fs_m_in, message *fs_m_out) { register int r = OK; mode_t bits; struct inode *rip; dev_t dev; caller_uid = (uid_t) fs_m_in->REQ_UID; caller_gid = (gid_t) fs_m_in->REQ_GID; bits = (mode_t) fs_m_in->REQ_MODE; dev = (dev_t) fs_m_in->REQ_DEV; /* Try to allocate the inode */ if( (rip = alloc_inode(dev, bits) ) == NULL) return(err_code); switch (bits & S_IFMT) { case S_IFBLK: case S_IFCHR: rip->i_rdev = dev; /* Major/minor dev numbers */ break; case S_IFIFO: if ((get_block(dev, rip->i_num)) == NULL) r = EIO; break; default: r = EIO; /* Unsupported file type */ } if (r != OK) { free_inode(rip); } else { /* Fill in the fields of the response message */ fs_m_out->RES_INODE_NR = rip->i_num; fs_m_out->RES_MODE = rip->i_mode; fs_m_out->RES_FILE_SIZE_LO = rip->i_size; fs_m_out->RES_UID = rip->i_uid; fs_m_out->RES_GID = rip->i_gid; fs_m_out->RES_DEV = dev; } return(r); }
int tfs_unlink(struct inode *dir, const char *dname) { struct inode *inode; struct cache_struct *cs; struct tfs_dir_entry *de; struct tfs_sb_info *sbi = TFS_SBI(dir->i_fs); int err; cs = tfs_find_entry(dir, dname, &de); if (IS_ERR_OR_NULL(cs)) { err = cs ? PTR_ERR(cs) : -ENOENT; goto out; } inode = tfs_iget_by_inr(dir->i_fs, de->d_inode); if (IS_ERR(inode)) { err = PTR_ERR(inode); goto out; } if (inode->i_mode != TFS_FILE) { printk("%s: not a file!\n", dname); goto error; } dir->i_size -= sizeof(struct tfs_dir_entry); err = tfs_iwrite(dir); if (err) goto error; de->d_inode = 0; err = tfs_bwrite(sbi, cs->block, cs->data); if (err) goto error; err = tfs_release_inode(sbi, inode); goto out; error: free_inode(inode); out: return err; }
Cache_ent * new_file() { Cache_ent * cp; Inodenum inode; /* Get an inode - it is locked when we get it. */ if ((inode = alloc_inode()) < 0) return 0; /* Get a cache slot */ if ((cp = alloc_cache_slot(inode)) == 0) { free_inode(inode,0,ANN_NEVER,SEND_CANWAIT); /* unlocks the inode */ return 0; } cp->c_flags |= NOTCOMMITTED; cp->c_timeout = BS_CACHE_TIMEOUT; return cp; }
int main(void){ memset((char*)m_inodemap,'\0',1024); memset((char*)m_blockmap,'\0',1024); int inode_num; int block_num; int n; int i; get_superblock_data(&sb); printf("super_block.s_free_blocks_count: %d\n",sb.s_free_blocks_count); printf("super_block.s_free_inodes_count: %d\n",sb.s_free_inodes_count); printf("super_block.s_wtime: %d\n",sb.s_wtime); get_blockmap((char*)m_blockmap,1024); get_inodemap((char*)m_inodemap,1024); for(i=0;i<256;i++){ if(m_blockmap[i] == 0) continue; printf("blockmap[%d]:%#X\n",i,m_blockmap[i]); } for(i=0;i<256;i++){ if(m_inodemap[i] == 0) continue; printf("inodemap[%d]:%#X\n",i,m_inodemap[i]); } while(1){ printf("请输入您要选择的功能号(0-释放/1-申请/2-退出):"); scanf("%d",&n); if(n == 0){ printf("请输入需要释放的数据块号:"); scanf("%d",&block_num); if(free_block(block_num) == -1){ perror("释放失败!\n"); exit(EXIT_FAILURE); } get_blockmap((char*)m_blockmap,1024); printf("blockmap[0]:%#X\n",m_blockmap[0]); printf("请输入需要释放的i节点号:"); scanf("%d",&inode_num); if(free_inode(inode_num) == -1){ perror("释放失败!\n"); exit(EXIT_FAILURE); } get_inodemap((char*)m_inodemap,1024); printf("inodemap[0]:%#X\n",m_inodemap[0]); } else if(n == 1){ /*申请一个空闲块*/ if((block_num=new_block()) == -1){ perror("申请失败!\n"); exit(EXIT_FAILURE); } printf("获得的空闲块号:%d\n",block_num); get_blockmap((char*)m_blockmap,1024); printf("blockmap[0]:%#X\n",m_blockmap[0]); /*申请一个空闲i节点*/ if((inode_num=new_inode()) == -1){ perror("申请失败!\n"); exit(EXIT_FAILURE); } printf("获得的空闲i节点号:%d\n",inode_num); get_inodemap((char*)m_inodemap,1024); printf("inodemap[0]:%#X\n",m_inodemap[0]); } else{ break; } } get_superblock_data(&sb); printf("super_block.s_free_blocks_count: %d\n",sb.s_free_blocks_count); printf("super_block.s_free_inodes_count: %d\n",sb.s_free_inodes_count); printf("super_block.s_wtime: %d\n",sb.s_wtime); for(i=0;i<256;i++){ if(m_blockmap[i] == 0) continue; printf("blockmap[%d]:%#X\n",i,m_blockmap[i]); } for(i=0;i<256;i++){ if(m_inodemap[i] == 0) continue; printf("inodemap[%d]:%#X\n",i,m_inodemap[i]); } return 0; }
int ext2_unlink(inode_t *dir, dentry_t *dentry) { remove_dir_entry((ext2_fs_instance_t*)dir->i_instance, dir->i_ino, dentry->d_name); free_inode((ext2_fs_instance_t*)dir->i_instance, dentry->d_inode->i_ino); // TODO: nlink-- return 0; }
//handling create request void create_handler(Msg *msg, int sender_pid) { char pathname[MAXPATHNAMELEN]; CopyFrom(sender_pid,pathname,msg->ptr1,msg->num1+1); char* filename = pathname+msg->num1; int direct_len = msg->num1; while ((*filename)!='/' && filename!=pathname) { filename--; direct_len--; } if ((*filename)=='/') { direct_len++; filename++; } if (strlen(filename)==0) { perror("invalid pathname when creating file==0!"); msg->type = ERROR; return; } int direct_inum = path_to_inum(pathname,direct_len,msg->num2,0); if (direct_inum<=0) { perror("invalid pathname when creating file direct_num<0!"); msg->type = ERROR; return; } int new_inum = check_dir(direct_inum,filename); if (new_inum<0) { perror("invalid pathname when creating file new_inum<0!"); msg->type = ERROR; return; } //exist same file name in the directory if (new_inum>0) { inode_cache *n = read_inode(new_inum); free_inode(n->inode_num); msg->num1 = new_inum; } else if (new_inum==0) { new_inum = alloc_inode(INODE_REGULAR,0); struct dir_entry *d = empty_dir(direct_inum); if (d==NULL) { perror("no empty space for new directory"); msg->type = ERROR; return; } d->inum = new_inum; memcpy(d->name,filename,strlen(filename)); inode_cache *n = read_inode(direct_inum); n->data.size += sizeof(struct dir_entry); n->data.nlink++; n->dirty = 1; msg->num1 = new_inum; n = read_inode(new_inum); msg->num2 = n->data.reuse; } }
//handling unlink request void unlink_handler(Msg *msg, int sender_pid) { char pathname[MAXPATHNAMELEN]; memset(pathname,'\0',MAXPATHNAMELEN); CopyFrom(sender_pid,pathname,msg->ptr1,msg->num2+1); int dir_len=msg->num2; char *dir_pathname=pathname+msg->num2; while((*dir_pathname)!='/'&&dir_pathname!=pathname){ dir_len--; dir_pathname--; } if((*dir_pathname)=='/'){ dir_len++; dir_pathname++; } int parent_inum=path_to_inum(pathname,dir_len,msg->num1,0); int path_inum=check_dir(parent_inum,dir_pathname); if(path_inum<=0||parent_inum<=0){ msg->type=-1; return; } inode_cache *path_inode=read_inode(path_inum); inode_cache *parent_inode=read_inode(parent_inum); if(path_inode->data.type==INODE_DIRECTORY){ msg->type=-1; return; } struct dir_entry *path_dir_entry=search_dir_entry(parent_inum,dir_pathname); if(path_inode->data.nlink>1){ path_dir_entry->inum=0; path_inode->data.nlink--; memset(path_dir_entry->name,'\0',DIRNAMELEN); parent_inode->data.size-=sizeof(struct dir_entry); parent_inode->dirty=1; } else if(path_inode->data.nlink==1){ path_dir_entry->inum=0; path_inode->data.nlink--; memset(path_dir_entry->name,'\0',DIRNAMELEN); free_inode(path_inum);//XXX path_inode->dirty=1; parent_inode->data.size-=sizeof(struct dir_entry); parent_inode->dirty=1; } else{ msg->type=-1; return; } }