diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-05-23 15:44:28 -0400 |
---|---|---|
committer | David Woodhouse <dwmw2@hera.kernel.org> | 2007-05-23 15:44:28 -0400 |
commit | e06afa839e726959be2166bec4cb85c117e213f1 (patch) | |
tree | f2acae733ce4c4368e3368cf912b1c76462aa0f7 /fs/btrfs/super.c | |
parent | f9f3c6b666f717510b67036c314ec915b9059eaa (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.c | 132 |
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 | ||
2504 | static 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 | } | ||
2607 | out_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 | |||
2507 | static struct file_system_type btrfs_fs_type = { | 2614 | static 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 | ||
2536 | static struct inode_operations btrfs_dir_ro_inode_operations = { | 2644 | static struct inode_operations btrfs_dir_ro_inode_operations = { |