Example #1
0
int
affs_create(struct inode *dir, struct dentry *dentry, int mode, struct nameidata *nd)
{
	struct super_block *sb = dir->i_sb;
	struct inode	*inode;
	int		 error;

	pr_debug("AFFS: create(%lu,\"%.*s\",0%o)\n",dir->i_ino,(int)dentry->d_name.len,
		 dentry->d_name.name,mode);

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

	inode->i_mode = mode;
	mode_to_prot(inode);
	mark_inode_dirty(inode);

	inode->i_op = &affs_file_inode_operations;
	inode->i_fop = &affs_file_operations;
	inode->i_mapping->a_ops = (AFFS_SB(sb)->s_flags & SF_OFS) ? &affs_aops_ofs : &affs_aops;
	error = affs_add_entry(dir, inode, dentry, ST_FILE);
	if (error) {
		inode->i_nlink = 0;
		iput(inode);
		return error;
	}
	return 0;
}
Example #2
0
int
affs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
	struct inode		*inode;
	int			 error;

	pr_debug("AFFS: mkdir(%lu,\"%.*s\",0%o)\n",dir->i_ino,
		 (int)dentry->d_name.len,dentry->d_name.name,mode);

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

	inode->i_mode = S_IFDIR | mode;
	mode_to_prot(inode);

	inode->i_op = &affs_dir_inode_operations;
	inode->i_fop = &affs_dir_operations;

	error = affs_add_entry(dir, inode, dentry, ST_USERDIR);
	if (error) {
		inode->i_nlink = 0;
		mark_inode_dirty(inode);
		iput(inode);
		return error;
	}
	return 0;
}
Example #3
0
File: namei.c Project: Abioy/kasan
int
affs_create(struct inode *dir, struct dentry *dentry, umode_t mode, bool excl)
{
	struct super_block *sb = dir->i_sb;
	struct inode	*inode;
	int		 error;

	pr_debug("%s(%lu,\"%pd\",0%ho)\n",
		 __func__, dir->i_ino, dentry, mode);

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

	inode->i_mode = mode;
	mode_to_prot(inode);
	mark_inode_dirty(inode);

	inode->i_op = &affs_file_inode_operations;
	inode->i_fop = &affs_file_operations;
	inode->i_mapping->a_ops = (AFFS_SB(sb)->s_flags & SF_OFS) ? &affs_aops_ofs : &affs_aops;
	error = affs_add_entry(dir, inode, dentry, ST_FILE);
	if (error) {
		clear_nlink(inode);
		iput(inode);
		return error;
	}
	return 0;
}
Example #4
0
File: namei.c Project: Abioy/kasan
int
affs_mkdir(struct inode *dir, struct dentry *dentry, umode_t mode)
{
	struct inode		*inode;
	int			 error;

	pr_debug("%s(%lu,\"%pd\",0%ho)\n",
		 __func__, dir->i_ino, dentry, mode);

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

	inode->i_mode = S_IFDIR | mode;
	mode_to_prot(inode);

	inode->i_op = &affs_dir_inode_operations;
	inode->i_fop = &affs_dir_operations;

	error = affs_add_entry(dir, inode, dentry, ST_USERDIR);
	if (error) {
		clear_nlink(inode);
		mark_inode_dirty(inode);
		iput(inode);
		return error;
	}
	return 0;
}
Example #5
0
int
affs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
{
	struct inode		*inode;
	int			 error;
	
	pr_debug("AFFS: mkdir(%lu,\"%.*s\",0%o)\n",dir->i_ino,
		 (int)dentry->d_name.len,dentry->d_name.name,mode);

	error = -ENOSPC;
	inode = affs_new_inode(dir);
	if (!inode)
		goto out;

	inode->i_op = &affs_dir_inode_operations;
	error       = affs_add_entry(dir,NULL,inode,dentry,ST_USERDIR);
	if (error)
		goto out_iput;
	inode->i_mode = S_IFDIR | S_ISVTX | (mode & 0777 & ~current->fs->umask);
	inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode);
	d_instantiate(dentry,inode);
	mark_inode_dirty(inode);
	dir->i_version = ++event;
	mark_inode_dirty(dir);
