aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/extent-tree.c
diff options
context:
space:
mode:
authorChris Mason <chris.mason@oracle.com>2007-12-17 20:14:01 -0500
committerChris Mason <chris.mason@oracle.com>2008-09-25 11:03:58 -0400
commitbe20aa9dbadc8c06283784ee12bbc0d97dea3418 (patch)
tree52bd8b7e21b36d10dbb48f8b163eea992c9cfd4a /fs/btrfs/extent-tree.c
parentb6cda9bcb4df7544c67fc3548a53bc1607d59f46 (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.c101
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
682u32 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();
704again:
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
774out:
775 btrfs_free_path(path);
776 return total_count;
777
778}
779
682int btrfs_inc_root_ref(struct btrfs_trans_handle *trans, 780int 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,