diff options
-rw-r--r-- | fs/btrfs/root-tree.c | 31 |
1 files changed, 29 insertions, 2 deletions
diff --git a/fs/btrfs/root-tree.c b/fs/btrfs/root-tree.c index 723a5312763f..ffb1036ef10d 100644 --- a/fs/btrfs/root-tree.c +++ b/fs/btrfs/root-tree.c | |||
@@ -228,6 +228,10 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root) | |||
228 | struct btrfs_root *root; | 228 | struct btrfs_root *root; |
229 | int err = 0; | 229 | int err = 0; |
230 | int ret; | 230 | int ret; |
231 | bool can_recover = true; | ||
232 | |||
233 | if (tree_root->fs_info->sb->s_flags & MS_RDONLY) | ||
234 | can_recover = false; | ||
231 | 235 | ||
232 | path = btrfs_alloc_path(); | 236 | path = btrfs_alloc_path(); |
233 | if (!path) | 237 | if (!path) |
@@ -268,9 +272,32 @@ int btrfs_find_orphan_roots(struct btrfs_root *tree_root) | |||
268 | key.offset++; | 272 | key.offset++; |
269 | 273 | ||
270 | root = btrfs_read_fs_root(tree_root, &root_key); | 274 | root = btrfs_read_fs_root(tree_root, &root_key); |
271 | if (IS_ERR(root)) { | 275 | err = PTR_RET(root); |
272 | err = PTR_ERR(root); | 276 | if (err && err != -ENOENT) { |
273 | break; | 277 | break; |
278 | } else if (err == -ENOENT) { | ||
279 | struct btrfs_trans_handle *trans; | ||
280 | |||
281 | btrfs_release_path(path); | ||
282 | |||
283 | trans = btrfs_join_transaction(tree_root); | ||
284 | if (IS_ERR(trans)) { | ||
285 | err = PTR_ERR(trans); | ||
286 | btrfs_error(tree_root->fs_info, err, | ||
287 | "Failed to start trans to delete " | ||
288 | "orphan item"); | ||
289 | break; | ||
290 | } | ||
291 | err = btrfs_del_orphan_item(trans, tree_root, | ||
292 | root_key.objectid); | ||
293 | btrfs_end_transaction(trans, tree_root); | ||
294 | if (err) { | ||
295 | btrfs_error(tree_root->fs_info, err, | ||
296 | "Failed to delete root orphan " | ||
297 | "item"); | ||
298 | break; | ||
299 | } | ||
300 | continue; | ||
274 | } | 301 | } |
275 | 302 | ||
276 | if (btrfs_root_refs(&root->root_item) == 0) { | 303 | if (btrfs_root_refs(&root->root_item) == 0) { |