aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-03-25 13:44:56 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-03-25 13:44:56 -0400
commit134e97313491c3a3d6bc3eca3b7c9c64408cbd08 (patch)
treeb886139f45eaee59f0f46e65952cac99b05c7db2 /fs/btrfs/super.c
parent78fae27ebf5bd35fb9b2e4213e486635eacfc0ad (diff)
Btrfs: unlink and delete_inode
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c117
1 files changed, 114 insertions, 3 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 094a66c267b4..f96bd92155cc 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -187,6 +187,104 @@ static void btrfs_read_locked_inode(struct inode *inode)
187 return; 187 return;
188} 188}
189 189
190static int btrfs_unlink(struct inode *dir, struct dentry *dentry)
191{
192 struct btrfs_path path;
193 struct btrfs_root *root;
194 struct btrfs_trans_handle *trans;
195 const char *name = dentry->d_name.name;
196 int name_len = dentry->d_name.len;
197 int ret;
198 u64 objectid;
199 struct btrfs_dir_item *di;
200
201 btrfs_init_path(&path);
202 root = btrfs_sb(dir->i_sb);
203 mutex_lock(&root->fs_info->fs_mutex);
204 trans = btrfs_start_transaction(root, 1);
205
206 ret = btrfs_lookup_dir_item(trans, root, &path, dir->i_ino,
207 name, name_len, -1);
208 if (ret < 0)
209 goto err;
210 if (ret > 0) {
211 ret = -ENOENT;
212 goto err;
213 }
214 di = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0],
215 struct btrfs_dir_item);
216 objectid = btrfs_dir_objectid(di);
217
218 ret = btrfs_del_item(trans, root, &path);
219 BUG_ON(ret);
220 dentry->d_inode->i_ctime = dir->i_ctime;
221err:
222 btrfs_release_path(root, &path);
223 btrfs_end_transaction(trans, root);
224 mutex_unlock(&root->fs_info->fs_mutex);
225 if (ret == 0)
226 inode_dec_link_count(dentry->d_inode);
227 return ret;
228}
229
230static int btrfs_free_inode(struct btrfs_trans_handle *trans,
231 struct btrfs_root *root,
232 struct inode *inode)
233{
234 u64 objectid = inode->i_ino;
235 struct btrfs_path path;
236 struct btrfs_inode_map_item *map;
237 struct btrfs_key stat_data_key;
238 int ret;
239 clear_inode(inode);
240 btrfs_init_path(&path);
241 ret = btrfs_lookup_inode_map(trans, root, &path, objectid, -1);
242 if (ret) {
243 if (ret > 0)
244 ret = -ENOENT;
245 btrfs_release_path(root, &path);
246 goto error;
247 }
248 map = btrfs_item_ptr(btrfs_buffer_leaf(path.nodes[0]), path.slots[0],
249 struct btrfs_inode_map_item);
250 btrfs_disk_key_to_cpu(&stat_data_key, &map->key);
251 ret = btrfs_del_item(trans, root->fs_info->inode_root, &path);
252 BUG_ON(ret);
253 btrfs_release_path(root, &path);
254 btrfs_init_path(&path);
255
256 ret = btrfs_lookup_inode(trans, root, &path, objectid, -1);
257 BUG_ON(ret);
258 ret = btrfs_del_item(trans, root, &path);
259 BUG_ON(ret);
260 btrfs_release_path(root, &path);
261error:
262 return ret;
263}
264
265static void btrfs_delete_inode(struct inode *inode)
266{
267 struct btrfs_trans_handle *trans;
268 struct btrfs_root *root = btrfs_sb(inode->i_sb);
269 truncate_inode_pages(&inode->i_data, 0);
270 if (is_bad_inode(inode)) {
271 goto no_delete;
272 }
273 inode->i_size = 0;
274 if (inode->i_blocks)
275 WARN_ON(1);
276
277 mutex_lock(&root->fs_info->fs_mutex);
278 trans = btrfs_start_transaction(root, 1);
279 btrfs_free_inode(trans, root, inode);
280 btrfs_end_transaction(trans, root);
281 mutex_unlock(&root->fs_info->fs_mutex);
282 return;
283no_delete:
284 clear_inode(inode);
285}
286
287
190static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry, 288static int btrfs_inode_by_name(struct inode *dir, struct dentry *dentry,
191 ino_t *ino) 289 ino_t *ino)
192{ 290{
@@ -272,6 +370,13 @@ static int btrfs_readdir(struct file *filp, void *dirent, filldir_t filldir)
272 leaf = btrfs_buffer_leaf(path.nodes[0]); 370 leaf = btrfs_buffer_leaf(path.nodes[0]);
273 nritems = btrfs_header_nritems(&leaf->header); 371 nritems = btrfs_header_nritems(&leaf->header);
274 slot = path.slots[0]; 372 slot = path.slots[0];
373#if 0
374 page_cache_readahead(
375 inode->i_sb->s_bdev->bd_inode->i_mapping,
376 &filp->f_ra, filp,
377 path.nodes[0]->b_blocknr >>
378 (PAGE_CACHE_SHIFT - inode->i_blkbits), 1);
379#endif
275 } else { 380 } else {
276 slot++; 381 slot++;
277 path.slots[0]++; 382 path.slots[0]++;
@@ -441,8 +546,6 @@ static int btrfs_add_nondir(struct btrfs_trans_handle *trans,
441 d_instantiate(dentry, inode); 546 d_instantiate(dentry, inode);
442 return 0; 547 return 0;
443 } 548 }
444 inode_dec_link_count(inode);
445 iput(inode);
446 return err; 549 return err;
447} 550}
448 551
@@ -453,6 +556,7 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
453 struct btrfs_root *root = btrfs_sb(dir->i_sb); 556 struct btrfs_root *root = btrfs_sb(dir->i_sb);
454 struct inode *inode; 557 struct inode *inode;
455 int err; 558 int err;
559 int drop_inode = 0;
456 560
457 mutex_lock(&root->fs_info->fs_mutex); 561 mutex_lock(&root->fs_info->fs_mutex);
458 trans = btrfs_start_transaction(root, 1); 562 trans = btrfs_start_transaction(root, 1);
@@ -462,10 +566,16 @@ static int btrfs_create(struct inode *dir, struct dentry *dentry,
462 goto out_unlock; 566 goto out_unlock;
463 // FIXME mark the inode dirty 567 // FIXME mark the inode dirty
464 err = btrfs_add_nondir(trans, dentry, inode); 568 err = btrfs_add_nondir(trans, dentry, inode);
569 if (err)
570 drop_inode = 1;
465 dir->i_sb->s_dirt = 1; 571 dir->i_sb->s_dirt = 1;
466 btrfs_end_transaction(trans, root); 572 btrfs_end_transaction(trans, root);
467out_unlock: 573out_unlock:
468 mutex_unlock(&root->fs_info->fs_mutex); 574 mutex_unlock(&root->fs_info->fs_mutex);
575 if (drop_inode) {
576 inode_dec_link_count(inode);
577 iput(inode);
578 }
469 return err; 579 return err;
470} 580}
471 581
@@ -516,7 +626,7 @@ static struct file_system_type btrfs_fs_type = {
516 626
517static struct super_operations btrfs_super_ops = { 627static struct super_operations btrfs_super_ops = {
518 .statfs = simple_statfs, 628 .statfs = simple_statfs,
519 .drop_inode = generic_delete_inode, 629 .delete_inode = btrfs_delete_inode,
520 .put_super = btrfs_put_super, 630 .put_super = btrfs_put_super,
521 .read_inode = btrfs_read_locked_inode, 631 .read_inode = btrfs_read_locked_inode,
522 .write_super = btrfs_write_super, 632 .write_super = btrfs_write_super,
@@ -526,6 +636,7 @@ static struct super_operations btrfs_super_ops = {
526static struct inode_operations btrfs_dir_inode_operations = { 636static struct inode_operations btrfs_dir_inode_operations = {
527 .lookup = btrfs_lookup, 637 .lookup = btrfs_lookup,
528 .create = btrfs_create, 638 .create = btrfs_create,
639 .unlink = btrfs_unlink,
529}; 640};
530 641
531static struct file_operations btrfs_dir_file_operations = { 642static struct file_operations btrfs_dir_file_operations = {