aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/super.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-05-23 15:44:28 -0400
committerDavid Woodhouse <dwmw2@hera.kernel.org>2007-05-23 15:44:28 -0400
commite06afa839e726959be2166bec4cb85c117e213f1 (patch)
treef2acae733ce4c4368e3368cf912b1c76462aa0f7 /fs/btrfs/super.c
parentf9f3c6b666f717510b67036c314ec915b9059eaa (diff)
Btrfs: rename
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/super.c')
-rw-r--r--fs/btrfs/super.c132
1 files changed, 120 insertions, 12 deletions
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c
index 0220c82841ad..f49cad603ee8 100644
--- a/fs/btrfs/super.c
+++ b/fs/btrfs/super.c
@@ -375,6 +375,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
375 struct btrfs_path *path; 375 struct btrfs_path *path;
376 struct btrfs_key key; 376 struct btrfs_key key;
377 struct btrfs_disk_key *found_key; 377 struct btrfs_disk_key *found_key;
378 u32 found_type;
378 struct btrfs_leaf *leaf; 379 struct btrfs_leaf *leaf;
379 struct btrfs_file_extent_item *fi = NULL; 380 struct btrfs_file_extent_item *fi = NULL;
380 u64 extent_start = 0; 381 u64 extent_start = 0;
@@ -386,12 +387,7 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
386 /* FIXME, add redo link to tree so we don't leak on crash */ 387 /* FIXME, add redo link to tree so we don't leak on crash */
387 key.objectid = inode->i_ino; 388 key.objectid = inode->i_ino;
388 key.offset = (u64)-1; 389 key.offset = (u64)-1;
389 key.flags = 0; 390 key.flags = (u32)-1;
390 /*
391 * use BTRFS_CSUM_ITEM_KEY because it is larger than inline keys
392 * or extent data
393 */
394 btrfs_set_key_type(&key, BTRFS_CSUM_ITEM_KEY);
395 while(1) { 391 while(1) {
396 btrfs_init_path(path); 392 btrfs_init_path(path);
397 ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 393 ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
@@ -405,10 +401,13 @@ static int btrfs_truncate_in_trans(struct btrfs_trans_handle *trans,
405 reada_truncate(root, path, inode->i_ino); 401 reada_truncate(root, path, inode->i_ino);
406 leaf = btrfs_buffer_leaf(path->nodes[0]); 402 leaf = btrfs_buffer_leaf(path->nodes[0]);
407 found_key = &leaf->items[path->slots[0]].key; 403 found_key = &leaf->items[path->slots[0]].key;
404 found_type = btrfs_disk_key_type(found_key);
408 if (btrfs_disk_key_objectid(found_key) != inode->i_ino) 405 if (btrfs_disk_key_objectid(found_key) != inode->i_ino)
409 break; 406 break;
410 if (btrfs_disk_key_type(found_key) != BTRFS_CSUM_ITEM_KEY && 407 if (found_type != BTRFS_CSUM_ITEM_KEY &&
411 btrfs_disk_key_type(found_key) != BTRFS_EXTENT_DATA_KEY) 408 found_type != BTRFS_DIR_ITEM_KEY &&
409 found_type != BTRFS_DIR_INDEX_KEY &&
410 found_type != BTRFS_EXTENT_DATA_KEY)
412 break; 411 break;
413 if (btrfs_disk_key_offset(found_key) < inode->i_size) 412 if (btrfs_disk_key_offset(found_key) < inode->i_size)
414 break; 413 break;
@@ -460,10 +459,8 @@ static void btrfs_delete_inode(struct inode *inode)
460 mutex_lock(&root->fs_info->fs_mutex); 459 mutex_lock(&root->fs_info->fs_mutex);
461 trans = btrfs_start_transaction(root, 1); 460 trans = btrfs_start_transaction(root, 1);
462 btrfs_set_trans_block_group(trans, inode); 461 btrfs_set_trans_block_group(trans, inode);
463 if (S_ISREG(inode->i_mode)) { 462 ret = btrfs_truncate_in_trans(trans, root, inode);
464 ret = btrfs_truncate_in_trans(trans, root, inode); 463 BUG_ON(ret);
465 BUG_ON(ret);
466 }
467 btrfs_free_inode(trans, root, inode); 464 btrfs_free_inode(trans, root, inode);
468 btrfs_end_transaction(trans, root); 465 btrfs_end_transaction(trans, root);
469 mutex_unlock(&root->fs_info->fs_mutex); 466 mutex_unlock(&root->fs_info->fs_mutex);
@@ -2504,6 +2501,116 @@ static int btrfs_statfs(struct dentry *dentry, struct kstatfs *buf)
2504 return 0; 2501 return 0;
2505} 2502}
2506 2503
2504static int btrfs_rename(struct inode * old_dir, struct dentry *old_dentry,
2505 struct inode * new_dir,struct dentry *new_dentry)
2506{
2507 struct btrfs_trans_handle *trans;
2508 struct btrfs_root *root = BTRFS_I(old_dir)->root;
2509 struct inode *new_inode = new_dentry->d_inode;
2510 struct inode *old_inode = old_dentry->d_inode;
2511 struct timespec ctime = CURRENT_TIME;
2512 struct btrfs_path *path;
2513 struct btrfs_dir_item *di;
2514 int ret;
2515
2516 if (S_ISDIR(old_inode->i_mode) && new_inode &&
2517 new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) {
2518 return -ENOTEMPTY;
2519 }
2520 mutex_lock(&root->fs_info->fs_mutex);
2521 trans = btrfs_start_transaction(root, 1);
2522 btrfs_set_trans_block_group(trans, new_dir);
2523 path = btrfs_alloc_path();
2524 if (!path) {
2525 ret = -ENOMEM;
2526 goto out_fail;
2527 }
2528
2529 old_dentry->d_inode->i_nlink++;
2530 old_dir->i_ctime = old_dir->i_mtime = ctime;
2531 new_dir->i_ctime = new_dir->i_mtime = ctime;
2532 old_inode->i_ctime = ctime;
2533 if (S_ISDIR(old_inode->i_mode) && old_dir != new_dir) {
2534 struct btrfs_key *location = &BTRFS_I(new_dir)->location;
2535 u64 old_parent_oid;
2536 di = btrfs_lookup_dir_item(trans, root, path, old_inode->i_ino,
2537 "..", 2, -1);
2538 if (IS_ERR(di)) {
2539 ret = PTR_ERR(di);
2540 goto out_fail;
2541 }
2542 if (!di) {
2543 ret = -ENOENT;
2544 goto out_fail;
2545 }
2546 old_parent_oid = btrfs_disk_key_objectid(&di->location);
2547 ret = btrfs_del_item(trans, root, path);
2548 if (ret) {
2549 ret = -EIO;
2550 goto out_fail;
2551 }
2552 btrfs_release_path(root, path);
2553
2554 di = btrfs_lookup_dir_index_item(trans, root, path,
2555 old_inode->i_ino,
2556 old_parent_oid,
2557 "..", 2, -1);
2558 if (IS_ERR(di)) {
2559 ret = PTR_ERR(di);
2560 goto out_fail;
2561 }
2562 if (!di) {
2563 ret = -ENOENT;
2564 goto out_fail;
2565 }
2566 ret = btrfs_del_item(trans, root, path);
2567 if (ret) {
2568 ret = -EIO;
2569 goto out_fail;
2570 }
2571 btrfs_release_path(root, path);
2572
2573 ret = btrfs_insert_dir_item(trans, root, "..", 2,
2574 old_inode->i_ino, location, 0);
2575 if (ret)
2576 goto out_fail;
2577 }
2578
2579
2580 ret = btrfs_add_link(trans, new_dentry, old_inode);
2581 if (ret == -EEXIST && new_inode)
2582 ret = 0;
2583 else if (ret)
2584 goto out_fail;
2585
2586 ret = btrfs_unlink_trans(trans, root, old_dir, old_dentry);
2587 if (ret)
2588 goto out_fail;
2589
2590 if (new_inode) {
2591 new_inode->i_ctime = CURRENT_TIME;
2592 di = btrfs_lookup_dir_index_item(trans, root, path,
2593 new_dir->i_ino,
2594 new_inode->i_ino,
2595 new_dentry->d_name.name,
2596 new_dentry->d_name.len, -1);
2597 if (di && !IS_ERR(di)) {
2598 btrfs_del_item(trans, root, path);
2599 btrfs_release_path(root, path);
2600 }
2601 if (S_ISDIR(new_inode->i_mode))
2602 clear_nlink(new_inode);
2603 else
2604 drop_nlink(new_inode);
2605 btrfs_update_inode(trans, root, new_inode);
2606 }
2607out_fail:
2608 btrfs_free_path(path);
2609 btrfs_end_transaction(trans, root);
2610 mutex_unlock(&root->fs_info->fs_mutex);
2611 return ret;
2612}
2613
2507static struct file_system_type btrfs_fs_type = { 2614static struct file_system_type btrfs_fs_type = {
2508 .owner = THIS_MODULE, 2615 .owner = THIS_MODULE,
2509 .name = "btrfs", 2616 .name = "btrfs",
@@ -2531,6 +2638,7 @@ static struct inode_operations btrfs_dir_inode_operations = {
2531 .unlink = btrfs_unlink, 2638 .unlink = btrfs_unlink,
2532 .mkdir = btrfs_mkdir, 2639 .mkdir = btrfs_mkdir,
2533 .rmdir = btrfs_rmdir, 2640 .rmdir = btrfs_rmdir,
2641 .rename = btrfs_rename,
2534}; 2642};
2535 2643
2536static struct inode_operations btrfs_dir_ro_inode_operations = { 2644static struct inode_operations btrfs_dir_ro_inode_operations = {