diff options
author | Yan Zheng <zheng.yan@oracle.com> | 2008-08-05 13:05:02 -0400 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2008-09-25 11:04:06 -0400 |
commit | 7ea394f1192bee1af67ea4762c88ef4b7b0487a8 (patch) | |
tree | e2c593d054d802bc71e86508a5b7523ff80cc1ea /fs/btrfs/ordered-data.c | |
parent | 00e4e6b33a0f78aab4b788d6d31c884fd8bf88da (diff) |
Btrfs: Fix nodatacow for the new data=ordered mode
Signed-off-by: Chris Mason <chris.mason@oracle.com>
Diffstat (limited to 'fs/btrfs/ordered-data.c')
-rw-r--r-- | fs/btrfs/ordered-data.c | 16 |
1 files changed, 13 insertions, 3 deletions
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index db200e6baf7..da6d43eb41d 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -152,7 +152,7 @@ static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree, | |||
152 | * inserted. | 152 | * inserted. |
153 | */ | 153 | */ |
154 | int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | 154 | int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, |
155 | u64 start, u64 len) | 155 | u64 start, u64 len, int nocow) |
156 | { | 156 | { |
157 | struct btrfs_ordered_inode_tree *tree; | 157 | struct btrfs_ordered_inode_tree *tree; |
158 | struct rb_node *node; | 158 | struct rb_node *node; |
@@ -168,6 +168,8 @@ int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset, | |||
168 | entry->start = start; | 168 | entry->start = start; |
169 | entry->len = len; | 169 | entry->len = len; |
170 | entry->inode = inode; | 170 | entry->inode = inode; |
171 | if (nocow) | ||
172 | set_bit(BTRFS_ORDERED_NOCOW, &entry->flags); | ||
171 | 173 | ||
172 | /* one ref for the tree */ | 174 | /* one ref for the tree */ |
173 | atomic_set(&entry->refs, 1); | 175 | atomic_set(&entry->refs, 1); |
@@ -303,10 +305,11 @@ int btrfs_remove_ordered_extent(struct inode *inode, | |||
303 | return 0; | 305 | return 0; |
304 | } | 306 | } |
305 | 307 | ||
306 | int btrfs_wait_ordered_extents(struct btrfs_root *root) | 308 | int btrfs_wait_ordered_extents(struct btrfs_root *root, int nocow_only) |
307 | { | 309 | { |
308 | struct list_head splice; | 310 | struct list_head splice; |
309 | struct list_head *cur; | 311 | struct list_head *cur; |
312 | struct list_head *tmp; | ||
310 | struct btrfs_ordered_extent *ordered; | 313 | struct btrfs_ordered_extent *ordered; |
311 | struct inode *inode; | 314 | struct inode *inode; |
312 | 315 | ||
@@ -314,10 +317,16 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root) | |||
314 | 317 | ||
315 | spin_lock(&root->fs_info->ordered_extent_lock); | 318 | spin_lock(&root->fs_info->ordered_extent_lock); |
316 | list_splice_init(&root->fs_info->ordered_extents, &splice); | 319 | list_splice_init(&root->fs_info->ordered_extents, &splice); |
317 | while(!list_empty(&splice)) { | 320 | list_for_each_safe(cur, tmp, &splice) { |
318 | cur = splice.next; | 321 | cur = splice.next; |
319 | ordered = list_entry(cur, struct btrfs_ordered_extent, | 322 | ordered = list_entry(cur, struct btrfs_ordered_extent, |
320 | root_extent_list); | 323 | root_extent_list); |
324 | if (nocow_only && | ||
325 | !test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) { | ||
326 | cond_resched_lock(&root->fs_info->ordered_extent_lock); | ||
327 | continue; | ||
328 | } | ||
329 | |||
321 | list_del_init(&ordered->root_extent_list); | 330 | list_del_init(&ordered->root_extent_list); |
322 | atomic_inc(&ordered->refs); | 331 | atomic_inc(&ordered->refs); |
323 | inode = ordered->inode; | 332 | inode = ordered->inode; |
@@ -338,6 +347,7 @@ int btrfs_wait_ordered_extents(struct btrfs_root *root) | |||
338 | 347 | ||
339 | spin_lock(&root->fs_info->ordered_extent_lock); | 348 | spin_lock(&root->fs_info->ordered_extent_lock); |
340 | } | 349 | } |
350 | list_splice_init(&splice, &root->fs_info->ordered_extents); | ||
341 | spin_unlock(&root->fs_info->ordered_extent_lock); | 351 | spin_unlock(&root->fs_info->ordered_extent_lock); |
342 | return 0; | 352 | return 0; |
343 | } | 353 | } |