Skip to content

Commit

Permalink
Btrfs: Update nodatacow mode to support cloned single files and resizing
Browse files Browse the repository at this point in the history
Before, nodatacow only checked to make sure multiple roots didn't have
references on a single extent.  This check makes sure that multiple
inodes don't have references.

nodatacow needed an extra check to see if the block group was currently
readonly.  This way cows forced by the chunk relocation code are honored.

Signed-off-by: Chris Mason <chris.mason@oracle.com>
  • Loading branch information
Chris Mason committed Sep 25, 2008
1 parent bf4ef67 commit a68d593
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 5 deletions.
2 changes: 1 addition & 1 deletion fs/btrfs/ctree.h
Original file line number Diff line number Diff line change
Expand Up @@ -1325,7 +1325,7 @@ static inline struct dentry *fdentry(struct file *file) {
/* extent-tree.c */
u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
struct btrfs_path *count_path,
u64 first_extent);
u64 expected_owner, u64 first_extent);
int btrfs_extent_post_op(struct btrfs_trans_handle *trans,
struct btrfs_root *root);
int btrfs_copy_pinned(struct btrfs_root *root, struct extent_io_tree *copy);
Expand Down
9 changes: 9 additions & 0 deletions fs/btrfs/extent-tree.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,12 +721,14 @@ static int lookup_extent_ref(struct btrfs_trans_handle *trans,

u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
struct btrfs_path *count_path,
u64 expected_owner,
u64 first_extent)
{
struct btrfs_root *extent_root = root->fs_info->extent_root;
struct btrfs_path *path;
u64 bytenr;
u64 found_objectid;
u64 found_owner;
u64 root_objectid = root->root_key.objectid;
u32 total_count = 0;
u32 cur_count;
Expand Down Expand Up @@ -792,6 +794,13 @@ u32 btrfs_count_snapshots_in_path(struct btrfs_root *root,
total_count = 2;
goto out;
}
if (level == -1) {
found_owner = btrfs_ref_objectid(l, ref_item);
if (found_owner != expected_owner) {
total_count = 2;
goto out;
}
}
total_count = 1;
path->slots[0]++;
}
Expand Down
13 changes: 9 additions & 4 deletions fs/btrfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ static int run_delalloc_nocow(struct inode *inode, u64 start, u64 end)
u64 loops = 0;
u64 total_fs_bytes;
struct btrfs_root *root = BTRFS_I(inode)->root;
struct btrfs_block_group_cache *block_group;
struct extent_buffer *leaf;
int found_type;
struct btrfs_path *path;
Expand Down Expand Up @@ -230,16 +231,20 @@ static int run_delalloc_nocow(struct inode *inode, u64 start, u64 end)
if (bytenr == 0)
goto not_found;

if (btrfs_count_snapshots_in_path(root, path, inode->i_ino,
bytenr) != 1) {
goto not_found;
}

/*
* we may be called by the resizer, make sure we're inside
* the limits of the FS
*/
if (bytenr + extent_num_bytes > total_fs_bytes)
block_group = btrfs_lookup_block_group(root->fs_info,
bytenr);
if (!block_group || block_group->ro)
goto not_found;

if (btrfs_count_snapshots_in_path(root, path, bytenr) != 1) {
goto not_found;
}

start = extent_end;
} else {
Expand Down

0 comments on commit a68d593

Please sign in to comment.