[Btrfs-devel] Mknod: Operation not permitted

Frank Groeneveld frankgroeneveld at gmail.com
Fri Jun 29 08:45:39 PDT 2007


Thanks!
It didn't apply completely clean (2 hunks failed for inode.c) but  
after applying that by hand, it seems to work.

Frank

Op 29-jun-2007, om 17:30 heeft Josef Bacik het volgende geschreven:

> On Fri, Jun 29, 2007 at 04:44:10PM +0200, Frank Groeneveld wrote:
>> When trying to move my root to a btrfs filesystem, I found a missing
>> feature (or a bug). It's not possible to create device files. To
>> reproduce, run this on a btrfs filesystem:
>>
>> mknod test c 1 1
>>
>> result:
>> mknod: `test': Operation not permitted
>>
>>
>
> Hello,
>
> Please try this patch, it should work for you, I promise it  
> compiled and
> pretended to work for me :).
>
> Josef
>
> diff -r 080c0640a527 inode.c
> --- a/inode.c	Thu Jun 28 15:57:36 2007 -0400
> +++ b/inode.c	Fri Jun 29 07:18:42 2007 -0400
> @@ -47,6 +47,7 @@ static struct inode_operations btrfs_dir
>  static struct inode_operations btrfs_dir_inode_operations;
>  static struct inode_operations btrfs_symlink_inode_operations;
>  static struct inode_operations btrfs_dir_ro_inode_operations;
> +static struct inode_operations btrfs_special_inode_operations;
>  static struct inode_operations btrfs_file_inode_operations;
>  static struct address_space_operations btrfs_aops;
>  static struct address_space_operations btrfs_symlink_aops;
> @@ -1068,6 +1069,58 @@ static int btrfs_add_nondir(struct btrfs
>  	}
>  	if (err > 0)
>  		err = -EEXIST;
> +	return err;
> +}
> +
> +static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
> +			int mode, dev_t rdev)
> +{
> +	struct btrfs_trans_handle *trans;
> +	struct btrfs_root *root = BTRFS_I(dir)->root;
> +	struct inode *inode;
> +	int err;
> +	int drop_inode = 0;
> +	u64 objectid;
> +
> +	if (!new_valid_dev(rdev))
> +		return -EINVAL;
> +
> +	mutex_lock(&root->fs_info->fs_mutex);
> +	trans = btrfs_start_transaction(root, 1);
> +	btrfs_set_trans_block_group(trans, dir);
> +
> +	err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
> +	if (err) {
> +		err = -ENOSPC;
> +		goto out_unlock;
> +	}
> +
> +	inode = btrfs_new_inode(trans, root, objectid,
> +				BTRFS_I(dir)->block_group, mode);
> +	err = PTR_ERR(inode);
> +	if (IS_ERR(inode))
> +		goto out_unlock;
> +
> +	btrfs_set_trans_block_group(trans, inode);
> +	err = btrfs_add_nondir(trans, dentry, inode);
> +	if (err)
> +		drop_inode = 1;
> +	else {
> +		inode->i_op = &btrfs_special_inode_operations;
> +		init_special_inode(inode, inode->i_mode, rdev);
> +	}
> +	dir->i_sb->s_dirt = 1;
> +	btrfs_update_inode_block_group(trans, inode);
> +	btrfs_update_inode_block_group(trans, dir);
> +out_unlock:
> +	btrfs_end_transaction(trans, root);
> +	mutex_unlock(&root->fs_info->fs_mutex);
> +
> +	if (drop_inode) {
> +		inode_dec_link_count(inode);
> +		iput(inode);
> +	}
> +	btrfs_btree_balance_dirty(root);
>  	return err;
>  }
>
> @@ -2527,6 +2580,7 @@ static struct inode_operations btrfs_dir
>  	.rename		= btrfs_rename,
>  	.symlink	= btrfs_symlink,
>  	.setattr	= btrfs_setattr,
> +	.mknod		= btrfs_mknod,
>  };
>
>  static struct inode_operations btrfs_dir_ro_inode_operations = {
> @@ -2563,6 +2617,11 @@ static struct inode_operations btrfs_fil
>  	.setattr	= btrfs_setattr,
>  };
>
> +static struct inode_operations btrfs_special_inode_operations = {
> +	.getattr	= btrfs_getattr,
> +	.setattr	= btrfs_setattr,
> +};
> +
>  static struct inode_operations btrfs_symlink_inode_operations = {
>  	.readlink	= generic_readlink,
>  	.follow_link	= page_follow_link_light,




More information about the Btrfs-devel mailing list