| .. | .. |
|---|
| 77 | 77 | } |
|---|
| 78 | 78 | allowed &= flags; |
|---|
| 79 | 79 | |
|---|
| 80 | | - if (allowed & BTRFS_BLOCK_GROUP_RAID6) |
|---|
| 80 | + /* Select the highest-redundancy RAID level. */ |
|---|
| 81 | + if (allowed & BTRFS_BLOCK_GROUP_RAID1C4) |
|---|
| 82 | + allowed = BTRFS_BLOCK_GROUP_RAID1C4; |
|---|
| 83 | + else if (allowed & BTRFS_BLOCK_GROUP_RAID6) |
|---|
| 81 | 84 | allowed = BTRFS_BLOCK_GROUP_RAID6; |
|---|
| 85 | + else if (allowed & BTRFS_BLOCK_GROUP_RAID1C3) |
|---|
| 86 | + allowed = BTRFS_BLOCK_GROUP_RAID1C3; |
|---|
| 82 | 87 | else if (allowed & BTRFS_BLOCK_GROUP_RAID5) |
|---|
| 83 | 88 | allowed = BTRFS_BLOCK_GROUP_RAID5; |
|---|
| 84 | 89 | else if (allowed & BTRFS_BLOCK_GROUP_RAID10) |
|---|
| 85 | 90 | allowed = BTRFS_BLOCK_GROUP_RAID10; |
|---|
| 86 | 91 | else if (allowed & BTRFS_BLOCK_GROUP_RAID1) |
|---|
| 87 | 92 | allowed = BTRFS_BLOCK_GROUP_RAID1; |
|---|
| 93 | + else if (allowed & BTRFS_BLOCK_GROUP_DUP) |
|---|
| 94 | + allowed = BTRFS_BLOCK_GROUP_DUP; |
|---|
| 88 | 95 | else if (allowed & BTRFS_BLOCK_GROUP_RAID0) |
|---|
| 89 | 96 | allowed = BTRFS_BLOCK_GROUP_RAID0; |
|---|
| 90 | 97 | |
|---|
| .. | .. |
|---|
| 2279 | 2286 | } |
|---|
| 2280 | 2287 | |
|---|
| 2281 | 2288 | ret = inc_block_group_ro(cache, 0); |
|---|
| 2282 | | - if (!do_chunk_alloc || ret == -ETXTBSY) |
|---|
| 2283 | | - goto unlock_out; |
|---|
| 2284 | 2289 | if (!ret) |
|---|
| 2285 | 2290 | goto out; |
|---|
| 2291 | + if (ret == -ETXTBSY) |
|---|
| 2292 | + goto unlock_out; |
|---|
| 2293 | + |
|---|
| 2294 | + /* |
|---|
| 2295 | + * Skip chunk alloction if the bg is SYSTEM, this is to avoid system |
|---|
| 2296 | + * chunk allocation storm to exhaust the system chunk array. Otherwise |
|---|
| 2297 | + * we still want to try our best to mark the block group read-only. |
|---|
| 2298 | + */ |
|---|
| 2299 | + if (!do_chunk_alloc && ret == -ENOSPC && |
|---|
| 2300 | + (cache->flags & BTRFS_BLOCK_GROUP_SYSTEM)) |
|---|
| 2301 | + goto unlock_out; |
|---|
| 2302 | + |
|---|
| 2286 | 2303 | alloc_flags = btrfs_get_alloc_profile(fs_info, cache->space_info->flags); |
|---|
| 2287 | 2304 | ret = btrfs_chunk_alloc(trans, alloc_flags, CHUNK_ALLOC_FORCE); |
|---|
| 2288 | 2305 | if (ret < 0) |
|---|