diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:57:29 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-09-24 11:57:29 -0400 |
commit | dc2af6a6bcf3abdf44ac545759a6547dfe12070e (patch) | |
tree | 068ea2c5f5df55f72167ab3b51e001a98b7300e4 /fs/btrfs/inode.c | |
parent | 6c5daf012c9155aafd2c7973e4278766c30dfad0 (diff) | |
parent | 54bcf382daf08c1396edb8b81e650b58930ccaef (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (42 commits)
Btrfs: hash the btree inode during fill_super
Btrfs: relocate file extents in clusters
Btrfs: don't rename file into dummy directory
Btrfs: check size of inode backref before adding hardlink
Btrfs: fix releasepage to avoid unlocking extents we haven't locked
Btrfs: Fix test_range_bit for whole file extents
Btrfs: fix errors handling cached state in set/clear_extent_bit
Btrfs: fix early enospc during balancing
Btrfs: deal with NULL space info
Btrfs: account for space used by the super mirrors
Btrfs: fix extent entry threshold calculation
Btrfs: remove dead code
Btrfs: fix bitmap size tracking
Btrfs: don't keep retrying a block group if we fail to allocate a cluster
Btrfs: make balance code choose more wisely when relocating
Btrfs: fix arithmetic error in clone ioctl
Btrfs: add snapshot/subvolume destroy ioctl
Btrfs: change how subvolumes are organized
Btrfs: do not reuse objectid of deleted snapshot/subvol
Btrfs: speed up snapshot dropping
...
Diffstat (limited to 'fs/btrfs/inode.c')
-rw-r--r-- | fs/btrfs/inode.c | 663 |
1 files changed, 494 insertions, 169 deletions
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d154a3f365d5..e9b76bcd1c12 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -231,7 +231,8 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, | |||
231 | } | 231 | } |
232 | 232 | ||
233 | ret = btrfs_drop_extents(trans, root, inode, start, | 233 | ret = btrfs_drop_extents(trans, root, inode, start, |
234 | aligned_end, aligned_end, start, &hint_byte); | 234 | aligned_end, aligned_end, start, |
235 | &hint_byte, 1); | ||
235 | BUG_ON(ret); | 236 | BUG_ON(ret); |
236 | 237 | ||
237 | if (isize > actual_end) | 238 | if (isize > actual_end) |
@@ -240,7 +241,7 @@ static noinline int cow_file_range_inline(struct btrfs_trans_handle *trans, | |||
240 | inline_len, compressed_size, | 241 | inline_len, compressed_size, |
241 | compressed_pages); | 242 | compressed_pages); |
242 | BUG_ON(ret); | 243 | BUG_ON(ret); |
243 | btrfs_drop_extent_cache(inode, start, aligned_end, 0); | 244 | btrfs_drop_extent_cache(inode, start, aligned_end - 1, 0); |
244 | return 0; | 245 | return 0; |
245 | } | 246 | } |
246 | 247 | ||
@@ -425,7 +426,7 @@ again: | |||
425 | extent_clear_unlock_delalloc(inode, | 426 | extent_clear_unlock_delalloc(inode, |
426 | &BTRFS_I(inode)->io_tree, | 427 | &BTRFS_I(inode)->io_tree, |
427 | start, end, NULL, 1, 0, | 428 | start, end, NULL, 1, 0, |
428 | 0, 1, 1, 1); | 429 | 0, 1, 1, 1, 0); |
429 | ret = 0; | 430 | ret = 0; |
430 | goto free_pages_out; | 431 | goto free_pages_out; |
431 | } | 432 | } |
@@ -611,9 +612,9 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
611 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); | 612 | set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); |
612 | 613 | ||
613 | while (1) { | 614 | while (1) { |
614 | spin_lock(&em_tree->lock); | 615 | write_lock(&em_tree->lock); |
615 | ret = add_extent_mapping(em_tree, em); | 616 | ret = add_extent_mapping(em_tree, em); |
616 | spin_unlock(&em_tree->lock); | 617 | write_unlock(&em_tree->lock); |
617 | if (ret != -EEXIST) { | 618 | if (ret != -EEXIST) { |
618 | free_extent_map(em); | 619 | free_extent_map(em); |
619 | break; | 620 | break; |
@@ -640,7 +641,7 @@ static noinline int submit_compressed_extents(struct inode *inode, | |||
640 | async_extent->start, | 641 | async_extent->start, |
641 | async_extent->start + | 642 | async_extent->start + |
642 | async_extent->ram_size - 1, | 643 | async_extent->ram_size - 1, |
643 | NULL, 1, 1, 0, 1, 1, 0); | 644 | NULL, 1, 1, 0, 1, 1, 0, 0); |
644 | 645 | ||
645 | ret = btrfs_submit_compressed_write(inode, | 646 | ret = btrfs_submit_compressed_write(inode, |
646 | async_extent->start, | 647 | async_extent->start, |
@@ -713,7 +714,7 @@ static noinline int cow_file_range(struct inode *inode, | |||
713 | extent_clear_unlock_delalloc(inode, | 714 | extent_clear_unlock_delalloc(inode, |
714 | &BTRFS_I(inode)->io_tree, | 715 | &BTRFS_I(inode)->io_tree, |
715 | start, end, NULL, 1, 1, | 716 | start, end, NULL, 1, 1, |
716 | 1, 1, 1, 1); | 717 | 1, 1, 1, 1, 0); |
717 | *nr_written = *nr_written + | 718 | *nr_written = *nr_written + |
718 | (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; | 719 | (end - start + PAGE_CACHE_SIZE) / PAGE_CACHE_SIZE; |
719 | *page_started = 1; | 720 | *page_started = 1; |
@@ -725,6 +726,15 @@ static noinline int cow_file_range(struct inode *inode, | |||
725 | BUG_ON(disk_num_bytes > | 726 | BUG_ON(disk_num_bytes > |
726 | btrfs_super_total_bytes(&root->fs_info->super_copy)); | 727 | btrfs_super_total_bytes(&root->fs_info->super_copy)); |
727 | 728 | ||
729 | |||
730 | read_lock(&BTRFS_I(inode)->extent_tree.lock); | ||
731 | em = search_extent_mapping(&BTRFS_I(inode)->extent_tree, | ||
732 | start, num_bytes); | ||
733 | if (em) { | ||
734 | alloc_hint = em->block_start; | ||
735 | free_extent_map(em); | ||
736 | } | ||
737 | read_unlock(&BTRFS_I(inode)->extent_tree.lock); | ||
728 | btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); | 738 | btrfs_drop_extent_cache(inode, start, start + num_bytes - 1, 0); |
729 | 739 | ||
730 | while (disk_num_bytes > 0) { | 740 | while (disk_num_bytes > 0) { |
@@ -737,7 +747,6 @@ static noinline int cow_file_range(struct inode *inode, | |||
737 | em = alloc_extent_map(GFP_NOFS); | 747 | em = alloc_extent_map(GFP_NOFS); |
738 | em->start = start; | 748 | em->start = start; |
739 | em->orig_start = em->start; | 749 | em->orig_start = em->start; |
740 | |||
741 | ram_size = ins.offset; | 750 | ram_size = ins.offset; |
742 | em->len = ins.offset; | 751 | em->len = ins.offset; |
743 | 752 | ||
@@ -747,9 +756,9 @@ static noinline int cow_file_range(struct inode *inode, | |||
747 | set_bit(EXTENT_FLAG_PINNED, &em->flags); | 756 | set_bit(EXTENT_FLAG_PINNED, &em->flags); |
748 | 757 | ||
749 | while (1) { | 758 | while (1) { |
750 | spin_lock(&em_tree->lock); | 759 | write_lock(&em_tree->lock); |
751 | ret = add_extent_mapping(em_tree, em); | 760 | ret = add_extent_mapping(em_tree, em); |
752 | spin_unlock(&em_tree->lock); | 761 | write_unlock(&em_tree->lock); |
753 | if (ret != -EEXIST) { | 762 | if (ret != -EEXIST) { |
754 | free_extent_map(em); | 763 | free_extent_map(em); |
755 | break; | 764 | break; |
@@ -776,11 +785,14 @@ static noinline int cow_file_range(struct inode *inode, | |||
776 | /* we're not doing compressed IO, don't unlock the first | 785 | /* we're not doing compressed IO, don't unlock the first |
777 | * page (which the caller expects to stay locked), don't | 786 | * page (which the caller expects to stay locked), don't |
778 | * clear any dirty bits and don't set any writeback bits | 787 | * clear any dirty bits and don't set any writeback bits |
788 | * | ||
789 | * Do set the Private2 bit so we know this page was properly | ||
790 | * setup for writepage | ||
779 | */ | 791 | */ |
780 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, | 792 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, |
781 | start, start + ram_size - 1, | 793 | start, start + ram_size - 1, |
782 | locked_page, unlock, 1, | 794 | locked_page, unlock, 1, |
783 | 1, 0, 0, 0); | 795 | 1, 0, 0, 0, 1); |
784 | disk_num_bytes -= cur_alloc_size; | 796 | disk_num_bytes -= cur_alloc_size; |
785 | num_bytes -= cur_alloc_size; | 797 | num_bytes -= cur_alloc_size; |
786 | alloc_hint = ins.objectid + ins.offset; | 798 | alloc_hint = ins.objectid + ins.offset; |
@@ -853,7 +865,7 @@ static int cow_file_range_async(struct inode *inode, struct page *locked_page, | |||
853 | int limit = 10 * 1024 * 1042; | 865 | int limit = 10 * 1024 * 1042; |
854 | 866 | ||
855 | clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED | | 867 | clear_extent_bit(&BTRFS_I(inode)->io_tree, start, end, EXTENT_LOCKED | |
856 | EXTENT_DELALLOC, 1, 0, GFP_NOFS); | 868 | EXTENT_DELALLOC, 1, 0, NULL, GFP_NOFS); |
857 | while (start < end) { | 869 | while (start < end) { |
858 | async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); | 870 | async_cow = kmalloc(sizeof(*async_cow), GFP_NOFS); |
859 | async_cow->inode = inode; | 871 | async_cow->inode = inode; |
@@ -1080,9 +1092,9 @@ out_check: | |||
1080 | em->bdev = root->fs_info->fs_devices->latest_bdev; | 1092 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
1081 | set_bit(EXTENT_FLAG_PINNED, &em->flags); | 1093 | set_bit(EXTENT_FLAG_PINNED, &em->flags); |
1082 | while (1) { | 1094 | while (1) { |
1083 | spin_lock(&em_tree->lock); | 1095 | write_lock(&em_tree->lock); |
1084 | ret = add_extent_mapping(em_tree, em); | 1096 | ret = add_extent_mapping(em_tree, em); |
1085 | spin_unlock(&em_tree->lock); | 1097 | write_unlock(&em_tree->lock); |
1086 | if (ret != -EEXIST) { | 1098 | if (ret != -EEXIST) { |
1087 | free_extent_map(em); | 1099 | free_extent_map(em); |
1088 | break; | 1100 | break; |
@@ -1101,7 +1113,7 @@ out_check: | |||
1101 | 1113 | ||
1102 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, | 1114 | extent_clear_unlock_delalloc(inode, &BTRFS_I(inode)->io_tree, |
1103 | cur_offset, cur_offset + num_bytes - 1, | 1115 | cur_offset, cur_offset + num_bytes - 1, |
1104 | locked_page, 1, 1, 1, 0, 0, 0); | 1116 | locked_page, 1, 1, 1, 0, 0, 0, 1); |
1105 | cur_offset = extent_end; | 1117 | cur_offset = extent_end; |
1106 | if (cur_offset > end) | 1118 | if (cur_offset > end) |
1107 | break; | 1119 | break; |
@@ -1374,10 +1386,8 @@ again: | |||
1374 | lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); | 1386 | lock_extent(&BTRFS_I(inode)->io_tree, page_start, page_end, GFP_NOFS); |
1375 | 1387 | ||
1376 | /* already ordered? We're done */ | 1388 | /* already ordered? We're done */ |
1377 | if (test_range_bit(&BTRFS_I(inode)->io_tree, page_start, page_end, | 1389 | if (PagePrivate2(page)) |
1378 | EXTENT_ORDERED, 0)) { | ||
1379 | goto out; | 1390 | goto out; |
1380 | } | ||
1381 | 1391 | ||
1382 | ordered = btrfs_lookup_ordered_extent(inode, page_start); | 1392 | ordered = btrfs_lookup_ordered_extent(inode, page_start); |
1383 | if (ordered) { | 1393 | if (ordered) { |
@@ -1413,11 +1423,9 @@ static int btrfs_writepage_start_hook(struct page *page, u64 start, u64 end) | |||
1413 | struct inode *inode = page->mapping->host; | 1423 | struct inode *inode = page->mapping->host; |
1414 | struct btrfs_writepage_fixup *fixup; | 1424 | struct btrfs_writepage_fixup *fixup; |
1415 | struct btrfs_root *root = BTRFS_I(inode)->root; | 1425 | struct btrfs_root *root = BTRFS_I(inode)->root; |
1416 | int ret; | ||
1417 | 1426 | ||
1418 | ret = test_range_bit(&BTRFS_I(inode)->io_tree, start, end, | 1427 | /* this page is properly in the ordered list */ |
1419 | EXTENT_ORDERED, 0); | 1428 | if (TestClearPagePrivate2(page)) |
1420 | if (ret) | ||
1421 | return 0; | 1429 | return 0; |
1422 | 1430 | ||
1423 | if (PageChecked(page)) | 1431 | if (PageChecked(page)) |
@@ -1455,9 +1463,19 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
1455 | BUG_ON(!path); | 1463 | BUG_ON(!path); |
1456 | 1464 | ||
1457 | path->leave_spinning = 1; | 1465 | path->leave_spinning = 1; |
1466 | |||
1467 | /* | ||
1468 | * we may be replacing one extent in the tree with another. | ||
1469 | * The new extent is pinned in the extent map, and we don't want | ||
1470 | * to drop it from the cache until it is completely in the btree. | ||
1471 | * | ||
1472 | * So, tell btrfs_drop_extents to leave this extent in the cache. | ||
1473 | * the caller is expected to unpin it and allow it to be merged | ||
1474 | * with the others. | ||
1475 | */ | ||
1458 | ret = btrfs_drop_extents(trans, root, inode, file_pos, | 1476 | ret = btrfs_drop_extents(trans, root, inode, file_pos, |
1459 | file_pos + num_bytes, locked_end, | 1477 | file_pos + num_bytes, locked_end, |
1460 | file_pos, &hint); | 1478 | file_pos, &hint, 0); |
1461 | BUG_ON(ret); | 1479 | BUG_ON(ret); |
1462 | 1480 | ||
1463 | ins.objectid = inode->i_ino; | 1481 | ins.objectid = inode->i_ino; |
@@ -1485,7 +1503,6 @@ static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
1485 | btrfs_mark_buffer_dirty(leaf); | 1503 | btrfs_mark_buffer_dirty(leaf); |
1486 | 1504 | ||
1487 | inode_add_bytes(inode, num_bytes); | 1505 | inode_add_bytes(inode, num_bytes); |
1488 | btrfs_drop_extent_cache(inode, file_pos, file_pos + num_bytes - 1, 0); | ||
1489 | 1506 | ||
1490 | ins.objectid = disk_bytenr; | 1507 | ins.objectid = disk_bytenr; |
1491 | ins.offset = disk_num_bytes; | 1508 | ins.offset = disk_num_bytes; |
@@ -1596,6 +1613,9 @@ static int btrfs_finish_ordered_io(struct inode *inode, u64 start, u64 end) | |||
1596 | ordered_extent->len, | 1613 | ordered_extent->len, |
1597 | compressed, 0, 0, | 1614 | compressed, 0, 0, |
1598 | BTRFS_FILE_EXTENT_REG); | 1615 | BTRFS_FILE_EXTENT_REG); |
1616 | unpin_extent_cache(&BTRFS_I(inode)->extent_tree, | ||
1617 | ordered_extent->file_offset, | ||
1618 | ordered_extent->len); | ||
1599 | BUG_ON(ret); | 1619 | BUG_ON(ret); |
1600 | } | 1620 | } |
1601 | unlock_extent(io_tree, ordered_extent->file_offset, | 1621 | unlock_extent(io_tree, ordered_extent->file_offset, |
@@ -1623,6 +1643,7 @@ nocow: | |||
1623 | static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, | 1643 | static int btrfs_writepage_end_io_hook(struct page *page, u64 start, u64 end, |
1624 | struct extent_state *state, int uptodate) | 1644 | struct extent_state *state, int uptodate) |
1625 | { | 1645 | { |
1646 | ClearPagePrivate2(page); | ||
1626 | return btrfs_finish_ordered_io(page->mapping->host, start, end); | 1647 | return btrfs_finish_ordered_io(page->mapping->host, start, end); |
1627 | } | 1648 | } |
1628 | 1649 | ||
@@ -1669,13 +1690,13 @@ static int btrfs_io_failed_hook(struct bio *failed_bio, | |||
1669 | failrec->last_mirror = 0; | 1690 | failrec->last_mirror = 0; |
1670 | failrec->bio_flags = 0; | 1691 | failrec->bio_flags = 0; |
1671 | 1692 | ||
1672 | spin_lock(&em_tree->lock); | 1693 | read_lock(&em_tree->lock); |
1673 | em = lookup_extent_mapping(em_tree, start, failrec->len); | 1694 | em = lookup_extent_mapping(em_tree, start, failrec->len); |
1674 | if (em->start > start || em->start + em->len < start) { | 1695 | if (em->start > start || em->start + em->len < start) { |
1675 | free_extent_map(em); | 1696 | free_extent_map(em); |
1676 | em = NULL; | 1697 | em = NULL; |
1677 | } | 1698 | } |
1678 | spin_unlock(&em_tree->lock); | 1699 | read_unlock(&em_tree->lock); |
1679 | 1700 | ||
1680 | if (!em || IS_ERR(em)) { | 1701 | if (!em || IS_ERR(em)) { |
1681 | kfree(failrec); | 1702 | kfree(failrec); |
@@ -1794,7 +1815,7 @@ static int btrfs_readpage_end_io_hook(struct page *page, u64 start, u64 end, | |||
1794 | return 0; | 1815 | return 0; |
1795 | 1816 | ||
1796 | if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID && | 1817 | if (root->root_key.objectid == BTRFS_DATA_RELOC_TREE_OBJECTID && |
1797 | test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1)) { | 1818 | test_range_bit(io_tree, start, end, EXTENT_NODATASUM, 1, NULL)) { |
1798 | clear_extent_bits(io_tree, start, end, EXTENT_NODATASUM, | 1819 | clear_extent_bits(io_tree, start, end, EXTENT_NODATASUM, |
1799 | GFP_NOFS); | 1820 | GFP_NOFS); |
1800 | return 0; | 1821 | return 0; |
@@ -2352,6 +2373,69 @@ static int btrfs_unlink(struct inode *dir, struct dentry *dentry) | |||
2352 | return ret; | 2373 | return ret; |
2353 | } | 2374 | } |
2354 | 2375 | ||
2376 | int btrfs_unlink_subvol(struct btrfs_trans_handle *trans, | ||
2377 | struct btrfs_root *root, | ||
2378 | struct inode *dir, u64 objectid, | ||
2379 | const char *name, int name_len) | ||
2380 | { | ||
2381 | struct btrfs_path *path; | ||
2382 | struct extent_buffer *leaf; | ||
2383 | struct btrfs_dir_item *di; | ||
2384 | struct btrfs_key key; | ||
2385 | u64 index; | ||
2386 | int ret; | ||
2387 | |||
2388 | path = btrfs_alloc_path(); | ||
2389 | if (!path) | ||
2390 | return -ENOMEM; | ||
2391 | |||
2392 | di = btrfs_lookup_dir_item(trans, root, path, dir->i_ino, | ||
2393 | name, name_len, -1); | ||
2394 | BUG_ON(!di || IS_ERR(di)); | ||
2395 | |||
2396 | leaf = path->nodes[0]; | ||
2397 | btrfs_dir_item_key_to_cpu(leaf, di, &key); | ||
2398 | WARN_ON(key.type != BTRFS_ROOT_ITEM_KEY || key.objectid != objectid); | ||
2399 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | ||
2400 | BUG_ON(ret); | ||
2401 | btrfs_release_path(root, path); | ||
2402 | |||
2403 | ret = btrfs_del_root_ref(trans, root->fs_info->tree_root, | ||
2404 | objectid, root->root_key.objectid, | ||
2405 | dir->i_ino, &index, name, name_len); | ||
2406 | if (ret < 0) { | ||
2407 | BUG_ON(ret != -ENOENT); | ||
2408 | di = btrfs_search_dir_index_item(root, path, dir->i_ino, | ||
2409 | name, name_len); | ||
2410 | BUG_ON(!di || IS_ERR(di)); | ||
2411 | |||
2412 | leaf = path->nodes[0]; | ||
2413 | btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); | ||
2414 | btrfs_release_path(root, path); | ||
2415 | index = key.offset; | ||
2416 | } | ||
2417 | |||
2418 | di = btrfs_lookup_dir_index_item(trans, root, path, dir->i_ino, | ||
2419 | index, name, name_len, -1); | ||
2420 | BUG_ON(!di || IS_ERR(di)); | ||
2421 | |||
2422 | leaf = path->nodes[0]; | ||
2423 | btrfs_dir_item_key_to_cpu(leaf, di, &key); | ||
2424 | WARN_ON(key.type != BTRFS_ROOT_ITEM_KEY || key.objectid != objectid); | ||
2425 | ret = btrfs_delete_one_dir_name(trans, root, path, di); | ||
2426 | BUG_ON(ret); | ||
2427 | btrfs_release_path(root, path); | ||
2428 | |||
2429 | btrfs_i_size_write(dir, dir->i_size - name_len * 2); | ||
2430 | dir->i_mtime = dir->i_ctime = CURRENT_TIME; | ||
2431 | ret = btrfs_update_inode(trans, root, dir); | ||
2432 | BUG_ON(ret); | ||
2433 | dir->i_sb->s_dirt = 1; | ||
2434 | |||
2435 | btrfs_free_path(path); | ||
2436 | return 0; | ||
2437 | } | ||
2438 | |||
2355 | static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | 2439 | static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) |
2356 | { | 2440 | { |
2357 | struct inode *inode = dentry->d_inode; | 2441 | struct inode *inode = dentry->d_inode; |
@@ -2361,29 +2445,31 @@ static int btrfs_rmdir(struct inode *dir, struct dentry *dentry) | |||
2361 | struct btrfs_trans_handle *trans; | 2445 | struct btrfs_trans_handle *trans; |
2362 | unsigned long nr = 0; | 2446 | unsigned long nr = 0; |
2363 | 2447 | ||
2364 | /* | ||
2365 | * the FIRST_FREE_OBJECTID check makes sure we don't try to rmdir | ||
2366 | * the root of a subvolume or snapshot | ||
2367 | */ | ||
2368 | if (inode->i_size > BTRFS_EMPTY_DIR_SIZE || | 2448 | if (inode->i_size > BTRFS_EMPTY_DIR_SIZE || |
2369 | inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) { | 2449 | inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) |
2370 | return -ENOTEMPTY; | 2450 | return -ENOTEMPTY; |
2371 | } | ||
2372 | 2451 | ||
2373 | trans = btrfs_start_transaction(root, 1); | 2452 | trans = btrfs_start_transaction(root, 1); |
2374 | btrfs_set_trans_block_group(trans, dir); | 2453 | btrfs_set_trans_block_group(trans, dir); |
2375 | 2454 | ||
2455 | if (unlikely(inode->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { | ||
2456 | err = btrfs_unlink_subvol(trans, root, dir, | ||
2457 | BTRFS_I(inode)->location.objectid, | ||
2458 | dentry->d_name.name, | ||
2459 | dentry->d_name.len); | ||
2460 | goto out; | ||
2461 | } | ||
2462 | |||
2376 | err = btrfs_orphan_add(trans, inode); | 2463 | err = btrfs_orphan_add(trans, inode); |
2377 | if (err) | 2464 | if (err) |
2378 | goto fail_trans; | 2465 | goto out; |
2379 | 2466 | ||
2380 | /* now the directory is empty */ | 2467 | /* now the directory is empty */ |
2381 | err = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, | 2468 | err = btrfs_unlink_inode(trans, root, dir, dentry->d_inode, |
2382 | dentry->d_name.name, dentry->d_name.len); | 2469 | dentry->d_name.name, dentry->d_name.len); |
2383 | if (!err) | 2470 | if (!err) |
2384 | btrfs_i_size_write(inode, 0); | 2471 | btrfs_i_size_write(inode, 0); |
2385 | 2472 | out: | |
2386 | fail_trans: | ||
2387 | nr = trans->blocks_used; | 2473 | nr = trans->blocks_used; |
2388 | ret = btrfs_end_transaction_throttle(trans, root); | 2474 | ret = btrfs_end_transaction_throttle(trans, root); |
2389 | btrfs_btree_balance_dirty(root, nr); | 2475 | btrfs_btree_balance_dirty(root, nr); |
@@ -2935,7 +3021,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t size) | |||
2935 | cur_offset, | 3021 | cur_offset, |
2936 | cur_offset + hole_size, | 3022 | cur_offset + hole_size, |
2937 | block_end, | 3023 | block_end, |
2938 | cur_offset, &hint_byte); | 3024 | cur_offset, &hint_byte, 1); |
2939 | if (err) | 3025 | if (err) |
2940 | break; | 3026 | break; |
2941 | err = btrfs_insert_file_extent(trans, root, | 3027 | err = btrfs_insert_file_extent(trans, root, |
@@ -3003,6 +3089,11 @@ void btrfs_delete_inode(struct inode *inode) | |||
3003 | } | 3089 | } |
3004 | btrfs_wait_ordered_range(inode, 0, (u64)-1); | 3090 | btrfs_wait_ordered_range(inode, 0, (u64)-1); |
3005 | 3091 | ||
3092 | if (inode->i_nlink > 0) { | ||
3093 | BUG_ON(btrfs_root_refs(&root->root_item) != 0); | ||
3094 | goto no_delete; | ||
3095 | } | ||
3096 | |||
3006 | btrfs_i_size_write(inode, 0); | 3097 | btrfs_i_size_write(inode, 0); |
3007 | trans = btrfs_join_transaction(root, 1); | 3098 | trans = btrfs_join_transaction(root, 1); |
3008 | 3099 | ||
@@ -3070,29 +3161,67 @@ out_err: | |||
3070 | * is kind of like crossing a mount point. | 3161 | * is kind of like crossing a mount point. |
3071 | */ | 3162 | */ |
3072 | static int fixup_tree_root_location(struct btrfs_root *root, | 3163 | static int fixup_tree_root_location(struct btrfs_root *root, |
3073 | struct btrfs_key *location, | 3164 | struct inode *dir, |
3074 | struct btrfs_root **sub_root, | 3165 | struct dentry *dentry, |
3075 | struct dentry *dentry) | 3166 | struct btrfs_key *location, |
3167 | struct btrfs_root **sub_root) | ||
3076 | { | 3168 | { |
3077 | struct btrfs_root_item *ri; | 3169 | struct btrfs_path *path; |
3170 | struct btrfs_root *new_root; | ||
3171 | struct btrfs_root_ref *ref; | ||
3172 | struct extent_buffer *leaf; | ||
3173 | int ret; | ||
3174 | int err = 0; | ||
3078 | 3175 | ||
3079 | if (btrfs_key_type(location) != BTRFS_ROOT_ITEM_KEY) | 3176 | path = btrfs_alloc_path(); |
3080 | return 0; | 3177 | if (!path) { |
3081 | if (location->objectid == BTRFS_ROOT_TREE_OBJECTID) | 3178 | err = -ENOMEM; |
3082 | return 0; | 3179 | goto out; |
3180 | } | ||
3083 | 3181 | ||
3084 | *sub_root = btrfs_read_fs_root(root->fs_info, location, | 3182 | err = -ENOENT; |
3085 | dentry->d_name.name, | 3183 | ret = btrfs_find_root_ref(root->fs_info->tree_root, path, |
3086 | dentry->d_name.len); | 3184 | BTRFS_I(dir)->root->root_key.objectid, |
3087 | if (IS_ERR(*sub_root)) | 3185 | location->objectid); |
3088 | return PTR_ERR(*sub_root); | 3186 | if (ret) { |
3187 | if (ret < 0) | ||
3188 | err = ret; | ||
3189 | goto out; | ||
3190 | } | ||
3089 | 3191 | ||
3090 | ri = &(*sub_root)->root_item; | 3192 | leaf = path->nodes[0]; |
3091 | location->objectid = btrfs_root_dirid(ri); | 3193 | ref = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_ref); |
3092 | btrfs_set_key_type(location, BTRFS_INODE_ITEM_KEY); | 3194 | if (btrfs_root_ref_dirid(leaf, ref) != dir->i_ino || |
3093 | location->offset = 0; | 3195 | btrfs_root_ref_name_len(leaf, ref) != dentry->d_name.len) |
3196 | goto out; | ||
3094 | 3197 | ||
3095 | return 0; | 3198 | ret = memcmp_extent_buffer(leaf, dentry->d_name.name, |
3199 | (unsigned long)(ref + 1), | ||
3200 | dentry->d_name.len); | ||
3201 | if (ret) | ||
3202 | goto out; | ||
3203 | |||
3204 | btrfs_release_path(root->fs_info->tree_root, path); | ||
3205 | |||
3206 | new_root = btrfs_read_fs_root_no_name(root->fs_info, location); | ||
3207 | if (IS_ERR(new_root)) { | ||
3208 | err = PTR_ERR(new_root); | ||
3209 | goto out; | ||
3210 | } | ||
3211 | |||
3212 | if (btrfs_root_refs(&new_root->root_item) == 0) { | ||
3213 | err = -ENOENT; | ||
3214 | goto out; | ||
3215 | } | ||
3216 | |||
3217 | *sub_root = new_root; | ||
3218 | location->objectid = btrfs_root_dirid(&new_root->root_item); | ||
3219 | location->type = BTRFS_INODE_ITEM_KEY; | ||
3220 | location->offset = 0; | ||
3221 | err = 0; | ||
3222 | out: | ||
3223 | btrfs_free_path(path); | ||
3224 | return err; | ||
3096 | } | 3225 | } |
3097 | 3226 | ||
3098 | static void inode_tree_add(struct inode *inode) | 3227 | static void inode_tree_add(struct inode *inode) |
@@ -3101,11 +3230,13 @@ static void inode_tree_add(struct inode *inode) | |||
3101 | struct btrfs_inode *entry; | 3230 | struct btrfs_inode *entry; |
3102 | struct rb_node **p; | 3231 | struct rb_node **p; |
3103 | struct rb_node *parent; | 3232 | struct rb_node *parent; |
3104 | |||
3105 | again: | 3233 | again: |
3106 | p = &root->inode_tree.rb_node; | 3234 | p = &root->inode_tree.rb_node; |
3107 | parent = NULL; | 3235 | parent = NULL; |
3108 | 3236 | ||
3237 | if (hlist_unhashed(&inode->i_hash)) | ||
3238 | return; | ||
3239 | |||
3109 | spin_lock(&root->inode_lock); | 3240 | spin_lock(&root->inode_lock); |
3110 | while (*p) { | 3241 | while (*p) { |
3111 | parent = *p; | 3242 | parent = *p; |
@@ -3132,13 +3263,87 @@ again: | |||
3132 | static void inode_tree_del(struct inode *inode) | 3263 | static void inode_tree_del(struct inode *inode) |
3133 | { | 3264 | { |
3134 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3265 | struct btrfs_root *root = BTRFS_I(inode)->root; |
3266 | int empty = 0; | ||
3135 | 3267 | ||
3136 | spin_lock(&root->inode_lock); | 3268 | spin_lock(&root->inode_lock); |
3137 | if (!RB_EMPTY_NODE(&BTRFS_I(inode)->rb_node)) { | 3269 | if (!RB_EMPTY_NODE(&BTRFS_I(inode)->rb_node)) { |
3138 | rb_erase(&BTRFS_I(inode)->rb_node, &root->inode_tree); | 3270 | rb_erase(&BTRFS_I(inode)->rb_node, &root->inode_tree); |
3139 | RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); | 3271 | RB_CLEAR_NODE(&BTRFS_I(inode)->rb_node); |
3272 | empty = RB_EMPTY_ROOT(&root->inode_tree); | ||
3140 | } | 3273 | } |
3141 | spin_unlock(&root->inode_lock); | 3274 | spin_unlock(&root->inode_lock); |
3275 | |||
3276 | if (empty && btrfs_root_refs(&root->root_item) == 0) { | ||
3277 | synchronize_srcu(&root->fs_info->subvol_srcu); | ||
3278 | spin_lock(&root->inode_lock); | ||
3279 | empty = RB_EMPTY_ROOT(&root->inode_tree); | ||
3280 | spin_unlock(&root->inode_lock); | ||
3281 | if (empty) | ||
3282 | btrfs_add_dead_root(root); | ||
3283 | } | ||
3284 | } | ||
3285 | |||
3286 | int btrfs_invalidate_inodes(struct btrfs_root *root) | ||
3287 | { | ||
3288 | struct rb_node *node; | ||
3289 | struct rb_node *prev; | ||
3290 | struct btrfs_inode *entry; | ||
3291 | struct inode *inode; | ||
3292 | u64 objectid = 0; | ||
3293 | |||
3294 | WARN_ON(btrfs_root_refs(&root->root_item) != 0); | ||
3295 | |||
3296 | spin_lock(&root->inode_lock); | ||
3297 | again: | ||
3298 | node = root->inode_tree.rb_node; | ||
3299 | prev = NULL; | ||
3300 | while (node) { | ||
3301 | prev = node; | ||
3302 | entry = rb_entry(node, struct btrfs_inode, rb_node); | ||
3303 | |||
3304 | if (objectid < entry->vfs_inode.i_ino) | ||
3305 | node = node->rb_left; | ||
3306 | else if (objectid > entry->vfs_inode.i_ino) | ||
3307 | node = node->rb_right; | ||
3308 | else | ||
3309 | break; | ||
3310 | } | ||
3311 | if (!node) { | ||
3312 | while (prev) { | ||
3313 | entry = rb_entry(prev, struct btrfs_inode, rb_node); | ||
3314 | if (objectid <= entry->vfs_inode.i_ino) { | ||
3315 | node = prev; | ||
3316 | break; | ||
3317 | } | ||
3318 | prev = rb_next(prev); | ||
3319 | } | ||
3320 | } | ||
3321 | while (node) { | ||
3322 | entry = rb_entry(node, struct btrfs_inode, rb_node); | ||
3323 | objectid = entry->vfs_inode.i_ino + 1; | ||
3324 | inode = igrab(&entry->vfs_inode); | ||
3325 | if (inode) { | ||
3326 | spin_unlock(&root->inode_lock); | ||
3327 | if (atomic_read(&inode->i_count) > 1) | ||
3328 | d_prune_aliases(inode); | ||
3329 | /* | ||
3330 | * btrfs_drop_inode will remove it from | ||
3331 | * the inode cache when its usage count | ||
3332 | * hits zero. | ||
3333 | */ | ||
3334 | iput(inode); | ||
3335 | cond_resched(); | ||
3336 | spin_lock(&root->inode_lock); | ||
3337 | goto again; | ||
3338 | } | ||
3339 | |||
3340 | if (cond_resched_lock(&root->inode_lock)) | ||
3341 | goto again; | ||
3342 | |||
3343 | node = rb_next(node); | ||
3344 | } | ||
3345 | spin_unlock(&root->inode_lock); | ||
3346 | return 0; | ||
3142 | } | 3347 | } |
3143 | 3348 | ||
3144 | static noinline void init_btrfs_i(struct inode *inode) | 3349 | static noinline void init_btrfs_i(struct inode *inode) |
@@ -3225,15 +3430,41 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
3225 | return inode; | 3430 | return inode; |
3226 | } | 3431 | } |
3227 | 3432 | ||
3433 | static struct inode *new_simple_dir(struct super_block *s, | ||
3434 | struct btrfs_key *key, | ||
3435 | struct btrfs_root *root) | ||
3436 | { | ||
3437 | struct inode *inode = new_inode(s); | ||
3438 | |||
3439 | if (!inode) | ||
3440 | return ERR_PTR(-ENOMEM); | ||
3441 | |||
3442 | init_btrfs_i(inode); | ||
3443 | |||
3444 | BTRFS_I(inode)->root = root; | ||
3445 | memcpy(&BTRFS_I(inode)->location, key, sizeof(*key)); | ||
3446 | BTRFS_I(inode)->dummy_inode = 1; | ||
3447 | |||
3448 | inode->i_ino = BTRFS_EMPTY_SUBVOL_DIR_OBJECTID; | ||
3449 | inode->i_op = &simple_dir_inode_operations; | ||
3450 | inode->i_fop = &simple_dir_operations; | ||
3451 | inode->i_mode = S_IFDIR | S_IRUGO | S_IWUSR | S_IXUGO; | ||
3452 | inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME; | ||
3453 | |||
3454 | return inode; | ||
3455 | } | ||
3456 | |||
3228 | struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | 3457 | struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) |
3229 | { | 3458 | { |
3230 | struct inode *inode; | 3459 | struct inode *inode; |
3231 | struct btrfs_inode *bi = BTRFS_I(dir); | 3460 | struct btrfs_root *root = BTRFS_I(dir)->root; |
3232 | struct btrfs_root *root = bi->root; | ||
3233 | struct btrfs_root *sub_root = root; | 3461 | struct btrfs_root *sub_root = root; |
3234 | struct btrfs_key location; | 3462 | struct btrfs_key location; |
3463 | int index; | ||
3235 | int ret; | 3464 | int ret; |
3236 | 3465 | ||
3466 | dentry->d_op = &btrfs_dentry_operations; | ||
3467 | |||
3237 | if (dentry->d_name.len > BTRFS_NAME_LEN) | 3468 | if (dentry->d_name.len > BTRFS_NAME_LEN) |
3238 | return ERR_PTR(-ENAMETOOLONG); | 3469 | return ERR_PTR(-ENAMETOOLONG); |
3239 | 3470 | ||
@@ -3242,29 +3473,50 @@ struct inode *btrfs_lookup_dentry(struct inode *dir, struct dentry *dentry) | |||
3242 | if (ret < 0) | 3473 | if (ret < 0) |
3243 | return ERR_PTR(ret); | 3474 | return ERR_PTR(ret); |
3244 | 3475 | ||
3245 | inode = NULL; | 3476 | if (location.objectid == 0) |
3246 | if (location.objectid) { | 3477 | return NULL; |
3247 | ret = fixup_tree_root_location(root, &location, &sub_root, | 3478 | |
3248 | dentry); | 3479 | if (location.type == BTRFS_INODE_ITEM_KEY) { |
3249 | if (ret < 0) | 3480 | inode = btrfs_iget(dir->i_sb, &location, root); |
3250 | return ERR_PTR(ret); | 3481 | return inode; |
3251 | if (ret > 0) | 3482 | } |
3252 | return ERR_PTR(-ENOENT); | 3483 | |
3484 | BUG_ON(location.type != BTRFS_ROOT_ITEM_KEY); | ||
3485 | |||
3486 | index = srcu_read_lock(&root->fs_info->subvol_srcu); | ||
3487 | ret = fixup_tree_root_location(root, dir, dentry, | ||
3488 | &location, &sub_root); | ||
3489 | if (ret < 0) { | ||
3490 | if (ret != -ENOENT) | ||
3491 | inode = ERR_PTR(ret); | ||
3492 | else | ||
3493 | inode = new_simple_dir(dir->i_sb, &location, sub_root); | ||
3494 | } else { | ||
3253 | inode = btrfs_iget(dir->i_sb, &location, sub_root); | 3495 | inode = btrfs_iget(dir->i_sb, &location, sub_root); |
3254 | if (IS_ERR(inode)) | ||
3255 | return ERR_CAST(inode); | ||
3256 | } | 3496 | } |
3497 | srcu_read_unlock(&root->fs_info->subvol_srcu, index); | ||
3498 | |||
3257 | return inode; | 3499 | return inode; |
3258 | } | 3500 | } |
3259 | 3501 | ||
3502 | static int btrfs_dentry_delete(struct dentry *dentry) | ||
3503 | { | ||
3504 | struct btrfs_root *root; | ||
3505 | |||
3506 | if (!dentry->d_inode) | ||
3507 | return 0; | ||
3508 | |||
3509 | root = BTRFS_I(dentry->d_inode)->root; | ||
3510 | if (btrfs_root_refs(&root->root_item) == 0) | ||
3511 | return 1; | ||
3512 | return 0; | ||
3513 | } | ||
3514 | |||
3260 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, | 3515 | static struct dentry *btrfs_lookup(struct inode *dir, struct dentry *dentry, |
3261 | struct nameidata *nd) | 3516 | struct nameidata *nd) |
3262 | { | 3517 | { |
3263 | struct inode *inode; | 3518 | struct inode *inode; |
3264 | 3519 | ||
3265 | if (dentry->d_name.len > BTRFS_NAME_LEN) | ||
3266 | return ERR_PTR(-ENAMETOOLONG); | ||
3267 | |||
3268 | inode = btrfs_lookup_dentry(dir, dentry); | 3520 | inode = btrfs_lookup_dentry(dir, dentry); |
3269 | if (IS_ERR(inode)) | 3521 | if (IS_ERR(inode)) |
3270 | return ERR_CAST(inode); | 3522 | return ERR_CAST(inode); |
@@ -3603,9 +3855,6 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, | |||
3603 | if (ret != 0) | 3855 | if (ret != 0) |
3604 | goto fail; | 3856 | goto fail; |
3605 | 3857 | ||
3606 | if (objectid > root->highest_inode) | ||
3607 | root->highest_inode = objectid; | ||
3608 | |||
3609 | inode->i_uid = current_fsuid(); | 3858 | inode->i_uid = current_fsuid(); |
3610 | 3859 | ||
3611 | if (dir && (dir->i_mode & S_ISGID)) { | 3860 | if (dir && (dir->i_mode & S_ISGID)) { |
@@ -3673,26 +3922,35 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, | |||
3673 | struct inode *parent_inode, struct inode *inode, | 3922 | struct inode *parent_inode, struct inode *inode, |
3674 | const char *name, int name_len, int add_backref, u64 index) | 3923 | const char *name, int name_len, int add_backref, u64 index) |
3675 | { | 3924 | { |
3676 | int ret; | 3925 | int ret = 0; |
3677 | struct btrfs_key key; | 3926 | struct btrfs_key key; |
3678 | struct btrfs_root *root = BTRFS_I(parent_inode)->root; | 3927 | struct btrfs_root *root = BTRFS_I(parent_inode)->root; |
3679 | 3928 | ||
3680 | key.objectid = inode->i_ino; | 3929 | if (unlikely(inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { |
3681 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | 3930 | memcpy(&key, &BTRFS_I(inode)->root->root_key, sizeof(key)); |
3682 | key.offset = 0; | 3931 | } else { |
3932 | key.objectid = inode->i_ino; | ||
3933 | btrfs_set_key_type(&key, BTRFS_INODE_ITEM_KEY); | ||
3934 | key.offset = 0; | ||
3935 | } | ||
3936 | |||
3937 | if (unlikely(inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { | ||
3938 | ret = btrfs_add_root_ref(trans, root->fs_info->tree_root, | ||
3939 | key.objectid, root->root_key.objectid, | ||
3940 | parent_inode->i_ino, | ||
3941 | index, name, name_len); | ||
3942 | } else if (add_backref) { | ||
3943 | ret = btrfs_insert_inode_ref(trans, root, | ||
3944 | name, name_len, inode->i_ino, | ||
3945 | parent_inode->i_ino, index); | ||
3946 | } | ||
3683 | 3947 | ||
3684 | ret = btrfs_insert_dir_item(trans, root, name, name_len, | ||
3685 | parent_inode->i_ino, | ||
3686 | &key, btrfs_inode_type(inode), | ||
3687 | index); | ||
3688 | if (ret == 0) { | 3948 | if (ret == 0) { |
3689 | if (add_backref) { | 3949 | ret = btrfs_insert_dir_item(trans, root, name, name_len, |
3690 | ret = btrfs_insert_inode_ref(trans, root, | 3950 | parent_inode->i_ino, &key, |
3691 | name, name_len, | 3951 | btrfs_inode_type(inode), index); |
3692 | inode->i_ino, | 3952 | BUG_ON(ret); |
3693 | parent_inode->i_ino, | 3953 | |
3694 | index); | ||
3695 | } | ||
3696 | btrfs_i_size_write(parent_inode, parent_inode->i_size + | 3954 | btrfs_i_size_write(parent_inode, parent_inode->i_size + |
3697 | name_len * 2); | 3955 | name_len * 2); |
3698 | parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; | 3956 | parent_inode->i_mtime = parent_inode->i_ctime = CURRENT_TIME; |
@@ -3875,18 +4133,16 @@ static int btrfs_link(struct dentry *old_dentry, struct inode *dir, | |||
3875 | 4133 | ||
3876 | err = btrfs_add_nondir(trans, dentry, inode, 1, index); | 4134 | err = btrfs_add_nondir(trans, dentry, inode, 1, index); |
3877 | 4135 | ||
3878 | if (err) | 4136 | if (err) { |
3879 | drop_inode = 1; | ||
3880 | |||
3881 | btrfs_update_inode_block_group(trans, dir); | ||
3882 | err = btrfs_update_inode(trans, root, inode); | ||
3883 | |||
3884 | if (err) | ||
3885 | drop_inode = 1; | 4137 | drop_inode = 1; |
4138 | } else { | ||
4139 | btrfs_update_inode_block_group(trans, dir); | ||
4140 | err = btrfs_update_inode(trans, root, inode); | ||
4141 | BUG_ON(err); | ||
4142 | btrfs_log_new_name(trans, inode, NULL, dentry->d_parent); | ||
4143 | } | ||
3886 | 4144 | ||
3887 | nr = trans->blocks_used; | 4145 | nr = trans->blocks_used; |
3888 | |||
3889 | btrfs_log_new_name(trans, inode, NULL, dentry->d_parent); | ||
3890 | btrfs_end_transaction_throttle(trans, root); | 4146 | btrfs_end_transaction_throttle(trans, root); |
3891 | fail: | 4147 | fail: |
3892 | if (drop_inode) { | 4148 | if (drop_inode) { |
@@ -4064,11 +4320,11 @@ struct extent_map *btrfs_get_extent(struct inode *inode, struct page *page, | |||
4064 | int compressed; | 4320 | int compressed; |
4065 | 4321 | ||
4066 | again: | 4322 | again: |
4067 | spin_lock(&em_tree->lock); | 4323 | read_lock(&em_tree->lock); |
4068 | em = lookup_extent_mapping(em_tree, start, len); | 4324 | em = lookup_extent_mapping(em_tree, start, len); |
4069 | if (em) | 4325 | if (em) |
4070 | em->bdev = root->fs_info->fs_devices->latest_bdev; | 4326 | em->bdev = root->fs_info->fs_devices->latest_bdev; |
4071 | spin_unlock(&em_tree->lock); | 4327 | read_unlock(&em_tree->lock); |
4072 | 4328 | ||
4073 | if (em) { | 4329 | if (em) { |
4074 | if (em->start > start || em->start + em->len <= start) | 4330 | if (em->start > start || em->start + em->len <= start) |
@@ -4215,6 +4471,11 @@ again: | |||
4215 | map = kmap(page); | 4471 | map = kmap(page); |
4216 | read_extent_buffer(leaf, map + pg_offset, ptr, | 4472 | read_extent_buffer(leaf, map + pg_offset, ptr, |
4217 | copy_size); | 4473 | copy_size); |
4474 | if (pg_offset + copy_size < PAGE_CACHE_SIZE) { | ||
4475 | memset(map + pg_offset + copy_size, 0, | ||
4476 | PAGE_CACHE_SIZE - pg_offset - | ||
4477 | copy_size); | ||
4478 | } | ||
4218 | kunmap(page); | 4479 | kunmap(page); |
4219 | } | 4480 | } |
4220 | flush_dcache_page(page); | 4481 | flush_dcache_page(page); |
@@ -4259,7 +4520,7 @@ insert: | |||
4259 | } | 4520 | } |
4260 | 4521 | ||
4261 | err = 0; | 4522 | err = 0; |
4262 | spin_lock(&em_tree->lock); | 4523 | write_lock(&em_tree->lock); |
4263 | ret = add_extent_mapping(em_tree, em); | 4524 | ret = add_extent_mapping(em_tree, em); |
4264 | /* it is possible that someone inserted the extent into the tree | 4525 | /* it is possible that someone inserted the extent into the tree |
4265 | * while we had the lock dropped. It is also possible that | 4526 | * while we had the lock dropped. It is also possible that |
@@ -4299,7 +4560,7 @@ insert: | |||
4299 | err = 0; | 4560 | err = 0; |
4300 | } | 4561 | } |
4301 | } | 4562 | } |
4302 | spin_unlock(&em_tree->lock); | 4563 | write_unlock(&em_tree->lock); |
4303 | out: | 4564 | out: |
4304 | if (path) | 4565 | if (path) |
4305 | btrfs_free_path(path); | 4566 | btrfs_free_path(path); |
@@ -4398,13 +4659,21 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
4398 | u64 page_start = page_offset(page); | 4659 | u64 page_start = page_offset(page); |
4399 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; | 4660 | u64 page_end = page_start + PAGE_CACHE_SIZE - 1; |
4400 | 4661 | ||
4662 | |||
4663 | /* | ||
4664 | * we have the page locked, so new writeback can't start, | ||
4665 | * and the dirty bit won't be cleared while we are here. | ||
4666 | * | ||
4667 | * Wait for IO on this page so that we can safely clear | ||
4668 | * the PagePrivate2 bit and do ordered accounting | ||
4669 | */ | ||
4401 | wait_on_page_writeback(page); | 4670 | wait_on_page_writeback(page); |
4671 | |||
4402 | tree = &BTRFS_I(page->mapping->host)->io_tree; | 4672 | tree = &BTRFS_I(page->mapping->host)->io_tree; |
4403 | if (offset) { | 4673 | if (offset) { |
4404 | btrfs_releasepage(page, GFP_NOFS); | 4674 | btrfs_releasepage(page, GFP_NOFS); |
4405 | return; | 4675 | return; |
4406 | } | 4676 | } |
4407 | |||
4408 | lock_extent(tree, page_start, page_end, GFP_NOFS); | 4677 | lock_extent(tree, page_start, page_end, GFP_NOFS); |
4409 | ordered = btrfs_lookup_ordered_extent(page->mapping->host, | 4678 | ordered = btrfs_lookup_ordered_extent(page->mapping->host, |
4410 | page_offset(page)); | 4679 | page_offset(page)); |
@@ -4415,16 +4684,21 @@ static void btrfs_invalidatepage(struct page *page, unsigned long offset) | |||
4415 | */ | 4684 | */ |
4416 | clear_extent_bit(tree, page_start, page_end, | 4685 | clear_extent_bit(tree, page_start, page_end, |
4417 | EXTENT_DIRTY | EXTENT_DELALLOC | | 4686 | EXTENT_DIRTY | EXTENT_DELALLOC | |
4418 | EXTENT_LOCKED, 1, 0, GFP_NOFS); | 4687 | EXTENT_LOCKED, 1, 0, NULL, GFP_NOFS); |
4419 | btrfs_finish_ordered_io(page->mapping->host, | 4688 | /* |
4420 | page_start, page_end); | 4689 | * whoever cleared the private bit is responsible |
4690 | * for the finish_ordered_io | ||
4691 | */ | ||
4692 | if (TestClearPagePrivate2(page)) { | ||
4693 | btrfs_finish_ordered_io(page->mapping->host, | ||
4694 | page_start, page_end); | ||
4695 | } | ||
4421 | btrfs_put_ordered_extent(ordered); | 4696 | btrfs_put_ordered_extent(ordered); |
4422 | lock_extent(tree, page_start, page_end, GFP_NOFS); | 4697 | lock_extent(tree, page_start, page_end, GFP_NOFS); |
4423 | } | 4698 | } |
4424 | clear_extent_bit(tree, page_start, page_end, | 4699 | clear_extent_bit(tree, page_start, page_end, |
4425 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC | | 4700 | EXTENT_LOCKED | EXTENT_DIRTY | EXTENT_DELALLOC, |
4426 | EXTENT_ORDERED, | 4701 | 1, 1, NULL, GFP_NOFS); |
4427 | 1, 1, GFP_NOFS); | ||
4428 | __btrfs_releasepage(page, GFP_NOFS); | 4702 | __btrfs_releasepage(page, GFP_NOFS); |
4429 | 4703 | ||
4430 | ClearPageChecked(page); | 4704 | ClearPageChecked(page); |
@@ -4521,11 +4795,14 @@ again: | |||
4521 | } | 4795 | } |
4522 | ClearPageChecked(page); | 4796 | ClearPageChecked(page); |
4523 | set_page_dirty(page); | 4797 | set_page_dirty(page); |
4798 | SetPageUptodate(page); | ||
4524 | 4799 | ||
4525 | BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; | 4800 | BTRFS_I(inode)->last_trans = root->fs_info->generation + 1; |
4526 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); | 4801 | unlock_extent(io_tree, page_start, page_end, GFP_NOFS); |
4527 | 4802 | ||
4528 | out_unlock: | 4803 | out_unlock: |
4804 | if (!ret) | ||
4805 | return VM_FAULT_LOCKED; | ||
4529 | unlock_page(page); | 4806 | unlock_page(page); |
4530 | out: | 4807 | out: |
4531 | return ret; | 4808 | return ret; |
@@ -4594,11 +4871,11 @@ out: | |||
4594 | * create a new subvolume directory/inode (helper for the ioctl). | 4871 | * create a new subvolume directory/inode (helper for the ioctl). |
4595 | */ | 4872 | */ |
4596 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | 4873 | int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, |
4597 | struct btrfs_root *new_root, struct dentry *dentry, | 4874 | struct btrfs_root *new_root, |
4598 | u64 new_dirid, u64 alloc_hint) | 4875 | u64 new_dirid, u64 alloc_hint) |
4599 | { | 4876 | { |
4600 | struct inode *inode; | 4877 | struct inode *inode; |
4601 | int error; | 4878 | int err; |
4602 | u64 index = 0; | 4879 | u64 index = 0; |
4603 | 4880 | ||
4604 | inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, | 4881 | inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, |
@@ -4611,11 +4888,10 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | |||
4611 | inode->i_nlink = 1; | 4888 | inode->i_nlink = 1; |
4612 | btrfs_i_size_write(inode, 0); | 4889 | btrfs_i_size_write(inode, 0); |
4613 | 4890 | ||
4614 | error = btrfs_update_inode(trans, new_root, inode); | 4891 | err = btrfs_update_inode(trans, new_root, inode); |
4615 | if (error) | 4892 | BUG_ON(err); |
4616 | return error; | ||
4617 | 4893 | ||
4618 | d_instantiate(dentry, inode); | 4894 | iput(inode); |
4619 | return 0; | 4895 | return 0; |
4620 | } | 4896 | } |
4621 | 4897 | ||
@@ -4693,6 +4969,16 @@ void btrfs_destroy_inode(struct inode *inode) | |||
4693 | kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); | 4969 | kmem_cache_free(btrfs_inode_cachep, BTRFS_I(inode)); |
4694 | } | 4970 | } |
4695 | 4971 | ||
4972 | void btrfs_drop_inode(struct inode *inode) | ||
4973 | { | ||
4974 | struct btrfs_root *root = BTRFS_I(inode)->root; | ||
4975 | |||
4976 | if (inode->i_nlink > 0 && btrfs_root_refs(&root->root_item) == 0) | ||
4977 | generic_delete_inode(inode); | ||
4978 | else | ||
4979 | generic_drop_inode(inode); | ||
4980 | } | ||
4981 | |||
4696 | static void init_once(void *foo) | 4982 | static void init_once(void *foo) |
4697 | { | 4983 | { |
4698 | struct btrfs_inode *ei = (struct btrfs_inode *) foo; | 4984 | struct btrfs_inode *ei = (struct btrfs_inode *) foo; |
@@ -4761,31 +5047,32 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4761 | { | 5047 | { |
4762 | struct btrfs_trans_handle *trans; | 5048 | struct btrfs_trans_handle *trans; |
4763 | struct btrfs_root *root = BTRFS_I(old_dir)->root; | 5049 | struct btrfs_root *root = BTRFS_I(old_dir)->root; |
5050 | struct btrfs_root *dest = BTRFS_I(new_dir)->root; | ||
4764 | struct inode *new_inode = new_dentry->d_inode; | 5051 | struct inode *new_inode = new_dentry->d_inode; |
4765 | struct inode *old_inode = old_dentry->d_inode; | 5052 | struct inode *old_inode = old_dentry->d_inode; |
4766 | struct timespec ctime = CURRENT_TIME; | 5053 | struct timespec ctime = CURRENT_TIME; |
4767 | u64 index = 0; | 5054 | u64 index = 0; |
5055 | u64 root_objectid; | ||
4768 | int ret; | 5056 | int ret; |
4769 | 5057 | ||
4770 | /* we're not allowed to rename between subvolumes */ | 5058 | if (new_dir->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID) |
4771 | if (BTRFS_I(old_inode)->root->root_key.objectid != | 5059 | return -EPERM; |
4772 | BTRFS_I(new_dir)->root->root_key.objectid) | 5060 | |
5061 | /* we only allow rename subvolume link between subvolumes */ | ||
5062 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID && root != dest) | ||
4773 | return -EXDEV; | 5063 | return -EXDEV; |
4774 | 5064 | ||
4775 | if (S_ISDIR(old_inode->i_mode) && new_inode && | 5065 | if (old_inode->i_ino == BTRFS_EMPTY_SUBVOL_DIR_OBJECTID || |
4776 | new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) { | 5066 | (new_inode && new_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) |
4777 | return -ENOTEMPTY; | 5067 | return -ENOTEMPTY; |
4778 | } | ||
4779 | 5068 | ||
4780 | /* to rename a snapshot or subvolume, we need to juggle the | 5069 | if (S_ISDIR(old_inode->i_mode) && new_inode && |
4781 | * backrefs. This isn't coded yet | 5070 | new_inode->i_size > BTRFS_EMPTY_DIR_SIZE) |
4782 | */ | 5071 | return -ENOTEMPTY; |
4783 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | ||
4784 | return -EXDEV; | ||
4785 | 5072 | ||
4786 | ret = btrfs_check_metadata_free_space(root); | 5073 | ret = btrfs_check_metadata_free_space(root); |
4787 | if (ret) | 5074 | if (ret) |
4788 | goto out_unlock; | 5075 | return ret; |
4789 | 5076 | ||
4790 | /* | 5077 | /* |
4791 | * we're using rename to replace one file with another. | 5078 | * we're using rename to replace one file with another. |
@@ -4796,8 +5083,40 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4796 | old_inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) | 5083 | old_inode->i_size > BTRFS_ORDERED_OPERATIONS_FLUSH_LIMIT) |
4797 | filemap_flush(old_inode->i_mapping); | 5084 | filemap_flush(old_inode->i_mapping); |
4798 | 5085 | ||
5086 | /* close the racy window with snapshot create/destroy ioctl */ | ||
5087 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | ||
5088 | down_read(&root->fs_info->subvol_sem); | ||
5089 | |||
4799 | trans = btrfs_start_transaction(root, 1); | 5090 | trans = btrfs_start_transaction(root, 1); |
5091 | btrfs_set_trans_block_group(trans, new_dir); | ||
5092 | |||
5093 | if (dest != root) | ||
5094 | btrfs_record_root_in_trans(trans, dest); | ||
4800 | 5095 | ||
5096 | ret = btrfs_set_inode_index(new_dir, &index); | ||
5097 | if (ret) | ||
5098 | goto out_fail; | ||
5099 | |||
5100 | if (unlikely(old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { | ||
5101 | /* force full log commit if subvolume involved. */ | ||
5102 | root->fs_info->last_trans_log_full_commit = trans->transid; | ||
5103 | } else { | ||
5104 | ret = btrfs_insert_inode_ref(trans, dest, | ||
5105 | new_dentry->d_name.name, | ||
5106 | new_dentry->d_name.len, | ||
5107 | old_inode->i_ino, | ||
5108 | new_dir->i_ino, index); | ||
5109 | if (ret) | ||
5110 | goto out_fail; | ||
5111 | /* | ||
5112 | * this is an ugly little race, but the rename is required | ||
5113 | * to make sure that if we crash, the inode is either at the | ||
5114 | * old name or the new one. pinning the log transaction lets | ||
5115 | * us make sure we don't allow a log commit to come in after | ||
5116 | * we unlink the name but before we add the new name back in. | ||
5117 | */ | ||
5118 | btrfs_pin_log_trans(root); | ||
5119 | } | ||
4801 | /* | 5120 | /* |
4802 | * make sure the inode gets flushed if it is replacing | 5121 | * make sure the inode gets flushed if it is replacing |
4803 | * something. | 5122 | * something. |
@@ -4807,18 +5126,6 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4807 | btrfs_add_ordered_operation(trans, root, old_inode); | 5126 | btrfs_add_ordered_operation(trans, root, old_inode); |
4808 | } | 5127 | } |
4809 | 5128 | ||
4810 | /* | ||
4811 | * this is an ugly little race, but the rename is required to make | ||
4812 | * sure that if we crash, the inode is either at the old name | ||
4813 | * or the new one. pinning the log transaction lets us make sure | ||
4814 | * we don't allow a log commit to come in after we unlink the | ||
4815 | * name but before we add the new name back in. | ||
4816 | */ | ||
4817 | btrfs_pin_log_trans(root); | ||
4818 | |||
4819 | btrfs_set_trans_block_group(trans, new_dir); | ||
4820 | |||
4821 | btrfs_inc_nlink(old_dentry->d_inode); | ||
4822 | old_dir->i_ctime = old_dir->i_mtime = ctime; | 5129 | old_dir->i_ctime = old_dir->i_mtime = ctime; |
4823 | new_dir->i_ctime = new_dir->i_mtime = ctime; | 5130 | new_dir->i_ctime = new_dir->i_mtime = ctime; |
4824 | old_inode->i_ctime = ctime; | 5131 | old_inode->i_ctime = ctime; |
@@ -4826,47 +5133,58 @@ static int btrfs_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
4826 | if (old_dentry->d_parent != new_dentry->d_parent) | 5133 | if (old_dentry->d_parent != new_dentry->d_parent) |
4827 | btrfs_record_unlink_dir(trans, old_dir, old_inode, 1); | 5134 | btrfs_record_unlink_dir(trans, old_dir, old_inode, 1); |
4828 | 5135 | ||
4829 | ret = btrfs_unlink_inode(trans, root, old_dir, old_dentry->d_inode, | 5136 | if (unlikely(old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)) { |
4830 | old_dentry->d_name.name, | 5137 | root_objectid = BTRFS_I(old_inode)->root->root_key.objectid; |
4831 | old_dentry->d_name.len); | 5138 | ret = btrfs_unlink_subvol(trans, root, old_dir, root_objectid, |
4832 | if (ret) | 5139 | old_dentry->d_name.name, |
4833 | goto out_fail; | 5140 | old_dentry->d_name.len); |
5141 | } else { | ||
5142 | btrfs_inc_nlink(old_dentry->d_inode); | ||
5143 | ret = btrfs_unlink_inode(trans, root, old_dir, | ||
5144 | old_dentry->d_inode, | ||
5145 | old_dentry->d_name.name, | ||
5146 | old_dentry->d_name.len); | ||
5147 | } | ||
5148 | BUG_ON(ret); | ||
4834 | 5149 | ||
4835 | if (new_inode) { | 5150 | if (new_inode) { |
4836 | new_inode->i_ctime = CURRENT_TIME; | 5151 | new_inode->i_ctime = CURRENT_TIME; |
4837 | ret = btrfs_unlink_inode(trans, root, new_dir, | 5152 | if (unlikely(new_inode->i_ino == |
4838 | new_dentry->d_inode, | 5153 | BTRFS_EMPTY_SUBVOL_DIR_OBJECTID)) { |
4839 | new_dentry->d_name.name, | 5154 | root_objectid = BTRFS_I(new_inode)->location.objectid; |
4840 | new_dentry->d_name.len); | 5155 | ret = btrfs_unlink_subvol(trans, dest, new_dir, |
4841 | if (ret) | 5156 | root_objectid, |
4842 | goto out_fail; | 5157 | new_dentry->d_name.name, |
5158 | new_dentry->d_name.len); | ||
5159 | BUG_ON(new_inode->i_nlink == 0); | ||
5160 | } else { | ||
5161 | ret = btrfs_unlink_inode(trans, dest, new_dir, | ||
5162 | new_dentry->d_inode, | ||
5163 | new_dentry->d_name.name, | ||
5164 | new_dentry->d_name.len); | ||
5165 | } | ||
5166 | BUG_ON(ret); | ||
4843 | if (new_inode->i_nlink == 0) { | 5167 | if (new_inode->i_nlink == 0) { |
4844 | ret = btrfs_orphan_add(trans, new_dentry->d_inode); | 5168 | ret = btrfs_orphan_add(trans, new_dentry->d_inode); |
4845 | if (ret) | 5169 | BUG_ON(ret); |
4846 | goto out_fail; | ||
4847 | } | 5170 | } |
4848 | |||
4849 | } | 5171 | } |
4850 | ret = btrfs_set_inode_index(new_dir, &index); | ||
4851 | if (ret) | ||
4852 | goto out_fail; | ||
4853 | 5172 | ||
4854 | ret = btrfs_add_link(trans, new_dentry->d_parent->d_inode, | 5173 | ret = btrfs_add_link(trans, new_dir, old_inode, |
4855 | old_inode, new_dentry->d_name.name, | 5174 | new_dentry->d_name.name, |
4856 | new_dentry->d_name.len, 1, index); | 5175 | new_dentry->d_name.len, 0, index); |
4857 | if (ret) | 5176 | BUG_ON(ret); |
4858 | goto out_fail; | ||
4859 | 5177 | ||
4860 | btrfs_log_new_name(trans, old_inode, old_dir, | 5178 | if (old_inode->i_ino != BTRFS_FIRST_FREE_OBJECTID) { |
4861 | new_dentry->d_parent); | 5179 | btrfs_log_new_name(trans, old_inode, old_dir, |
5180 | new_dentry->d_parent); | ||
5181 | btrfs_end_log_trans(root); | ||
5182 | } | ||
4862 | out_fail: | 5183 | out_fail: |
4863 | |||
4864 | /* this btrfs_end_log_trans just allows the current | ||
4865 | * log-sub transaction to complete | ||
4866 | */ | ||
4867 | btrfs_end_log_trans(root); | ||
4868 | btrfs_end_transaction_throttle(trans, root); | 5184 | btrfs_end_transaction_throttle(trans, root); |
4869 | out_unlock: | 5185 | |
5186 | if (old_inode->i_ino == BTRFS_FIRST_FREE_OBJECTID) | ||
5187 | up_read(&root->fs_info->subvol_sem); | ||
4870 | return ret; | 5188 | return ret; |
4871 | } | 5189 | } |
4872 | 5190 | ||
@@ -5058,6 +5376,8 @@ static int prealloc_file_range(struct btrfs_trans_handle *trans, | |||
5058 | 0, 0, 0, | 5376 | 0, 0, 0, |
5059 | BTRFS_FILE_EXTENT_PREALLOC); | 5377 | BTRFS_FILE_EXTENT_PREALLOC); |
5060 | BUG_ON(ret); | 5378 | BUG_ON(ret); |
5379 | btrfs_drop_extent_cache(inode, cur_offset, | ||
5380 | cur_offset + ins.offset -1, 0); | ||
5061 | num_bytes -= ins.offset; | 5381 | num_bytes -= ins.offset; |
5062 | cur_offset += ins.offset; | 5382 | cur_offset += ins.offset; |
5063 | alloc_hint = ins.objectid + ins.offset; | 5383 | alloc_hint = ins.objectid + ins.offset; |
@@ -5223,6 +5543,7 @@ static const struct inode_operations btrfs_dir_ro_inode_operations = { | |||
5223 | .lookup = btrfs_lookup, | 5543 | .lookup = btrfs_lookup, |
5224 | .permission = btrfs_permission, | 5544 | .permission = btrfs_permission, |
5225 | }; | 5545 | }; |
5546 | |||
5226 | static struct file_operations btrfs_dir_file_operations = { | 5547 | static struct file_operations btrfs_dir_file_operations = { |
5227 | .llseek = generic_file_llseek, | 5548 | .llseek = generic_file_llseek, |
5228 | .read = generic_read_dir, | 5549 | .read = generic_read_dir, |
@@ -5310,3 +5631,7 @@ static const struct inode_operations btrfs_symlink_inode_operations = { | |||
5310 | .listxattr = btrfs_listxattr, | 5631 | .listxattr = btrfs_listxattr, |
5311 | .removexattr = btrfs_removexattr, | 5632 | .removexattr = btrfs_removexattr, |
5312 | }; | 5633 | }; |
5634 | |||
5635 | struct dentry_operations btrfs_dentry_operations = { | ||
5636 | .d_delete = btrfs_dentry_delete, | ||
5637 | }; | ||