out:
	return error;

out_iput:
	inode->i_nlink = 0;
	mark_inode_dirty(inode);
	iput(inode);
	goto out;
}
int
affs_notify_change(struct dentry *dentry, struct iattr *attr)
{
	struct inode *inode = dentry->d_inode;
	int error;

	pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);

	error = inode_change_ok(inode,attr);
	if (error)
		goto out;

	if (((attr->ia_valid & ATTR_UID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETUID)) ||
	    ((attr->ia_valid & ATTR_GID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETGID)) ||
	    ((attr->ia_valid & ATTR_MODE) &&
	     (AFFS_SB(inode->i_sb)->s_flags & (SF_SETMODE | SF_IMMUTABLE)))) {
		if (!(AFFS_SB(inode->i_sb)->s_flags & SF_QUIET))
			error = -EPERM;
		goto out;
	}

	error = inode_setattr(inode, attr);
	if (!error && (attr->ia_valid & ATTR_MODE))
		mode_to_prot(inode);
out:
	return error;
}
Example #7
0
int
affs_notify_change(struct dentry *dentry, struct iattr *attr)
{
	struct inode *inode = dentry->d_inode;
	int error;

	pr_debug("AFFS: notify_change(%lu,0x%x)\n",inode->i_ino,attr->ia_valid);

	error = inode_change_ok(inode,attr);
	if (error)
		goto out;

	if (((attr->ia_valid & ATTR_UID) && (inode->i_sb->u.affs_sb.s_flags & SF_SETUID)) ||
	    ((attr->ia_valid & ATTR_GID) && (inode->i_sb->u.affs_sb.s_flags & SF_SETGID)) ||
	    ((attr->ia_valid & ATTR_MODE) &&
	     (inode->i_sb->u.affs_sb.s_flags & (SF_SETMODE | SF_IMMUTABLE)))) {
		if (!(inode->i_sb->u.affs_sb.s_flags & SF_QUIET))
			error = -EPERM;
		goto out;
	}

	if (attr->ia_valid & ATTR_MODE)
		inode->u.affs_i.i_protect = mode_to_prot(attr->ia_mode);

	inode_setattr(inode, attr);
	mark_inode_dirty(inode);
	error = 0;
out:
	return error;
}
Example #8
0
int
affs_link(struct dentry *old_dentry, struct inode *dir, struct dentry *dentry)
{
	struct inode		*oldinode = old_dentry->d_inode;
	struct inode		*inode;
	struct buffer_head	*bh;
	unsigned long		 i;
	int			 error;
	
	pr_debug("AFFS: link(%lu,%lu,\"%.*s\")\n",oldinode->i_ino,dir->i_ino,
		 (int)dentry->d_name.len,dentry->d_name.name);

	/* N.B. Do we need this test? The dentry must be negative ... */
	bh = affs_find_entry(dir,dentry,&i);
	if (bh) {
		affs_brelse(bh);
		return -EEXIST;
	}
	if (oldinode->u.affs_i.i_hlink)	{	/* Cannot happen */
		affs_warning(dir->i_sb,"link","Impossible link to link");
		return -EINVAL;
	}
	error = -ENOSPC;
	if (!(inode = affs_new_inode(dir)))
		goto out;

	inode->i_op                = oldinode->i_op;
	inode->u.affs_i.i_protect  = mode_to_prot(oldinode->i_mode);
	inode->u.affs_i.i_original = oldinode->i_ino;
	inode->u.affs_i.i_hlink    = 1;
	inode->i_mtime             = oldinode->i_mtime;

	if (S_ISDIR(oldinode->i_mode))
		error = affs_add_entry(dir,oldinode,inode,dentry,ST_LINKDIR);
	else
		error = affs_add_entry(dir,oldinode,inode,dentry,ST_LINKFILE);
	if (error)
		inode->i_nlink = 0;
	else {
		dir->i_version = ++event;
		mark_inode_dirty(dir);
		mark_inode_dirty(oldinode);
		oldinode->i_count++;
		d_instantiate(dentry,oldinode);
	}
	mark_inode_dirty(inode);
	iput(inode);

out:
	return error;
}
Example #9
0
File: inode.c Project: 3null/linux
int
affs_notify_change(struct dentry *dentry, struct iattr *attr)
{
	struct inode *inode = dentry->d_inode;
	int error;

	pr_debug("notify_change(%lu,0x%x)\n", inode->i_ino, attr->ia_valid);

	error = inode_change_ok(inode,attr);
	if (error)
		goto out;

	if (((attr->ia_valid & ATTR_UID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETUID)) ||
	    ((attr->ia_valid & ATTR_GID) && (AFFS_SB(inode->i_sb)->s_flags & SF_SETGID)) ||
	    ((attr->ia_valid & ATTR_MODE) &&
	     (AFFS_SB(inode->i_sb)->s_flags & (SF_SETMODE | SF_IMMUTABLE)))) {
		if (!(AFFS_SB(inode->i_sb)->s_flags & SF_QUIET))
			error = -EPERM;
		goto out;
	}

	if ((attr->ia_valid & ATTR_SIZE) &&
	    attr->ia_size != i_size_read(inode)) {
		error = inode_newsize_ok(inode, attr->ia_size);
		if (error)
			return error;

		truncate_setsize(inode, attr->ia_size);
		affs_truncate(inode);
	}

	setattr_copy(inode, attr);
	mark_inode_dirty(inode);

	if (attr->ia_valid & ATTR_MODE)
		mode_to_prot(inode);
out:
	return error;
}
Example #10
0
int
affs_create(struct inode *dir, struct dentry *dentry, int mode)
{
	struct inode	*inode;
	int		 error;
	
	pr_debug("AFFS: create(%lu,\"%.*s\",0%o)\n",dir->i_ino,(int)dentry->d_name.len,
		 dentry->d_name.name,mode);

	error = -ENOSPC;
	inode = affs_new_inode(dir);
	if (!inode)
		goto out;

	pr_debug("AFFS: ino=%lu\n",inode->i_ino);
	if (dir->i_sb->u.affs_sb.s_flags & SF_OFS)
		inode->i_op = &affs_file_inode_operations_ofs;
	else
		inode->i_op = &affs_file_inode_operations;

	error = affs_add_entry(dir,NULL,inode,dentry,ST_FILE);
	if (error)
		goto out_iput;
	inode->i_mode = mode;
	inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode);
	d_instantiate(dentry,inode);
	mark_inode_dirty(inode);
	dir->i_version = ++event;
	mark_inode_dirty(dir);
