Loading fs/btrfs/ctree.h +3 −3 Original line number Diff line number Diff line Loading @@ -1258,7 +1258,7 @@ struct btrfs_root { */ int send_in_progress; struct btrfs_subvolume_writers *subv_writers; atomic_t will_be_snapshoted; atomic_t will_be_snapshotted; /* For qgroup metadata space reserve */ atomic64_t qgroup_meta_rsv; Loading Loading @@ -2773,8 +2773,8 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info); int btrfs_delayed_refs_qgroup_accounting(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int __get_raid_index(u64 flags); int btrfs_start_write_no_snapshoting(struct btrfs_root *root); void btrfs_end_write_no_snapshoting(struct btrfs_root *root); int btrfs_start_write_no_snapshotting(struct btrfs_root *root); void btrfs_end_write_no_snapshotting(struct btrfs_root *root); void btrfs_wait_for_snapshot_creation(struct btrfs_root *root); void check_system_chunk(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, const u64 type); Loading fs/btrfs/disk-io.c +1 −1 Original line number Diff line number Diff line Loading @@ -1343,7 +1343,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info, atomic_set(&root->log_batch, 0); atomic_set(&root->orphan_inodes, 0); refcount_set(&root->refs, 1); atomic_set(&root->will_be_snapshoted, 0); atomic_set(&root->will_be_snapshotted, 0); atomic64_set(&root->qgroup_meta_rsv, 0); root->log_transid = 0; root->log_transid_committed = -1; Loading fs/btrfs/extent-tree.c +11 −11 Original line number Diff line number Diff line Loading @@ -10989,14 +10989,14 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) } /* * btrfs_{start,end}_write_no_snapshoting() are similar to * btrfs_{start,end}_write_no_snapshotting() are similar to * mnt_{want,drop}_write(), they are used to prevent some tasks from writing * data into the page cache through nocow before the subvolume is snapshoted, * but flush the data into disk after the snapshot creation, or to prevent * operations while snapshoting is ongoing and that cause the snapshot to be * operations while snapshotting is ongoing and that cause the snapshot to be * inconsistent (writes followed by expanding truncates for example). */ void btrfs_end_write_no_snapshoting(struct btrfs_root *root) void btrfs_end_write_no_snapshotting(struct btrfs_root *root) { percpu_counter_dec(&root->subv_writers->counter); /* Loading @@ -11007,9 +11007,9 @@ void btrfs_end_write_no_snapshoting(struct btrfs_root *root) wake_up(&root->subv_writers->wait); } int btrfs_start_write_no_snapshoting(struct btrfs_root *root) int btrfs_start_write_no_snapshotting(struct btrfs_root *root) { if (atomic_read(&root->will_be_snapshoted)) if (atomic_read(&root->will_be_snapshotted)) return 0; percpu_counter_inc(&root->subv_writers->counter); Loading @@ -11017,14 +11017,14 @@ int btrfs_start_write_no_snapshoting(struct btrfs_root *root) * Make sure counter is updated before we check for snapshot creation. */ smp_mb(); if (atomic_read(&root->will_be_snapshoted)) { btrfs_end_write_no_snapshoting(root); if (atomic_read(&root->will_be_snapshotted)) { btrfs_end_write_no_snapshotting(root); return 0; } return 1; } static int wait_snapshoting_atomic_t(atomic_t *a) static int wait_snapshotting_atomic_t(atomic_t *a) { schedule(); return 0; Loading @@ -11035,11 +11035,11 @@ void btrfs_wait_for_snapshot_creation(struct btrfs_root *root) while (true) { int ret; ret = btrfs_start_write_no_snapshoting(root); ret = btrfs_start_write_no_snapshotting(root); if (ret) break; wait_on_atomic_t(&root->will_be_snapshoted, wait_snapshoting_atomic_t, wait_on_atomic_t(&root->will_be_snapshotted, wait_snapshotting_atomic_t, TASK_UNINTERRUPTIBLE); } } fs/btrfs/file.c +5 −5 Original line number Diff line number Diff line Loading @@ -1536,7 +1536,7 @@ static noinline int check_can_nocow(struct btrfs_inode *inode, loff_t pos, u64 num_bytes; int ret; ret = btrfs_start_write_no_snapshoting(root); ret = btrfs_start_write_no_snapshotting(root); if (!ret) return -ENOSPC; Loading @@ -1561,7 +1561,7 @@ static noinline int check_can_nocow(struct btrfs_inode *inode, loff_t pos, NULL, NULL, NULL); if (ret <= 0) { ret = 0; btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); } else { *write_bytes = min_t(size_t, *write_bytes , num_bytes - pos + lockstart); Loading Loading @@ -1664,7 +1664,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, data_reserved, pos, write_bytes); else btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); break; } Loading Loading @@ -1767,7 +1767,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, release_bytes = 0; if (only_release_metadata) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); if (only_release_metadata && copied > 0) { lockstart = round_down(pos, Loading Loading @@ -1797,7 +1797,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, if (release_bytes) { if (only_release_metadata) { btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); btrfs_delalloc_release_metadata(BTRFS_I(inode), release_bytes); } else { Loading fs/btrfs/inode.c +11 −11 Original line number Diff line number Diff line Loading @@ -1381,7 +1381,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, * we fall into common COW way. */ if (!nolock) { err = btrfs_start_write_no_snapshoting(root); err = btrfs_start_write_no_snapshotting(root); if (!err) goto out_check; } Loading @@ -1393,12 +1393,12 @@ static noinline int run_delalloc_nocow(struct inode *inode, if (csum_exist_in_range(fs_info, disk_bytenr, num_bytes)) { if (!nolock) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); goto out_check; } if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) { if (!nolock) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); goto out_check; } nocow = 1; Loading @@ -1415,7 +1415,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, if (extent_end <= start) { path->slots[0]++; if (!nolock && nocow) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); if (nocow) btrfs_dec_nocow_writers(fs_info, disk_bytenr); goto next_slot; Loading @@ -1438,7 +1438,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, NULL); if (ret) { if (!nolock && nocow) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); if (nocow) btrfs_dec_nocow_writers(fs_info, disk_bytenr); Loading @@ -1459,7 +1459,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, BTRFS_ORDERED_PREALLOC); if (IS_ERR(em)) { if (!nolock && nocow) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); if (nocow) btrfs_dec_nocow_writers(fs_info, disk_bytenr); Loading Loading @@ -1499,7 +1499,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, PAGE_UNLOCK | PAGE_SET_PRIVATE2); if (!nolock && nocow) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); cur_offset = extent_end; /* Loading Loading @@ -5053,7 +5053,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) if (newsize > oldsize) { /* * Don't do an expanding truncate while snapshoting is ongoing. * Don't do an expanding truncate while snapshotting is ongoing. * This is to ensure the snapshot captures a fully consistent * state of this file - if the snapshot captures this expanding * truncation, it must capture all writes that happened before Loading @@ -5062,13 +5062,13 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) btrfs_wait_for_snapshot_creation(root); ret = btrfs_cont_expand(inode, oldsize, newsize); if (ret) { btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); return ret; } trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); return PTR_ERR(trans); } Loading @@ -5076,7 +5076,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL); pagecache_isize_extended(inode, oldsize, newsize); ret = btrfs_update_inode(trans, root, inode); btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); btrfs_end_transaction(trans); } else { Loading Loading
fs/btrfs/ctree.h +3 −3 Original line number Diff line number Diff line Loading @@ -1258,7 +1258,7 @@ struct btrfs_root { */ int send_in_progress; struct btrfs_subvolume_writers *subv_writers; atomic_t will_be_snapshoted; atomic_t will_be_snapshotted; /* For qgroup metadata space reserve */ atomic64_t qgroup_meta_rsv; Loading Loading @@ -2773,8 +2773,8 @@ int btrfs_init_space_info(struct btrfs_fs_info *fs_info); int btrfs_delayed_refs_qgroup_accounting(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info); int __get_raid_index(u64 flags); int btrfs_start_write_no_snapshoting(struct btrfs_root *root); void btrfs_end_write_no_snapshoting(struct btrfs_root *root); int btrfs_start_write_no_snapshotting(struct btrfs_root *root); void btrfs_end_write_no_snapshotting(struct btrfs_root *root); void btrfs_wait_for_snapshot_creation(struct btrfs_root *root); void check_system_chunk(struct btrfs_trans_handle *trans, struct btrfs_fs_info *fs_info, const u64 type); Loading
fs/btrfs/disk-io.c +1 −1 Original line number Diff line number Diff line Loading @@ -1343,7 +1343,7 @@ static void __setup_root(struct btrfs_root *root, struct btrfs_fs_info *fs_info, atomic_set(&root->log_batch, 0); atomic_set(&root->orphan_inodes, 0); refcount_set(&root->refs, 1); atomic_set(&root->will_be_snapshoted, 0); atomic_set(&root->will_be_snapshotted, 0); atomic64_set(&root->qgroup_meta_rsv, 0); root->log_transid = 0; root->log_transid_committed = -1; Loading
fs/btrfs/extent-tree.c +11 −11 Original line number Diff line number Diff line Loading @@ -10989,14 +10989,14 @@ int btrfs_trim_fs(struct btrfs_fs_info *fs_info, struct fstrim_range *range) } /* * btrfs_{start,end}_write_no_snapshoting() are similar to * btrfs_{start,end}_write_no_snapshotting() are similar to * mnt_{want,drop}_write(), they are used to prevent some tasks from writing * data into the page cache through nocow before the subvolume is snapshoted, * but flush the data into disk after the snapshot creation, or to prevent * operations while snapshoting is ongoing and that cause the snapshot to be * operations while snapshotting is ongoing and that cause the snapshot to be * inconsistent (writes followed by expanding truncates for example). */ void btrfs_end_write_no_snapshoting(struct btrfs_root *root) void btrfs_end_write_no_snapshotting(struct btrfs_root *root) { percpu_counter_dec(&root->subv_writers->counter); /* Loading @@ -11007,9 +11007,9 @@ void btrfs_end_write_no_snapshoting(struct btrfs_root *root) wake_up(&root->subv_writers->wait); } int btrfs_start_write_no_snapshoting(struct btrfs_root *root) int btrfs_start_write_no_snapshotting(struct btrfs_root *root) { if (atomic_read(&root->will_be_snapshoted)) if (atomic_read(&root->will_be_snapshotted)) return 0; percpu_counter_inc(&root->subv_writers->counter); Loading @@ -11017,14 +11017,14 @@ int btrfs_start_write_no_snapshoting(struct btrfs_root *root) * Make sure counter is updated before we check for snapshot creation. */ smp_mb(); if (atomic_read(&root->will_be_snapshoted)) { btrfs_end_write_no_snapshoting(root); if (atomic_read(&root->will_be_snapshotted)) { btrfs_end_write_no_snapshotting(root); return 0; } return 1; } static int wait_snapshoting_atomic_t(atomic_t *a) static int wait_snapshotting_atomic_t(atomic_t *a) { schedule(); return 0; Loading @@ -11035,11 +11035,11 @@ void btrfs_wait_for_snapshot_creation(struct btrfs_root *root) while (true) { int ret; ret = btrfs_start_write_no_snapshoting(root); ret = btrfs_start_write_no_snapshotting(root); if (ret) break; wait_on_atomic_t(&root->will_be_snapshoted, wait_snapshoting_atomic_t, wait_on_atomic_t(&root->will_be_snapshotted, wait_snapshotting_atomic_t, TASK_UNINTERRUPTIBLE); } }
fs/btrfs/file.c +5 −5 Original line number Diff line number Diff line Loading @@ -1536,7 +1536,7 @@ static noinline int check_can_nocow(struct btrfs_inode *inode, loff_t pos, u64 num_bytes; int ret; ret = btrfs_start_write_no_snapshoting(root); ret = btrfs_start_write_no_snapshotting(root); if (!ret) return -ENOSPC; Loading @@ -1561,7 +1561,7 @@ static noinline int check_can_nocow(struct btrfs_inode *inode, loff_t pos, NULL, NULL, NULL); if (ret <= 0) { ret = 0; btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); } else { *write_bytes = min_t(size_t, *write_bytes , num_bytes - pos + lockstart); Loading Loading @@ -1664,7 +1664,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, data_reserved, pos, write_bytes); else btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); break; } Loading Loading @@ -1767,7 +1767,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, release_bytes = 0; if (only_release_metadata) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); if (only_release_metadata && copied > 0) { lockstart = round_down(pos, Loading Loading @@ -1797,7 +1797,7 @@ static noinline ssize_t __btrfs_buffered_write(struct file *file, if (release_bytes) { if (only_release_metadata) { btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); btrfs_delalloc_release_metadata(BTRFS_I(inode), release_bytes); } else { Loading
fs/btrfs/inode.c +11 −11 Original line number Diff line number Diff line Loading @@ -1381,7 +1381,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, * we fall into common COW way. */ if (!nolock) { err = btrfs_start_write_no_snapshoting(root); err = btrfs_start_write_no_snapshotting(root); if (!err) goto out_check; } Loading @@ -1393,12 +1393,12 @@ static noinline int run_delalloc_nocow(struct inode *inode, if (csum_exist_in_range(fs_info, disk_bytenr, num_bytes)) { if (!nolock) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); goto out_check; } if (!btrfs_inc_nocow_writers(fs_info, disk_bytenr)) { if (!nolock) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); goto out_check; } nocow = 1; Loading @@ -1415,7 +1415,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, if (extent_end <= start) { path->slots[0]++; if (!nolock && nocow) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); if (nocow) btrfs_dec_nocow_writers(fs_info, disk_bytenr); goto next_slot; Loading @@ -1438,7 +1438,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, NULL); if (ret) { if (!nolock && nocow) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); if (nocow) btrfs_dec_nocow_writers(fs_info, disk_bytenr); Loading @@ -1459,7 +1459,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, BTRFS_ORDERED_PREALLOC); if (IS_ERR(em)) { if (!nolock && nocow) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); if (nocow) btrfs_dec_nocow_writers(fs_info, disk_bytenr); Loading Loading @@ -1499,7 +1499,7 @@ static noinline int run_delalloc_nocow(struct inode *inode, PAGE_UNLOCK | PAGE_SET_PRIVATE2); if (!nolock && nocow) btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); cur_offset = extent_end; /* Loading Loading @@ -5053,7 +5053,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) if (newsize > oldsize) { /* * Don't do an expanding truncate while snapshoting is ongoing. * Don't do an expanding truncate while snapshotting is ongoing. * This is to ensure the snapshot captures a fully consistent * state of this file - if the snapshot captures this expanding * truncation, it must capture all writes that happened before Loading @@ -5062,13 +5062,13 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) btrfs_wait_for_snapshot_creation(root); ret = btrfs_cont_expand(inode, oldsize, newsize); if (ret) { btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); return ret; } trans = btrfs_start_transaction(root, 1); if (IS_ERR(trans)) { btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); return PTR_ERR(trans); } Loading @@ -5076,7 +5076,7 @@ static int btrfs_setsize(struct inode *inode, struct iattr *attr) btrfs_ordered_update_i_size(inode, i_size_read(inode), NULL); pagecache_isize_extended(inode, oldsize, newsize); ret = btrfs_update_inode(trans, root, inode); btrfs_end_write_no_snapshoting(root); btrfs_end_write_no_snapshotting(root); btrfs_end_transaction(trans); } else { Loading