diff options
| -rw-r--r-- | fs/btrfs/ctree.h | 12 | ||||
| -rw-r--r-- | fs/btrfs/disk-io.c | 1 | ||||
| -rw-r--r-- | fs/btrfs/extent-tree.c | 17 | ||||
| -rw-r--r-- | fs/btrfs/inode.c | 117 | ||||
| -rw-r--r-- | fs/btrfs/ioctl.c | 35 | ||||
| -rw-r--r-- | fs/btrfs/qgroup.c | 5 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.c | 48 | ||||
| -rw-r--r-- | fs/btrfs/tree-log.h | 10 | ||||
| -rw-r--r-- | fs/btrfs/volumes.c | 7 |
9 files changed, 197 insertions, 55 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 53af9f5253f4..2cddfe7806a4 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
| @@ -1280,6 +1280,7 @@ struct btrfs_root { | |||
| 1280 | int send_in_progress; | 1280 | int send_in_progress; |
| 1281 | struct btrfs_subvolume_writers *subv_writers; | 1281 | struct btrfs_subvolume_writers *subv_writers; |
| 1282 | atomic_t will_be_snapshotted; | 1282 | atomic_t will_be_snapshotted; |
| 1283 | atomic_t snapshot_force_cow; | ||
| 1283 | 1284 | ||
| 1284 | /* For qgroup metadata reserved space */ | 1285 | /* For qgroup metadata reserved space */ |
| 1285 | spinlock_t qgroup_meta_rsv_lock; | 1286 | spinlock_t qgroup_meta_rsv_lock; |
| @@ -3390,9 +3391,9 @@ do { \ | |||
| 3390 | #define btrfs_debug(fs_info, fmt, args...) \ | 3391 | #define btrfs_debug(fs_info, fmt, args...) \ |
| 3391 | btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args) | 3392 | btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args) |
| 3392 | #define btrfs_debug_in_rcu(fs_info, fmt, args...) \ | 3393 | #define btrfs_debug_in_rcu(fs_info, fmt, args...) \ |
| 3393 | btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args) | 3394 | btrfs_no_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args) |
| 3394 | #define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \ | 3395 | #define btrfs_debug_rl_in_rcu(fs_info, fmt, args...) \ |
| 3395 | btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args) | 3396 | btrfs_no_printk_in_rcu(fs_info, KERN_DEBUG fmt, ##args) |
| 3396 | #define btrfs_debug_rl(fs_info, fmt, args...) \ | 3397 | #define btrfs_debug_rl(fs_info, fmt, args...) \ |
| 3397 | btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args) | 3398 | btrfs_no_printk(fs_info, KERN_DEBUG fmt, ##args) |
| 3398 | #endif | 3399 | #endif |
| @@ -3404,6 +3405,13 @@ do { \ | |||
| 3404 | rcu_read_unlock(); \ | 3405 | rcu_read_unlock(); \ |
| 3405 | } while (0) | 3406 | } while (0) |
| 3406 | 3407 | ||
| 3408 | #define btrfs_no_printk_in_rcu(fs_info, fmt, args...) \ | ||
| 3409 | do { \ | ||
| 3410 | rcu_read_lock(); \ | ||
| 3411 | btrfs_no_printk(fs_info, fmt, ##args); \ | ||
| 3412 | rcu_read_unlock(); \ | ||
| 3413 | } while (0) | ||
| 3414 | |||
| 3407 | #define btrfs_printk_ratelimited(fs_info, fmt, args...) \ | 3415 | #define btrfs_printk_ratelimited(fs_info, fmt, args...) \ |
| 3408 | do { \ | 3416 | do { \ |
| 3409 | static DEFINE_RATELIMIT_STATE(_rs, \ | 3417 | static DEFINE_RATELIMIT_STATE(_rs, \ |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 5124c15705ce..05dc3c17cb62 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
| @@ -1187,6 +1187,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info, | |||
| 1187 | atomic_set(&root->log_batch, 0); | 1187 | atomic_set(&root->log_batch, 0); |
| 1188 | refcount_set(&root->refs, 1); | 1188 | refcount_set(&root->refs, 1); |
| 1189 | atomic_set(&root->will_be_snapshotted, 0); | 1189 | atomic_set(&root->will_be_snapshotted, 0); |
| 1190 | atomic_set(&root->snapshot_force_cow, 0); | ||
| 1190 | root->log_transid = 0; | 1191 | root->log_transid = 0; |
| 1191 | root->log_transid_committed = -1; | 1192 | root->log_transid_committed = -1; |
| 1192 | root->last_log_commit = 0; | 1193 | root->last_log_commit = 0; |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index de6f75f5547b..2d9074295d7f 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
| @@ -5800,7 +5800,7 @@ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans) | |||
| 5800 | * root: the root of the parent directory | 5800 | * root: the root of the parent directory |
| 5801 | * rsv: block reservation | 5801 | * rsv: block reservation |
| 5802 | * items: the number of items that we need do reservation | 5802 | * items: the number of items that we need do reservation |
| 5803 | * qgroup_reserved: used to return the reserved size in qgroup | 5803 | * use_global_rsv: allow fallback to the global block reservation |
| 5804 | * | 5804 | * |
| 5805 | * This function is used to reserve the space for snapshot/subvolume | 5805 | * This function is used to reserve the space for snapshot/subvolume |
| 5806 | * creation and deletion. Those operations are different with the | 5806 | * creation and deletion. Those operations are different with the |
| @@ -5810,10 +5810,10 @@ void btrfs_trans_release_chunk_metadata(struct btrfs_trans_handle *trans) | |||
| 5810 | * the space reservation mechanism in start_transaction(). | 5810 | * the space reservation mechanism in start_transaction(). |
| 5811 | */ | 5811 | */ |
| 5812 | int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, | 5812 | int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, |
| 5813 | struct btrfs_block_rsv *rsv, | 5813 | struct btrfs_block_rsv *rsv, int items, |
| 5814 | int items, | ||
| 5815 | bool use_global_rsv) | 5814 | bool use_global_rsv) |
| 5816 | { | 5815 | { |
| 5816 | u64 qgroup_num_bytes = 0; | ||
| 5817 | u64 num_bytes; | 5817 | u64 num_bytes; |
| 5818 | int ret; | 5818 | int ret; |
| 5819 | struct btrfs_fs_info *fs_info = root->fs_info; | 5819 | struct btrfs_fs_info *fs_info = root->fs_info; |
| @@ -5821,12 +5821,11 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, | |||
| 5821 | 5821 | ||
| 5822 | if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) { | 5822 | if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags)) { |
| 5823 | /* One for parent inode, two for dir entries */ | 5823 | /* One for parent inode, two for dir entries */ |
| 5824 | num_bytes = 3 * fs_info->nodesize; | 5824 | qgroup_num_bytes = 3 * fs_info->nodesize; |
| 5825 | ret = btrfs_qgroup_reserve_meta_prealloc(root, num_bytes, true); | 5825 | ret = btrfs_qgroup_reserve_meta_prealloc(root, |
| 5826 | qgroup_num_bytes, true); | ||
| 5826 | if (ret) | 5827 | if (ret) |
| 5827 | return ret; | 5828 | return ret; |
| 5828 | } else { | ||
| 5829 | num_bytes = 0; | ||
| 5830 | } | 5829 | } |
| 5831 | 5830 | ||
| 5832 | num_bytes = btrfs_calc_trans_metadata_size(fs_info, items); | 5831 | num_bytes = btrfs_calc_trans_metadata_size(fs_info, items); |
| @@ -5838,8 +5837,8 @@ int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, | |||
| 5838 | if (ret == -ENOSPC && use_global_rsv) | 5837 | if (ret == -ENOSPC && use_global_rsv) |
| 5839 | ret = btrfs_block_rsv_migrate(global_rsv, rsv, num_bytes, 1); | 5838 | ret = btrfs_block_rsv_migrate(global_rsv, rsv, num_bytes, 1); |
| 5840 | 5839 | ||
| 5841 | if (ret && num_bytes) | 5840 | if (ret && qgroup_num_bytes) |
| 5842 | btrfs_qgroup_free_meta_prealloc(root, num_bytes); | 5841 | btrfs_qgroup_free_meta_prealloc(root, qgroup_num_bytes); |
| 5843 | 5842 | ||
| 5844 | return ret; | 5843 | return ret; |
| 5845 | } | 5844 | } |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 9357a19d2bff..3ea5339603cf 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
| @@ -1271,7 +1271,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, | |||
| 1271 | u64 disk_num_bytes; | 1271 | u64 disk_num_bytes; |
| 1272 | u64 ram_bytes; | 1272 | u64 ram_bytes; |
| 1273 | int extent_type; | 1273 | int extent_type; |
| 1274 | int ret, err; | 1274 | int ret; |
| 1275 | int type; | 1275 | int type; |
| 1276 | int nocow; | 1276 | int nocow; |
| 1277 | int check_prev = 1; | 1277 | int check_prev = 1; |
| @@ -1403,11 +1403,8 @@ next_slot: | |||
| 1403 | * if there are pending snapshots for this root, | 1403 | * if there are pending snapshots for this root, |
| 1404 | * we fall into common COW way. | 1404 | * we fall into common COW way. |
| 1405 | */ | 1405 | */ |
| 1406 | if (!nolock) { | 1406 | if (!nolock && atomic_read(&root->snapshot_force_cow)) |
| 1407 | err = btrfs_start_write_no_snapshotting(root); | 1407 | goto out_check; |
| 1408 | if (!err) | ||
| 1409 | goto out_check; | ||
| 1410 | } | ||
| 1411 | /* | 1408 | /* |
| 1412 | * force cow if csum exists in the range. | 1409 | * force cow if csum exists in the range. |
| 1413 | * this ensure that csum for a given extent are | 1410 | * this ensure that csum for a given extent are |
| @@ -1416,9 +1413,6 @@ next_slot: | |||
| 1416 | ret = csum_exist_in_range(fs_info, disk_bytenr, | 1413 | ret = csum_exist_in_range(fs_info, disk_bytenr, |
| 1417 | num_bytes); | 1414 | num_bytes); |
| 1418 | if (ret) { | 1415 | if (ret) { |
| 1419 | if (!nolock) | ||
| 1420 | btrfs_end_write_no_snapshotting(root); | ||
| 1421 | |||
| 1422 | /* | 1416 | /* |
| 1423 | * ret could be -EIO if the above fails to read | 1417 | * ret could be -EIO if the above fails to read |
| 1424 | * metadata. | 1418 | * metadata. |
| @@ -1431,11 +1425,8 @@ next_slot: | |||
| 1431 | WARN_ON_ONCE(nolock); | 1425 | WARN_ON_ONCE(nolock); |
| 1432 | goto out_check; | 1426 | goto out_check; |
| 1433 | } | 1427 | } |
| 1434 | if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) { | 1428 | if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) |
| 1435 | if (!nolock) | ||
| 1436 | btrfs_end_write_no_snapshotting(root); | ||
| 1437 | goto out_check; | 1429 | goto out_check; |
| 1438 | } | ||
| 1439 | nocow = 1; | 1430 | nocow = 1; |
| 1440 | } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { | 1431 | } else if (extent_type == BTRFS_FILE_EXTENT_INLINE) { |
| 1441 | extent_end = found_key.offset + | 1432 | extent_end = found_key.offset + |
| @@ -1448,8 +1439,6 @@ next_slot: | |||
| 1448 | out_check: | 1439 | out_check: |
| 1449 | if (extent_end <= start) { | 1440 | if (extent_end <= start) { |
| 1450 | path->slots[0]++; | 1441 | path->slots[0]++; |
| 1451 | if (!nolock && nocow) | ||
| 1452 | btrfs_end_write_no_snapshotting(root); | ||
| 1453 | if (nocow) | 1442 | if (nocow) |
| 1454 | btrfs_dec_nocow_writers(fs_info, disk_bytenr); | 1443 | btrfs_dec_nocow_writers(fs_info, disk_bytenr); |
| 1455 | goto next_slot; | 1444 | goto next_slot; |
| @@ -1471,8 +1460,6 @@ out_check: | |||
| 1471 | end, page_started, nr_written, 1, | 1460 | end, page_started, nr_written, 1, |
| 1472 | NULL); | 1461 | NULL); |
| 1473 | if (ret) { | 1462 | if (ret) { |
| 1474 | if (!nolock && nocow) | ||
| 1475 | btrfs_end_write_no_snapshotting(root); | ||
| 1476 | if (nocow) | 1463 | if (nocow) |
| 1477 | btrfs_dec_nocow_writers(fs_info, | ||
