Btrfs: use atomic for btrfs_fs_info->generation
Subsystems (2)
PATCH 1/11 Btrfs: use atomic for btrfs_fs_info->generation
fs_info->generation is a 64bit variant, we might get a wrong number on the 32bit machines if there is no lock or other methods to protect it.
Signed-off-by Zhao Lei <[email protected]>
Signed-off-by Miao Xie <[email protected]>
--- fs/btrfs/ctree.c | 7 ++++--- fs/btrfs/ctree.h | 2 +- fs/btrfs/disk-io.c | 8 ++++---- fs/btrfs/file.c | 6 ++++-- fs/btrfs/inode.c | 5 +++-- fs/btrfs/qgroup.c | 2 +- fs/btrfs/transaction.c | 4 ++-- include/trace/events/btrfs.h | 3 ++- 8 files changed, 21 insertions(+), 16 deletions(-)
fs/btrfs/ctree.c +4 -3
@@ -1365,10 +1365,11 @@ noinline int btrfs_cow_block(struct btrfs_trans_handle *trans, (unsigned long long ) root->fs_info->running_transaction->transid); -if (trans->transid != root->fs_info->generation) +if (trans->transid !=atomic64_read (&root->fs_info->generation))WARN (1 ,KERN_CRIT "trans %llu running %llu\n" , (unsigned long long )trans->transid, - (unsigned long long )root->fs_info->generation); + (unsigned long long )atomic64_read ( + &root->fs_info->generation));if (!should_cow_block (trans, root, buf)) { *cow_ret = buf;
@@ -1465,7 +1466,7 @@ int btrfs_realloc_node(struct btrfs_trans_handle *trans,return 0 ;WARN_ON (trans->transaction != root->fs_info->running_transaction); -WARN_ON (trans->transid != root->fs_info->generation); +WARN_ON (trans->transid !=atomic64_read (&root->fs_info->generation)); parent_nritems =btrfs_header_nritems (parent); blocksize =btrfs_level_size (root, parent_level -1 );
fs/btrfs/ctree.h +1 -1
@@ -1278,7 +1278,7 @@ struct btrfs_fs_info {struct btrfs_block_rsv empty_block_rsv; -u64 generation; +atomic64_t generation;u64 last_trans_committed;/*
fs/btrfs/disk-io.c +4 -4
@@ -1200,7 +1200,7 @@ static void __setup_root(u32 nodesize, u32 leafsize, u32 sectorsize,memset (&root->root_item,0 ,sizeof (root->root_item));memset (&root->defrag_progress,0 ,sizeof (root->defrag_progress));memset (&root->root_kobj,0 ,sizeof (root->root_kobj)); - root->defrag_trans_start = fs_info->generation; + root->defrag_trans_start =atomic64_read (&fs_info->generation);init_completion (&root->kobj_unregister); root->defrag_running =0 ; root->root_key.objectid = objectid;
@@ -2501,7 +2501,7 @@ retry_root_backup: fs_info->pending_quota_state =1 ; } - fs_info->generation = generation; +atomic64_set (&fs_info->generation, generation); fs_info->last_trans_committed = generation; ret =btrfs_recover_balance (fs_info);
@@ -3436,12 +3436,12 @@ void btrfs_mark_buffer_dirty(struct extent_buffer *buf)int was_dirty;btrfs_assert_tree_locked (buf); -if (transid != root->fs_info->generation) +if (transid !=atomic64_read (&root->fs_info->generation))WARN (1 ,KERN_CRIT "btrfs transid mismatch buffer %llu, " "found %llu running %llu\n" , (unsigned long long )buf->start, (unsigned long long )transid, - (unsigned long long )root->fs_info->generation); + (u64 )atomic64_read (&root->fs_info->generation)); was_dirty =set_extent_buffer_dirty (buf);if (!was_dirty) {spin_lock (&root->fs_info->delalloc_lock);
fs/btrfs/file.c +4 -2
@@ -1588,7 +1588,8 @@ static ssize_t btrfs_file_aio_write(struct kiocb *iocb,* otherwise subsequent syncs to a file that's been synced in this * transaction will appear to have already occured. */ -BTRFS_I (inode)->last_trans = root->fs_info->generation +1 ; +BTRFS_I (inode)->last_trans =atomic64_read (&root->fs_info->generation) + +1 ;BTRFS_I (inode)->last_sub_trans = root->log_transid;if (num_written >0 || num_written == -EIOCBQUEUED ) { err =generic_write_sync (file, pos, num_written);
@@ -1679,7 +1680,8 @@ int btrfs_sync_file(struct file *file, loff_t start, loff_t end, int datasync)* syncing */ smp_mb (); -if (btrfs_inode_in_log (inode, root->fs_info->generation) || +if (btrfs_inode_in_log (inode, +atomic64_read (&root->fs_info->generation)) ||BTRFS_I (inode)->last_trans <= root->fs_info->last_trans_committed) {BTRFS_I (inode)->last_trans =0 ;
fs/btrfs/inode.c +3 -2
@@ -2632,7 +2632,8 @@ static void btrfs_read_locked_inode(struct inode *inode)* idea about which extents were modified before we were evicted from * cache. */ -if (BTRFS_I (inode)->last_trans == root->fs_info->generation) +if (BTRFS_I (inode)->last_trans == +atomic64_read (&root->fs_info->generation))set_bit (BTRFS_INODE_NEEDS_FULL_SYNC , &BTRFS_I (inode)->runtime_flags);
@@ -6852,7 +6853,7 @@ again:set_page_dirty (page);SetPageUptodate (page); -BTRFS_I (inode)->last_trans = root->fs_info->generation; +BTRFS_I (inode)->last_trans =atomic64_read (&root->fs_info->generation);BTRFS_I (inode)->last_sub_trans =BTRFS_I (inode)->root->log_transid;BTRFS_I (inode)->last_log_commit =BTRFS_I (inode)->root->last_log_commit;
fs/btrfs/qgroup.c +1 -1
@@ -290,7 +290,7 @@ int btrfs_read_qgroup_config(struct btrfs_fs_info *fs_info) goto out; }if (btrfs_qgroup_status_generation (l, ptr) != - fs_info->generation) { +atomic64_read (&fs_info->generation)) { flags |=BTRFS_QGROUP_STATUS_FLAG_INCONSISTENT ;printk (KERN_ERR "btrfs: qgroup generation mismatch, "
fs/btrfs/transaction.c +2 -2
@@ -161,8 +161,8 @@ loop:list_add_tail (&cur_trans->list, &fs_info->trans_list);extent_io_tree_init (&cur_trans->dirty_pages, fs_info->btree_inode->i_mapping); - fs_info->generation++; - cur_trans->transid = fs_info->generation; +atomic64_inc (&fs_info->generation); + cur_trans->transid =atomic64_read (&fs_info->generation); fs_info->running_transaction = cur_trans; cur_trans->aborted =0 ;spin_unlock (&fs_info->trans_lock);
include/trace/events/btrfs.h +2 -1
@@ -71,7 +71,8 @@ TRACE_EVENT(btrfs_transaction_commit, ),TP_fast_assign ( - __entry->generation = root->fs_info->generation; + __entry->generation = + atomic64_read(&root->fs_info->generation); __entry->root_objectid = root->root_key.objectid; ),
Signature · 1 line
1.7.11.7