Exemplo n.º 1
0
Arquivo: namei.c Projeto: foolsh/elks
int minix_mkdir(register struct inode *dir, char *name, size_t len, int mode)
{
    int error;
    register struct inode *inode;
    struct buffer_head *bh;
    struct minix_dir_entry *de;

    error = -EINVAL;
    if (!dir || !dir->i_sb)
	goto mkdir2;
    error = -EMLINK;
    if (dir->i_nlink >= MINIX_LINK_MAX)
	goto mkdir2;

    error = -EEXIST;
    bh = minix_find_entry(dir, name, len, &de);
    if (bh) {
	unmap_brelse(bh);
	goto mkdir2;
    }
    error = -ENOSPC;
    inode = minix_new_inode(dir, (__u16)mode);
    if (!inode)
	goto mkdir2;
/*--------------------------------------------------------------------------------*/
    debug("m_mkdir: new_inode succeeded\n");
    debug("m_mkdir: starting minix_bread\n");
    bh = minix_bread(inode, 0, 1);
    if (!bh) {
	goto mkdir1;
    }
    debug("m_mkdir: read succeeded\n");
    inode->i_size = (dir->i_sb->u.minix_sb.s_dirsize << 1);
    map_buffer(bh);
    de = (struct minix_dir_entry *) bh->b_data;
    de->inode = inode->i_ino;
    strcpy(de->name, ".");
    de = (struct minix_dir_entry *)(((char *)de) + dir->i_sb->u.minix_sb.s_dirsize);
    de->inode = dir->i_ino;
    strcpy(de->name, "..");
    mark_buffer_dirty(bh, 1);
    unmap_brelse(bh);
    debug("m_mkdir: dir_block update succeeded\n");
/*--------------------------------------------------------------------------------*/
    error = minix_add_entry(dir, name, len, inode->i_ino);
    if (error) {
      mkdir1:
	inode->i_nlink--;
    }
    else {
	inode->i_nlink++;
	dir->i_nlink++;
    }
    inode->i_dirt = 1;
    iput(inode);
 mkdir2:
    iput(dir);
    debug("m_mkdir: done!\n");
    return error;
}
Exemplo n.º 2
0
Arquivo: namei.c Projeto: lithoxs/elks
int minix_mknod(register struct inode *dir, char *name, size_t len,
		int mode, int rdev)
{
    int error;
    register struct inode *inode;
    struct buffer_head *bh;
    struct minix_dir_entry *de;

/*    if (!dir)
	return -ENOENT;*/	/* Already checked by do_mknod() */

    error = -EEXIST;
    bh = minix_find_entry(dir, name, len, &de);
    if (bh) {
	unmap_brelse(bh);
	goto mknod2;
    }
    error = -ENOSPC;
    inode = minix_new_inode(dir, (__u16)mode);
    if (!inode)
	goto mknod2;
/*----------------------------------------------------------------------*/
    if (S_ISBLK(mode) || S_ISCHR(mode))
	inode->i_rdev = to_kdev_t(rdev);
/*----------------------------------------------------------------------*/
    error = minix_add_entry(dir, name, len, inode->i_ino);
    if (error) {
	inode->i_nlink--;
	inode->i_dirt = 1;
    }
    iput(inode);
 mknod2:
    iput(dir);
    return error;
}
Exemplo n.º 3
0
Arquivo: namei.c Projeto: foolsh/elks
int minix_create(register struct inode *dir, char *name, size_t len,
		 int mode, struct inode **result)
{
    register struct inode *inode = NULL;
    int error;

    error = -ENOENT;
    if (!dir)
	goto create2;

    error = -ENOSPC;
    inode = minix_new_inode(dir, (__u16)mode);
    if (!inode)
	goto create1;
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
    error = minix_add_entry(dir, name, len, inode->i_ino);
    if(error) {
	inode->i_nlink--;
	inode->i_dirt = 1;
	iput(inode);
	inode = NULL;
    }
 create1:
    iput(dir);
 create2:
    *result = inode;
    return error;
}
Exemplo n.º 4
0
int minix_create(struct inode * dir, struct dentry *dentry, int mode)
{
	int error;
	struct inode * inode;
	struct buffer_head * bh;
	struct minix_dir_entry * de;

	if (!dir)
		return -ENOENT;
	inode = minix_new_inode(dir);
	if (!inode)
		return -ENOSPC;
	inode->i_op = &minix_file_inode_operations;
	inode->i_mode = mode;
	mark_inode_dirty(inode);
	error = minix_add_entry(dir, dentry->d_name.name,
				dentry->d_name.len, &bh ,&de);
	if (error) {
		inode->i_nlink--;
		mark_inode_dirty(inode);
		iput(inode);
		return error;
	}
	de->inode = inode->i_ino;
	mark_buffer_dirty(bh, 1);
	brelse(bh);
	d_instantiate(dentry, inode);
	return 0;
}
Exemplo n.º 5
0
static int minix_symlink(struct inode * dir, struct dentry *dentry,
	  const char * symname)
{
	int err = -ENAMETOOLONG;
	int i = strlen(symname)+1;
	struct inode * inode;

	if (i > dir->i_sb->s_blocksize)
		goto out;

	inode = minix_new_inode(dir, &err);
	if (!inode)
		goto out;

	inode->i_mode = S_IFLNK | 0777;
	minix_set_inode(inode, 0);
	err = page_symlink(inode, symname, i);
	if (err)
		goto out_fail;

	err = add_nondir(dentry, inode);
out:
	return err;

out_fail:
	dec_count(inode);
	iput(inode);
	goto out;
}
Exemplo n.º 6
0
int minix_create(register struct inode *dir, char *name, size_t len,
		 int mode, struct inode **result)
{
    register struct inode *inode;
    struct buffer_head *bh;
    struct minix_dir_entry *de;
    int error;

    *result = NULL;
    if (!dir)
	return -ENOENT;
    inode = minix_new_inode(dir);
    if (!inode) {
	iput(dir);
	return -ENOSPC;
    }
    inode->i_op = &minix_file_inode_operations;
    inode->i_mode = (__u16) mode;
    inode->i_dirt = 1;
    error = minix_add_entry(dir, name, len, &bh, &de);
    if (error) {
	inode->i_nlink--;
	inode->i_dirt = 1;
	iput(inode);
	iput(dir);
	return error;
    }
    de->inode = inode->i_ino;
    mark_buffer_dirty(bh, 1);
    brelse(bh);
    iput(dir);
    *result = inode;
    return 0;
}
Exemplo n.º 7
0
static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
{
	struct inode * inode;
	int err;

	inode_inc_link_count(dir);

	inode = minix_new_inode(dir, S_IFDIR | mode, &err);
	if (!inode)
		goto out_dir;

	minix_set_inode(inode, 0);

	inode_inc_link_count(inode);

	err = minix_make_empty(inode, dir);
	if (err)
		goto out_fail;

	err = minix_add_link(dentry, inode);
	if (err)
		goto out_fail;

	d_instantiate(dentry, inode);
out:
	return err;

out_fail:
	inode_dec_link_count(inode);
	inode_dec_link_count(inode);
	iput(inode);
out_dir:
	inode_dec_link_count(dir);
	goto out;
}
Exemplo n.º 8
0
int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
{
	int error;
	struct inode * inode;
	struct buffer_head * bh, *dir_block;
	struct minix_dir_entry * de;
	struct minix_sb_info * info;

	if (!dir || !dir->i_sb)
		return -EINVAL;
	info = &dir->i_sb->u.minix_sb;
	bh = minix_find_entry(dir, dentry->d_name.name,
			      dentry->d_name.len, &de);
	if (bh) {
		brelse(bh);
		return -EEXIST;
	}
	if (dir->i_nlink >= info->s_link_max)
		return -EMLINK;
	inode = minix_new_inode(dir);
	if (!inode)
		return -ENOSPC;
	inode->i_op = &minix_dir_inode_operations;
	inode->i_size = 2 * info->s_dirsize;
	dir_block = minix_bread(inode,0,1);
	if (!dir_block) {
		inode->i_nlink--;
		mark_inode_dirty(inode);
		iput(inode);
		return -ENOSPC;
	}
	de = (struct minix_dir_entry *) dir_block->b_data;
	de->inode=inode->i_ino;
	strcpy(de->name,".");
	de = (struct minix_dir_entry *) (dir_block->b_data + info->s_dirsize);
	de->inode = dir->i_ino;
	strcpy(de->name,"..");
	inode->i_nlink = 2;
	mark_buffer_dirty(dir_block, 1);
	brelse(dir_block);
	inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs->umask);
	if (dir->i_mode & S_ISGID)
		inode->i_mode |= S_ISGID;
	mark_inode_dirty(inode);
	error = minix_add_entry(dir, dentry->d_name.name,
				dentry->d_name.len, &bh, &de);
	if (error) {
		inode->i_nlink=0;
		iput(inode);
		return error;
	}
	de->inode = inode->i_ino;
	mark_buffer_dirty(bh, 1);
	dir->i_nlink++;
	mark_inode_dirty(dir);
	brelse(bh);
	d_instantiate(dentry, inode);
	return 0;
}
Exemplo n.º 9
0
int minix_symlink(struct inode *dir, char *name, size_t len, char *symname)
{
    struct minix_dir_entry *de;
    register struct inode *inode = NULL;
    struct buffer_head *bh = NULL;
    register struct buffer_head *name_block = NULL;
    int i;
    char c;

    if (!(inode = minix_new_inode(dir))) {
	iput(dir);
	return -ENOSPC;
    }
    inode->i_mode = (__u16) (S_IFLNK | 0777);
    inode->i_op = &minix_symlink_inode_operations;
    name_block = minix_bread(inode, 0, 1);
    if (!name_block) {
	iput(dir);
	inode->i_nlink--;
	inode->i_dirt = 1;
	iput(inode);
	return -ENOSPC;
    }
    map_buffer(name_block);
    i = 0;
    while (i < 1023 && (c = *(symname++)))
	name_block->b_data[i++] = c;
    name_block->b_data[i] = 0;
    mark_buffer_dirty(name_block, 1);
    unmap_brelse(name_block);
    inode->i_size = (__u32) i;
    inode->i_dirt = 1;
    bh = minix_find_entry(dir, name, len, &de);
    map_buffer(bh);
    if (bh) {
	inode->i_nlink--;
	inode->i_dirt = 1;
	iput(inode);
	unmap_brelse(bh);
	iput(dir);
	return -EEXIST;
    }
    i = minix_add_entry(dir, name, len, &bh, &de);
    if (i) {
	inode->i_nlink--;
	inode->i_dirt = 1;
	iput(inode);
	iput(dir);
	return i;
    }
    de->inode = inode->i_ino;
    mark_buffer_dirty(bh, 1);
    brelse(bh);
    iput(dir);
    iput(inode);
    return 0;
}
Exemplo n.º 10
0
Arquivo: namei.c Projeto: mhei/linux
static int minix_tmpfile(struct inode *dir, struct dentry *dentry, umode_t mode)
{
    int error;
    struct inode *inode = minix_new_inode(dir, mode, &error);
    if (inode) {
        minix_set_inode(inode, 0);
        mark_inode_dirty(inode);
        d_tmpfile(dentry, inode);
    }
    return error;
}
Exemplo n.º 11
0
int minix_symlink(struct inode * dir, struct dentry *dentry,
		  const char * symname)
{
	struct minix_dir_entry * de;
	struct inode * inode = NULL;
	struct buffer_head * bh = NULL, * name_block = NULL;
	int i;
	char c;

	if (!(inode = minix_new_inode(dir)))
		return -ENOSPC;

	inode->i_mode = S_IFLNK | 0777;
	inode->i_op = &minix_symlink_inode_operations;
	name_block = minix_bread(inode,0,1);
	if (!name_block) {
		inode->i_nlink--;
	        mark_inode_dirty(inode);
		iput(inode);
		return -ENOSPC;
	}
	i = 0;
	while (i < 1023 && (c=*(symname++)))
		name_block->b_data[i++] = c;
	name_block->b_data[i] = 0;
	mark_buffer_dirty(name_block, 1);
	brelse(name_block);
	inode->i_size = i;
	mark_inode_dirty(inode);
	bh = minix_find_entry(dir, dentry->d_name.name,
			      dentry->d_name.len, &de);
	if (bh) {
		inode->i_nlink--;
		mark_inode_dirty(inode);
		iput(inode);
		brelse(bh);
		return -EEXIST;
	}
	i = minix_add_entry(dir, dentry->d_name.name,
			    dentry->d_name.len, &bh, &de);
	if (i) {
		inode->i_nlink--;
		mark_inode_dirty(inode);
		iput(inode);
		return i;
	}
	de->inode = inode->i_ino;
	mark_buffer_dirty(bh, 1);
	brelse(bh);
	d_instantiate(dentry, inode);
	return 0;
}
Exemplo n.º 12
0
struct inode *minix_inode_create(struct inode *dir, char *base, int len)
{
	struct minix_dentry *de;
	struct inode *inode;
	struct block *block;
	int entries, i, k, n;

