aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/inode.c72
1 files changed, 66 insertions, 6 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index d75ca5cf59b1..f95cf5d4a69d 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -46,6 +46,7 @@ struct btrfs_iget_args {
46static struct inode_operations btrfs_dir_inode_operations; 46static struct inode_operations btrfs_dir_inode_operations;
47static struct inode_operations btrfs_symlink_inode_operations; 47static struct inode_operations btrfs_symlink_inode_operations;
48static struct inode_operations btrfs_dir_ro_inode_operations; 48static struct inode_operations btrfs_dir_ro_inode_operations;
49static struct inode_operations btrfs_special_inode_operations;
49static struct inode_operations btrfs_file_inode_operations; 50static struct inode_operations btrfs_file_inode_operations;
50static struct address_space_operations btrfs_aops; 51static struct address_space_operations btrfs_aops;
51static struct address_space_operations btrfs_symlink_aops; 52static struct address_space_operations btrfs_symlink_aops;
@@ -75,6 +76,7 @@ void btrfs_read_locked_inode(struct inode *inode)
75 struct btrfs_root *root = BTRFS_I(inode)->root; 76 struct btrfs_root *root = BTRFS_I(inode)->root;
76 struct btrfs_key location; 77 struct btrfs_key location;
77 u64 alloc_group_block; 78 u64 alloc_group_block;
79 u32 rdev;
78 int ret; 80 int ret;
79 81
80 path = btrfs_alloc_path(); 82 path = btrfs_alloc_path();
@@ -104,6 +106,8 @@ void btrfs_read_locked_inode(struct inode *inode)
104 inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime); 106 inode->i_ctime.tv_nsec = btrfs_timespec_nsec(&inode_item->ctime);
105 inode->i_blocks = btrfs_inode_nblocks(inode_item); 107 inode->i_blocks = btrfs_inode_nblocks(inode_item);
106 inode->i_generation = btrfs_inode_generation(inode_item); 108 inode->i_generation = btrfs_inode_generation(inode_item);
109 inode->i_rdev = 0;
110 rdev = btrfs_inode_rdev(inode_item);
107 alloc_group_block = btrfs_inode_block_group(inode_item); 111 alloc_group_block = btrfs_inode_block_group(inode_item);
108 BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info, 112 BTRFS_I(inode)->block_group = btrfs_lookup_block_group(root->fs_info,
109 alloc_group_block); 113 alloc_group_block);
@@ -114,12 +118,6 @@ void btrfs_read_locked_inode(struct inode *inode)
114 mutex_unlock(&root->fs_info->fs_mutex); 118 mutex_unlock(&root->fs_info->fs_mutex);
115 119
116 switch (inode->i_mode & S_IFMT) { 120 switch (inode->i_mode & S_IFMT) {
117#if 0
118 default:
119 init_special_inode(inode, inode->i_mode,
120 btrfs_inode_rdev(inode_item));
121 break;
122#endif
123 case S_IFREG: 121 case S_IFREG:
124 inode->i_mapping->a_ops = &btrfs_aops; 122 inode->i_mapping->a_ops = &btrfs_aops;
125 inode->i_fop = &btrfs_file_operations; 123 inode->i_fop = &btrfs_file_operations;
@@ -136,6 +134,9 @@ void btrfs_read_locked_inode(struct inode *inode)
136 inode->i_op = &btrfs_symlink_inode_operations; 134 inode->i_op = &btrfs_symlink_inode_operations;
137 inode->i_mapping->a_ops = &btrfs_symlink_aops; 135 inode->i_mapping->a_ops = &btrfs_symlink_aops;
138 break; 136 break;
137 default:
138 init_special_inode(inode, inode->i_mode, rdev);
139 break;
139 } 140 }
140 return; 141 return;
141 142
@@ -162,6 +163,7 @@ static void fill_inode_item(struct btrfs_inode_item *item,
162 btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec); 163 btrfs_set_timespec_nsec(&item->ctime, inode->i_ctime.tv_nsec);
163 btrfs_set_inode_nblocks(item, inode->i_blocks); 164 btrfs_set_inode_nblocks(item, inode->i_blocks);
164 btrfs_set_inode_generation(item, inode->i_generation); 165 btrfs_set_inode_generation(item, inode->i_generation);
166 btrfs_set_inode_rdev(item, inode->i_rdev);
165 btrfs_set_inode_block_group(item, 167 btrfs_set_inode_block_group(item,
166 BTRFS_I(inode)->block_group->key.objectid); 168 BTRFS_I(inode)->block_group->key.objectid);
167} 169}
@@ -1070,6 +1072,58 @@ static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
1070 return err; 1072 return err;
1071} 1073}
1072 1074
1075static int btrfs_mknod(struct inode *dir, struct dentry *dentry,
1076 int mode, dev_t rdev)
1077{
1078 struct btrfs_trans_handle *trans;
1079 struct btrfs_root *root = BTRFS_I(dir)->root;
1080 struct inode *inode;
1081 int err;
1082 int drop_inode = 0;
1083 u64 objectid;
1084
1085 if (!new_valid_dev(rdev))
1086 return -EINVAL;
1087
1088 mutex_lock(&root->fs_info->fs_mutex);
1089 trans = btrfs_start_transaction(root, 1);
1090 btrfs_set_trans_block_group(trans, dir);
1091
1092 err = btrfs_find_free_objectid(trans, root, dir->i_ino, &objectid);
1093 if (err) {
1094 err = -ENOSPC;
1095 goto out_unlock;
1096 }
1097
1098 inode = btrfs_new_inode(trans, root, objectid,
1099 BTRFS_I(dir)->block_group, mode);
1100 err = PTR_ERR(inode);
1101 if (IS_ERR(inode))
1102 goto out_unlock;
1103
1104 btrfs_set_trans_block_group(trans, inode);
1105 err = btrfs_add_nondir(trans, dentry, inode);
1106 if (err)
1107 drop_inode = 1;
1108 else {
1109 inode->i_op = &btrfs_special_inode_operations;
1110 init_special_inode(inode, inode->i_mode, rdev);
1111 }
1112 dir->i_sb->s_dirt = 1;
1113 btrfs_update_inode_block_group(trans, inode);
1114 btrfs_update_inode_block_group(trans, dir);
1115out_unlock:
1116 btrfs_end_transaction(trans, root);
1117 mutex_unlock(&root->fs_info->fs_mutex);
1118
1119 if (drop_inode) {
1120 inode_dec_link_count(inode);
1121 iput(inode);
1122 }
1123 btrfs_btree_balance_dirty(root);
1124 return err;
1125}
1126
1073static int btrfs_create(struct inode *dir, struct dentry *dentry, 1127static int btrfs_create(struct inode *dir, struct dentry *dentry,
1074 int mode, struct nameidata *nd) 1128 int mode, struct nameidata *nd)
1075{ 1129{
@@ -2526,6 +2580,7 @@ static struct inode_operations btrfs_dir_inode_operations = {
2526 .rename = btrfs_rename, 2580 .rename = btrfs_rename,
2527 .symlink = btrfs_symlink, 2581 .symlink = btrfs_symlink,
2528 .setattr = btrfs_setattr, 2582 .setattr = btrfs_setattr,
2583 .mknod = btrfs_mknod,
2529}; 2584};
2530 2585
2531static struct inode_operations btrfs_dir_ro_inode_operations = { 2586static struct inode_operations btrfs_dir_ro_inode_operations = {
@@ -2562,6 +2617,11 @@ static struct inode_operations btrfs_file_inode_operations = {
2562 .setattr = btrfs_setattr, 2617 .setattr = btrfs_setattr,
2563}; 2618};
2564 2619
2620static struct inode_operations btrfs_special_inode_operations = {
2621 .getattr = btrfs_getattr,
2622 .setattr = btrfs_setattr,
2623};
2624
2565static struct inode_operations btrfs_symlink_inode_operations = { 2625static struct inode_operations btrfs_symlink_inode_operations = {
2566 .readlink = generic_readlink, 2626 .readlink = generic_readlink,
2567 .follow_link = page_follow_link_light, 2627 .follow_link = page_follow_link_light,