out:
	return error;

out_iput:
	inode->i_nlink = 0;
	mark_inode_dirty(inode);
	iput(inode);
	goto out;
}
Example #11
0
int
affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
{
	struct super_block	*sb = dir->i_sb;
	struct buffer_head	*bh;
	struct inode		*inode;
	char			*p;
	int			 i, maxlen, error;
	char			 c, lc;

	pr_debug("AFFS: symlink(%lu,\"%.*s\" -> \"%s\")\n",dir->i_ino,
		 (int)dentry->d_name.len,dentry->d_name.name,symname);

	maxlen = AFFS_SB(sb)->s_hashsize * sizeof(u32) - 1;
	inode  = affs_new_inode(dir);
	if (!inode)
		return -ENOSPC;

	inode->i_op = &affs_symlink_inode_operations;
	inode->i_data.a_ops = &affs_symlink_aops;
	inode->i_mode = S_IFLNK | 0777;
	mode_to_prot(inode);

	error = -EIO;
	bh = affs_bread(sb, inode->i_ino);
	if (!bh)
		goto err;
	i  = 0;
	p  = (char *)AFFS_HEAD(bh)->table;
	lc = '/';
	if (*symname == '/') {
		struct affs_sb_info *sbi = AFFS_SB(sb);
		while (*symname == '/')
			symname++;
		spin_lock(&sbi->symlink_lock);
		while (sbi->s_volume[i])	/* Cannot overflow */
			*p++ = sbi->s_volume[i++];
		spin_unlock(&sbi->symlink_lock);
	}
	while (i < maxlen && (c = *symname++)) {
		if (c == '.' && lc == '/' && *symname == '.' && symname[1] == '/') {
			*p++ = '/';
			i++;
			symname += 2;
			lc = '/';
		} else if (c == '.' && lc == '/' && *symname == '/') {
			symname++;
			lc = '/';
		} else {
			*p++ = c;
			lc   = c;
			i++;
		}
		if (lc == '/')
			while (*symname == '/')
				symname++;
	}
	*p = 0;
	mark_buffer_dirty_inode(bh, inode);
	affs_brelse(bh);
	mark_inode_dirty(inode);

	error = affs_add_entry(dir, inode, dentry, ST_SOFTLINK);
	if (error)
		goto err;

	return 0;

err:
	inode->i_nlink = 0;
	mark_inode_dirty(inode);
	iput(inode);
	return error;
}
Example #12
0
int
affs_symlink(struct inode *dir, struct dentry *dentry, const char *symname)
{
	struct buffer_head	*bh;
	struct inode		*inode;
	char			*p;
	unsigned long		 tmp;
	int			 i, maxlen, error;
	char			 c, lc;

	pr_debug("AFFS: symlink(%lu,\"%.*s\" -> \"%s\")\n",dir->i_ino,
		 (int)dentry->d_name.len,dentry->d_name.name,symname);
	
	maxlen = 4 * AFFS_I2HSIZE(dir) - 1;
	error = -ENOSPC;
	inode  = affs_new_inode(dir);
	if (!inode)
		goto out;

	inode->i_op   = &affs_symlink_inode_operations;
	inode->i_mode = S_IFLNK | 0777;
	inode->u.affs_i.i_protect = mode_to_prot(inode->i_mode);
	error = -EIO;
	bh = affs_bread(inode->i_dev,inode->i_ino,AFFS_I2BSIZE(inode));
	if (!bh)
		goto out_iput;
	i  = 0;
	p  = ((struct slink_front *)bh->b_data)->symname;
	lc = '/';
	if (*symname == '/') {
		while (*symname == '/')
			symname++;
		while (inode->i_sb->u.affs_sb.s_volume[i])	/* Cannot overflow */
			*p++ = inode->i_sb->u.affs_sb.s_volume[i++];
	}
	while (i < maxlen && (c = *symname++)) {
		if (c == '.' && lc == '/' && *symname == '.' && symname[1] == '/') {
			*p++ = '/';
			i++;
			symname += 2;
			lc = '/';
		} else if (c == '.' && lc == '/' && *symname == '/') {
			symname++;
			lc = '/';
		} else {
			*p++ = c;
			lc   = c;
			i++;
		}
		if (lc == '/')
			while (*symname == '/')
				symname++;
	}
	*p = 0;
	mark_buffer_dirty(bh,1);
	affs_brelse(bh);
	mark_inode_dirty(inode);

	/* N.B. This test shouldn't be necessary ... dentry must be negative */
	error = -EEXIST;
	bh = affs_find_entry(dir,dentry,&tmp);
	if (bh)
		goto out_release;
	/* N.B. Shouldn't we add the entry before dirtying the buffer? */
	error = affs_add_entry(dir,NULL,inode,dentry,ST_SOFTLINK);
	if (error)
		goto out_release;
	d_instantiate(dentry,inode);
	dir->i_version = ++event;
	mark_inode_dirty(dir);

out:
	return error;

out_release:
	affs_brelse(bh);
out_iput:
	inode->i_nlink = 0;
	mark_inode_dirty(inode);
	iput(inode);
	goto out;
}