diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-23 14:14:10 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2015-05-23 14:14:10 -0400 |
commit | 7ce14f6ff26460819345fe8495cf2dd6538b7cdc (patch) | |
tree | 23fb69457c5f2c3b80aebf2a7351b57d87426c6d /fs/btrfs/backref.c | |
parent | cf539cbd8a81e12880735a0912de8b99f46c84fd (diff) | |
parent | 153c35b6cccc0c72de9fae06c8e2c8b2c47d79d4 (diff) |
Merge branch 'for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs fixes from Chris Mason:
"I fixed up a regression from 4.0 where conversion between different
raid levels would sometimes bail out without converting.
Filipe tracked down a race where it was possible to double allocate
chunks on the drive.
Mark has a fix for fiemap. All three will get bundled off for stable
as well"
* 'for-linus-4.1' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs:
Btrfs: fix regression in raid level conversion
Btrfs: fix racy system chunk allocation when setting block group ro
btrfs: clear 'ret' in btrfs_check_shared() loop
Diffstat (limited to 'fs/btrfs/backref.c')
-rw-r--r-- | fs/btrfs/backref.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 9de772ee0031..614aaa1969bd 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -880,6 +880,8 @@ static int __add_keyed_refs(struct btrfs_fs_info *fs_info, | |||
880 | * indirect refs to their parent bytenr. | 880 | * indirect refs to their parent bytenr. |
881 | * When roots are found, they're added to the roots list | 881 | * When roots are found, they're added to the roots list |
882 | * | 882 | * |
883 | * NOTE: This can return values > 0 | ||
884 | * | ||
883 | * FIXME some caching might speed things up | 885 | * FIXME some caching might speed things up |
884 | */ | 886 | */ |
885 | static int find_parent_nodes(struct btrfs_trans_handle *trans, | 887 | static int find_parent_nodes(struct btrfs_trans_handle *trans, |
@@ -1198,6 +1200,19 @@ int btrfs_find_all_roots(struct btrfs_trans_handle *trans, | |||
1198 | return ret; | 1200 | return ret; |
1199 | } | 1201 | } |
1200 | 1202 | ||
1203 | /** | ||
1204 | * btrfs_check_shared - tell us whether an extent is shared | ||
1205 | * | ||
1206 | * @trans: optional trans handle | ||
1207 | * | ||
1208 | * btrfs_check_shared uses the backref walking code but will short | ||
1209 | * circuit as soon as it finds a root or inode that doesn't match the | ||
1210 | * one passed in. This provides a significant performance benefit for | ||
1211 | * callers (such as fiemap) which want to know whether the extent is | ||
1212 | * shared but do not need a ref count. | ||
1213 | * | ||
1214 | * Return: 0 if extent is not shared, 1 if it is shared, < 0 on error. | ||
1215 | */ | ||
1201 | int btrfs_check_shared(struct btrfs_trans_handle *trans, | 1216 | int btrfs_check_shared(struct btrfs_trans_handle *trans, |
1202 | struct btrfs_fs_info *fs_info, u64 root_objectid, | 1217 | struct btrfs_fs_info *fs_info, u64 root_objectid, |
1203 | u64 inum, u64 bytenr) | 1218 | u64 inum, u64 bytenr) |
@@ -1226,11 +1241,13 @@ int btrfs_check_shared(struct btrfs_trans_handle *trans, | |||
1226 | ret = find_parent_nodes(trans, fs_info, bytenr, elem.seq, tmp, | 1241 | ret = find_parent_nodes(trans, fs_info, bytenr, elem.seq, tmp, |
1227 | roots, NULL, root_objectid, inum); | 1242 | roots, NULL, root_objectid, inum); |
1228 | if (ret == BACKREF_FOUND_SHARED) { | 1243 | if (ret == BACKREF_FOUND_SHARED) { |
1244 | /* this is the only condition under which we return 1 */ | ||
1229 | ret = 1; | 1245 | ret = 1; |
1230 | break; | 1246 | break; |
1231 | } | 1247 | } |
1232 | if (ret < 0 && ret != -ENOENT) | 1248 | if (ret < 0 && ret != -ENOENT) |
1233 | break; | 1249 | break; |
1250 | ret = 0; | ||
1234 | node = ulist_next(tmp, &uiter); | 1251 | node = ulist_next(tmp, &uiter); |
1235 | if (!node) | 1252 | if (!node) |
1236 | break; | 1253 | break; |