diff options
author | Chris Mason <chris.mason@oracle.com> | 2007-12-17 20:14:01 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:03:58 -0400 |
commit | be20aa9dbadc8c06283784ee12bbc0d97dea3418 (patch) | |
tree | 52bd8b7e21b36d10dbb48f8b163eea992c9cfd4a /fs/btrfs/extent-tree.c | |
parent | b6cda9bcb4df7544c67fc3548a53bc1607d59f46 (diff) |
Btrfs: Add mount option to turn off data cow
A number of workloads do not require copy on write data or checksumming.
mount -o nodatasum to disable checksums and -o nodatacow to disable
both copy on write and checksumming.
In nodatacow mode, copy on write is still performed when a given extent
is under snapshot.
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/extent-tree.c')
-rw-r--r-- | fs/btrfs/extent-tree.c | 101 |
1 files changed, 98 insertions, 3 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 00414836e963..1412d556313f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -679,6 +679,104 @@ out: | |||
679 | return 0; | 679 | return 0; |
680 | } | 680 | } |
681 | 681 | ||
682 | u32 btrfs_count_snapshots_in_path(struct btrfs_root *root, | ||
683 | struct btrfs_path *count_path, | ||
684 | u64 first_extent) | ||
685 | { | ||
686 | struct btrfs_root *extent_root = root->fs_info->extent_root; | ||
687 | struct btrfs_path *path; | ||
688 | u64 bytenr; | ||
689 | u64 found_objectid; | ||
690 | u64 root_objectid = 0; | ||
691 | u32 total_count = 0; | ||
692 | u32 cur_count; | ||
693 | u32 refs; | ||
694 | u32 nritems; | ||
695 | int ret; | ||
696 | struct btrfs_key key; | ||
697 | struct btrfs_key found_key; | ||
698 | struct extent_buffer *l; | ||
699 | struct btrfs_extent_item *item; | ||
700 | struct btrfs_extent_ref *ref_item; | ||
701 | int level = -1; | ||
702 | |||
703 | path = btrfs_alloc_path(); | ||
704 | again: | ||
705 | if (level == -1) | ||
706 | bytenr = first_extent; | ||
707 | else | ||
708 | bytenr = count_path->nodes[level]->start; | ||
709 | |||
710 | cur_count = 0; | ||
711 | key.objectid = bytenr; | ||
712 | key.offset = 0; | ||
713 | |||
714 | btrfs_set_key_type(&key, BTRFS_EXTENT_ITEM_KEY); | ||
715 | ret = btrfs_search_slot(NULL, extent_root, &key, path, 0, 0); | ||
716 | if (ret < 0) | ||
717 | goto out; | ||
718 | BUG_ON(ret == 0); | ||
719 | |||
720 | l = path->nodes[0]; | ||
721 | btrfs_item_key_to_cpu(l, &found_key, path->slots[0]); | ||
722 | |||
723 | if (found_key.objectid != bytenr || | ||
724 | found_key.type != BTRFS_EXTENT_ITEM_KEY) { | ||
725 | goto out; | ||
726 | } | ||
727 | |||
728 | item = btrfs_item_ptr(l, path->slots[0], struct btrfs_extent_item); | ||
729 | refs = btrfs_extent_refs(l, item); | ||
730 | while (1) { | ||
731 | nritems = btrfs_header_nritems(l); | ||
732 | if (path->slots[0] >= nritems) { | ||
733 | ret = btrfs_next_leaf(extent_root, path); | ||
734 | if (ret == 0) | ||
735 | continue; | ||
736 | break; | ||
737 | } | ||
738 | btrfs_item_key_to_cpu(l, &found_key, path->slots[0]); | ||
739 | if (found_key.objectid != bytenr) | ||
740 | break; | ||
741 | if (found_key.type != BTRFS_EXTENT_REF_KEY) { | ||
742 | path->slots[0]++; | ||
743 | continue; | ||
744 | } | ||
745 | |||
746 | cur_count++; | ||
747 | ref_item = btrfs_item_ptr(l, path->slots[0], | ||
748 | struct btrfs_extent_ref); | ||
749 | found_objectid = btrfs_ref_root(l, ref_item); | ||
750 | |||
751 | if (found_objectid != root_objectid) | ||
752 | total_count++; | ||
753 | |||
754 | if (total_count > 1) | ||
755 | goto out; | ||
756 | |||
757 | if (root_objectid == 0) | ||
758 | root_objectid = found_objectid; | ||
759 | |||
760 | path->slots[0]++; | ||
761 | } | ||
762 | if (cur_count == 0) { | ||
763 | total_count = 0; | ||
764 | goto out; | ||
765 | } | ||
766 | if (total_count > 1) | ||
767 | goto out; | ||
768 | if (level >= 0 && root->node == count_path->nodes[level]) | ||
769 | goto out; | ||
770 | level++; | ||
771 | btrfs_release_path(root, path); | ||
772 | goto again; | ||
773 | |||
774 | out: | ||
775 | btrfs_free_path(path); | ||
776 | return total_count; | ||
777 | |||
778 | } | ||
779 | |||
682 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, | 780 | int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, |
683 | struct btrfs_root *root, u64 owner_objectid) | 781 | struct btrfs_root *root, u64 owner_objectid) |
684 | { | 782 | { |
@@ -1127,9 +1225,6 @@ static int __free_extent(struct btrfs_trans_handle *trans, struct btrfs_root | |||
1127 | if (!path) | 1225 | if (!path) |
1128 | return -ENOMEM; | 1226 | return -ENOMEM; |
1129 | 1227 | ||
1130 | if (ref_generation && owner_objectid == 0 && root_objectid == 3) { | ||
1131 | //printk("drop backref root %Lu gen %Lu byte %Lu\n", root_objectid, ref_generation, bytenr ); | ||
1132 | } | ||
1133 | ret = lookup_extent_backref(trans, extent_root, path, | 1228 | ret = lookup_extent_backref(trans, extent_root, path, |
1134 | bytenr, root_objectid, | 1229 | bytenr, root_objectid, |
1135 | ref_generation, | 1230 | ref_generation, |