	if (len > MINIX_NAME_LEN)
		return NULL;
	/* exist? */
	de = minix_lookup_dentry(dir, base, len, NULL);
	if (de)
		return NULL;
	/* find an empty dir entry */
	entries = dir->i_size / MINIX_DENTRY_SIZE;
	for (i = 0; i < entries; i += n) {
		block = bmap_block(dir, i / MINIX_DENTRIES_PER_BLOCK, 0);
		de = (struct minix_dentry *)block->b_data;
		n = min(entries - i, MINIX_DENTRIES_PER_BLOCK);
		for (k = 0; k < n; k++, de++) {
			if (de->d_ino == 0)
				goto found;
		}
		if (i + n < entries || !(entries % MINIX_DENTRIES_PER_BLOCK)) {
			put_block(block);
			block = NULL;
		}
	}
	/* create a new data block and get dir entry from it */
	if (!block) {
		block = bmap_block(dir, entries / MINIX_DENTRIES_PER_BLOCK, 1);
		if (!block)
			return NULL;
		if (block->b_refcnt != 1)
			panic("Not new block(ref:%d)", block->b_refcnt);
		de = (struct minix_dentry *)block->b_data;
	}
	inode_update_size(dir, dir->i_size + MINIX_DENTRY_SIZE);
found:
	inode = minix_new_inode(dir->i_sb);
	if (!inode)
		goto out;
	/* fill dir entry */
	strncpy(de->d_name, base, len);
	de->d_name[len] = '\0';
	de->d_ino = inode->i_ino;
	minix_inode_dirty_block(dir, block);
out:
	put_block(block);
	return inode;
}
Exemplo n.º 13
0
static int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, dev_t rdev)
{
	int error;
	struct inode *inode;

	if (!old_valid_dev(rdev))
		return -EINVAL;

	inode = minix_new_inode(dir, mode, &error);

	if (inode) {
		minix_set_inode(inode, rdev);
		mark_inode_dirty(inode);
		error = add_nondir(dentry, inode);
	}
	return error;
}
Exemplo n.º 14
0
int minix_mknod(struct inode * dir, struct dentry *dentry, int mode, int rdev)
{
	int error;
	struct inode * inode;
	struct buffer_head * bh;
	struct minix_dir_entry * de;

	if (!dir)
		return -ENOENT;
	bh = minix_find_entry(dir, dentry->d_name.name,
			      dentry->d_name.len, &de);
	if (bh) {
		brelse(bh);
		return -EEXIST;
	}
	inode = minix_new_inode(dir);
	if (!inode)
		return -ENOSPC;
	inode->i_uid = current->fsuid;
	inode->i_mode = mode;
	inode->i_op = NULL;
	if (S_ISREG(inode->i_mode))
		inode->i_op = &minix_file_inode_operations;
	else if (S_ISCHR(inode->i_mode))
		inode->i_op = &chrdev_inode_operations;
	else if (S_ISBLK(inode->i_mode))
		inode->i_op = &blkdev_inode_operations;
	else if (S_ISFIFO(inode->i_mode))
		init_fifo(inode);
	if (S_ISBLK(mode) || S_ISCHR(mode))
		inode->i_rdev = to_kdev_t(rdev);
	mark_inode_dirty(inode);
	error = minix_add_entry(dir, dentry->d_name.name, dentry->d_name.len, &bh, &de);
	if (error) {
		inode->i_nlink--;
		mark_inode_dirty(inode);
		iput(inode);
		return error;
	}
	de->inode = inode->i_ino;
	mark_buffer_dirty(bh, 1);
	brelse(bh);
	d_instantiate(dentry, inode);
	return 0;
}
Exemplo n.º 15
0
Arquivo: namei.c Projeto: foolsh/elks
int minix_symlink(struct inode *dir, char *name, size_t len, char *symname)
{
    int error;
    register struct inode *inode;
    register struct buffer_head *bh;
    struct minix_dir_entry *de;

    error = -EEXIST;
    bh = minix_find_entry(dir, name, len, &de);
    if (bh) {
	unmap_brelse(bh);
	goto symlink2;
    }
    error = -ENOSPC;
    inode = minix_new_inode(dir, S_IFLNK);
    if (!inode)
	goto symlink2;
/*----------------------------------------------------------------------*/
    bh = minix_bread(inode, 0, 1);
    if (!bh)
	goto symlink1;
    map_buffer(bh);
    if((error = strlen_fromfs(symname)) > 1023)
	error = 1023;
    memcpy_fromfs(bh->b_data, symname, error);
    bh->b_data[error] = 0;
    inode->i_size = (__u32) error;
    mark_buffer_dirty(bh, 1);
    unmap_brelse(bh);
/*----------------------------------------------------------------------*/
    error = minix_add_entry(dir, name, len, inode->i_ino);
    if (error) {
      symlink1:
	inode->i_nlink--;
	inode->i_dirt = 1;
    }
    iput(inode);
 symlink2:
    iput(dir);
    return error;
}
Exemplo n.º 16
0
static int minix_mkdir(struct inode * dir, struct dentry *dentry, int mode)
{
	struct inode * inode;
	int err = -EMLINK;

	if (dir->i_nlink >= minix_sb(dir->i_sb)->s_link_max)
		goto out;

	inc_count(dir);

	inode = minix_new_inode(dir, &err);
	if (!inode)
		goto out_dir;

	inode->i_mode = S_IFDIR | mode;
	if (dir->i_mode & S_ISGID)
		inode->i_mode |= S_ISGID;
	minix_set_inode(inode, 0);

	inc_count(inode);

	err = minix_make_empty(inode, dir);
	if (err)
		goto out_fail;

	err = minix_add_link(dentry, inode);
	if (err)
		goto out_fail;

	d_instantiate(dentry, inode);
out:
	return err;

out_fail:
	dec_count(inode);
	dec_count(inode);
	iput(inode);
out_dir:
	dec_count(dir);
	goto out;
}
Exemplo n.º 17
0
Arquivo: namei.c Projeto: lithoxs/elks
int minix_create(register struct inode *dir, char *name, size_t len,
		 int mode, struct inode **result)
{
    register struct inode *inode = NULL;
    int error;

    if (!dir)
	error = -ENOENT;
    else if (!(inode = minix_new_inode(dir, (__u16)mode)))
	error = -ENOSPC;
    else {
/*----------------------------------------------------------------------*/
/*----------------------------------------------------------------------*/
	if ((error = minix_add_entry(dir, name, len, inode->i_ino))) {
	    inode->i_nlink--;
	    inode->i_dirt = 1;
	    iput(inode);
	    inode = NULL;
	}
	iput(dir);
    }
    *result = inode;
    return error;
}
Exemplo n.º 18
0
int minix_mknod(register struct inode *dir, char *name, size_t len,
		int mode, int rdev)
{
    int error;
    register struct inode *inode;
    struct buffer_head *bh;
    struct minix_dir_entry *de;

    if (!dir)
	return -ENOENT;
    bh = minix_find_entry(dir, name, len, &de);
    if (bh) {
	brelse(bh);
	iput(dir);
	return -EEXIST;
    }
    inode = minix_new_inode(dir);
    if (!inode) {
	iput(dir);
	return -ENOSPC;
    }
    inode->i_uid = current->euid;
    inode->i_mode = (__u16) mode;
    inode->i_op = NULL;

    minix_set_ops(inode);

    if (S_ISDIR(inode->i_mode))
	if (dir->i_mode & S_ISGID)
	    inode->i_mode |= S_ISGID;

    if (S_ISBLK(mode) || S_ISCHR(mode))
	inode->i_rdev = to_kdev_t(rdev);
    inode->i_dirt = 1;
    error = minix_add_entry(dir, name, len, &bh, &de);
#if 1
    if (error) {
	inode->i_nlink--;
	inode->i_dirt = 1;
	iput(inode);
	iput(dir);
	return error;
    }
    de->inode = inode->i_ino;
    mark_buffer_dirty(bh, 1);
    brelse(bh);
    iput(dir);
    iput(inode);
    return 0;
#else  /* MJN3: If the ordering of the iput()s isn't important, do this. */
    if (error) {
	inode->i_nlink--;
	inode->i_dirt = 1;
    } else {
	de->inode = inode->i_ino;
	mark_buffer_dirty(bh, 1);
	brelse(bh);
    }
    iput(dir);
    iput(inode);
    return error;
#endif
}
Exemplo n.º 19
0
int minix_mkdir(register struct inode *dir, char *name, size_t len, int mode)
{
    int error;
    register struct inode *inode;
    struct buffer_head *dir_block;
    struct buffer_head *bh;
    struct minix_dir_entry *de;

    if (!dir || !dir->i_sb) {
	iput(dir);
	return -EINVAL;
    }
    bh = minix_find_entry(dir, name, len, &de);
    if (bh) {
	brelse(bh);
	iput(dir);
	return -EEXIST;
    }
    if (dir->i_nlink >= MINIX_LINK_MAX) {
	iput(dir);
	return -EMLINK;
    }
    inode = minix_new_inode(dir);
    if (!inode) {
	iput(dir);
	return -ENOSPC;
    }
    debug("m_mkdir: new_inode succeeded\n");
    inode->i_op = &minix_dir_inode_operations;
    inode->i_size = 2 * dir->i_sb->u.minix_sb.s_dirsize;
    debug("m_mkdir: starting minix_bread\n");
    dir_block = minix_bread(inode, 0, 1);
    if (!dir_block) {
	iput(dir);
	inode->i_nlink--;
	inode->i_dirt = 1;
	iput(inode);
	return -ENOSPC;
    }
    debug("m_mkdir: read succeeded\n");
    map_buffer(dir_block);
    de = (struct minix_dir_entry *) dir_block->b_data;
    de->inode = inode->i_ino;
    strcpy(de->name, ".");
    de =
	(struct minix_dir_entry *) (dir_block->b_data +
				    dir->i_sb->u.minix_sb.s_dirsize);
    de->inode = dir->i_ino;
    strcpy(de->name, "..");
    inode->i_nlink = 2;
    mark_buffer_dirty(dir_block, 1);
    unmap_brelse(dir_block);
    debug("m_mkdir: dir_block update succeeded\n");
    inode->i_mode = S_IFDIR | (mode & 0777 & ~current->fs.umask);
    if (dir->i_mode & S_ISGID)
	inode->i_mode |= S_ISGID;
    inode->i_dirt = 1;
    error = minix_add_entry(dir, name, len, &bh, &de);
    if (error) {
	iput(dir);
	inode->i_nlink = 0;
	iput(inode);
	return error;
    }
    map_buffer(bh);
    de->inode = inode->i_ino;
    mark_buffer_dirty(bh, 1);
    dir->i_nlink++;
    dir->i_dirt = 1;
    iput(dir);
    iput(inode);
    unmap_brelse(bh);
    debug("m_mkdir: done!\n");
    return 0;
}