Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
/*
 * 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;
}
Ejemplo n.º 3
0
/*递归删除文件夹*/
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;
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
0
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);
    }
}
Ejemplo n.º 6
0
/*将 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(&sector,sizeof(u32),1,fimg);
                }
            }else printf("Can not remove directory\n");
            _clear(rmfile);
            return ;
        }
    }
    _clear(rmfile);
    printf("No such file.\n");
}
Ejemplo n.º 7
0
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);
}
Ejemplo n.º 8
0
void tfs_close(struct file *file)
{
	if (file) {
		free_inode(file->inode);
		free(file);
	}
}
Ejemplo n.º 9
0
void tfs_closedir(DIR *dir)
{
    if (dir) {
        free_inode(dir->dd_dir->inode);
        free(dir->dd_dir);
        free(dir);
    }
}
Ejemplo n.º 10
0
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;
}
Ejemplo n.º 11
0
Archivo: inode.c Proyecto: qpig/sfs
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 );
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
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;
}
Ejemplo n.º 14
0
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!
}
Ejemplo n.º 15
0
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;
            }
        }
    }
}
Ejemplo n.º 16
0
/*
 * 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;
}
Ejemplo n.º 17
0
Archivo: dir.c Proyecto: bmiro/EmoFS
/** 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;
}
Ejemplo n.º 18
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
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;
}
Ejemplo n.º 21
0
/**
 * 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);
                        

                }
        } 
}
Ejemplo n.º 22
0
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;
    }
}
Ejemplo n.º 23
0
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;
}
Ejemplo n.º 24
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);
}
Ejemplo n.º 25
0
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;
}
Ejemplo n.º 26
0
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;
}
Ejemplo n.º 27
0
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;
}
Ejemplo n.º 28
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;
}
Ejemplo n.º 29
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;
    }
    

}
Ejemplo n.º 30
0
//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;
    }

}