[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