Loading fs/btrfs/extent-tree.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -762,6 +762,7 @@ struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, BUG_ON(ret); BUG_ON(ret); buf = btrfs_find_create_tree_block(root, ins.objectid); buf = btrfs_find_create_tree_block(root, ins.objectid); set_buffer_uptodate(buf); set_buffer_uptodate(buf); set_radix_bit(&trans->transaction->dirty_pages, buf->b_page->index); return buf; return buf; } } Loading fs/btrfs/super.c +0 −1 Original line number Original line Diff line number Diff line Loading @@ -980,7 +980,6 @@ static int btrfs_sync_fs(struct super_block *sb, int wait) filemap_flush(root->fs_info->btree_inode->i_mapping); filemap_flush(root->fs_info->btree_inode->i_mapping); return 0; return 0; } } filemap_write_and_wait(root->fs_info->btree_inode->i_mapping); mutex_lock(&root->fs_info->fs_mutex); mutex_lock(&root->fs_info->fs_mutex); trans = btrfs_start_transaction(root, 1); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); ret = btrfs_commit_transaction(trans, root); Loading fs/btrfs/transaction.c +35 −2 Original line number Original line Diff line number Diff line Loading @@ -45,6 +45,7 @@ static int join_transaction(struct btrfs_root *root) cur_trans->use_count = 1; cur_trans->use_count = 1; cur_trans->commit_done = 0; cur_trans->commit_done = 0; list_add_tail(&cur_trans->list, &root->fs_info->trans_list); list_add_tail(&cur_trans->list, &root->fs_info->trans_list); init_bit_radix(&cur_trans->dirty_pages); } } cur_trans->num_writers++; cur_trans->num_writers++; return 0; return 0; Loading Loading @@ -106,8 +107,40 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans, int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, struct btrfs_root *root) struct btrfs_root *root) { { filemap_write_and_wait(root->fs_info->btree_inode->i_mapping); unsigned long gang[16]; return 0; int ret; int i; int err; int werr = 0; struct page *page; struct radix_tree_root *dirty_pages; struct inode *btree_inode = root->fs_info->btree_inode; if (!trans || !trans->transaction) { return filemap_write_and_wait(btree_inode->i_mapping); } dirty_pages = &trans->transaction->dirty_pages; while(1) { ret = find_first_radix_bit(dirty_pages, gang, ARRAY_SIZE(gang)); if (!ret) break; for (i = 0; i < ret; i++) { /* FIXME EIO */ clear_radix_bit(dirty_pages, gang[i]); page = find_lock_page(btree_inode->i_mapping, gang[i]); if (!page) continue; err = write_one_page(page, 0); if (err) werr = err; page_cache_release(page); } } err = filemap_fdatawait(btree_inode->i_mapping); if (err) werr = err; return werr; } } int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, Loading fs/btrfs/transaction.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -9,6 +9,7 @@ struct btrfs_transaction { int commit_done; int commit_done; int magic; int magic; struct list_head list; struct list_head list; struct radix_tree_root dirty_pages; wait_queue_head_t writer_wait; wait_queue_head_t writer_wait; wait_queue_head_t commit_wait; wait_queue_head_t commit_wait; }; }; Loading Loading
fs/btrfs/extent-tree.c +1 −0 Original line number Original line Diff line number Diff line Loading @@ -762,6 +762,7 @@ struct buffer_head *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, BUG_ON(ret); BUG_ON(ret); buf = btrfs_find_create_tree_block(root, ins.objectid); buf = btrfs_find_create_tree_block(root, ins.objectid); set_buffer_uptodate(buf); set_buffer_uptodate(buf); set_radix_bit(&trans->transaction->dirty_pages, buf->b_page->index); return buf; return buf; } } Loading
fs/btrfs/super.c +0 −1 Original line number Original line Diff line number Diff line Loading @@ -980,7 +980,6 @@ static int btrfs_sync_fs(struct super_block *sb, int wait) filemap_flush(root->fs_info->btree_inode->i_mapping); filemap_flush(root->fs_info->btree_inode->i_mapping); return 0; return 0; } } filemap_write_and_wait(root->fs_info->btree_inode->i_mapping); mutex_lock(&root->fs_info->fs_mutex); mutex_lock(&root->fs_info->fs_mutex); trans = btrfs_start_transaction(root, 1); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); ret = btrfs_commit_transaction(trans, root); Loading
fs/btrfs/transaction.c +35 −2 Original line number Original line Diff line number Diff line Loading @@ -45,6 +45,7 @@ static int join_transaction(struct btrfs_root *root) cur_trans->use_count = 1; cur_trans->use_count = 1; cur_trans->commit_done = 0; cur_trans->commit_done = 0; list_add_tail(&cur_trans->list, &root->fs_info->trans_list); list_add_tail(&cur_trans->list, &root->fs_info->trans_list); init_bit_radix(&cur_trans->dirty_pages); } } cur_trans->num_writers++; cur_trans->num_writers++; return 0; return 0; Loading Loading @@ -106,8 +107,40 @@ int btrfs_end_transaction(struct btrfs_trans_handle *trans, int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, int btrfs_write_and_wait_transaction(struct btrfs_trans_handle *trans, struct btrfs_root *root) struct btrfs_root *root) { { filemap_write_and_wait(root->fs_info->btree_inode->i_mapping); unsigned long gang[16]; return 0; int ret; int i; int err; int werr = 0; struct page *page; struct radix_tree_root *dirty_pages; struct inode *btree_inode = root->fs_info->btree_inode; if (!trans || !trans->transaction) { return filemap_write_and_wait(btree_inode->i_mapping); } dirty_pages = &trans->transaction->dirty_pages; while(1) { ret = find_first_radix_bit(dirty_pages, gang, ARRAY_SIZE(gang)); if (!ret) break; for (i = 0; i < ret; i++) { /* FIXME EIO */ clear_radix_bit(dirty_pages, gang[i]); page = find_lock_page(btree_inode->i_mapping, gang[i]); if (!page) continue; err = write_one_page(page, 0); if (err) werr = err; page_cache_release(page); } } err = filemap_fdatawait(btree_inode->i_mapping); if (err) werr = err; return werr; } } int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, int btrfs_commit_tree_roots(struct btrfs_trans_handle *trans, Loading
fs/btrfs/transaction.h +1 −0 Original line number Original line Diff line number Diff line Loading @@ -9,6 +9,7 @@ struct btrfs_transaction { int commit_done; int commit_done; int magic; int magic; struct list_head list; struct list_head list; struct radix_tree_root dirty_pages; wait_queue_head_t writer_wait; wait_queue_head_t writer_wait; wait_queue_head_t commit_wait; wait_queue_head_t commit_wait; }; }; Loading