aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/ctree.h12
-rw-r--r--fs/btrfs/disk-io.c1
-rw-r--r--fs/btrfs/extent-tree.c17
-rw-r--r--fs/btrfs/inode.c117
-rw-r--r--fs/btrfs/ioctl.c35
-rw-r--r--fs/btrfs/qgroup.c5
-rw-r--r--fs/btrfs/tree-log.c48
-rw-r--r--fs/btrfs/tree-log.h10
-rw-r--r--fs/btrfs/volumes.c7
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...) \
3409do { \
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...) \
3408do { \ 3416do { \
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 */
5812int btrfs_subvolume_reserve_metadata(struct btrfs_root *root, 5812int 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:
1448out_check: 1439out_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,