Loading fs/btrfs/ctree.c +4 −1 Original line number Diff line number Diff line Loading @@ -1352,6 +1352,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root free_extent_buffer(tmp); goto again; } else { if (tmp) free_extent_buffer(tmp); b = read_node_slot(root, b, slot); } } Loading Loading @@ -3048,6 +3050,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) free_extent_buffer(c); path->nodes[level] = next; path->slots[level] = 0; if (!path->skip_locking) path->locks[level] = 1; if (!level) break; Loading fs/btrfs/ctree.h +4 −9 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ #include <linux/mm.h> #include <linux/highmem.h> #include <linux/fs.h> #include <linux/workqueue.h> #include <linux/completion.h> #include <linux/backing-dev.h> #include <asm/kmap_types.h> Loading Loading @@ -519,15 +518,14 @@ struct btrfs_fs_info { struct backing_dev_info bdi; spinlock_t hash_lock; struct mutex trans_mutex; struct mutex transaction_kthread_mutex; struct mutex cleaner_mutex; struct mutex alloc_mutex; struct mutex chunk_mutex; struct mutex drop_mutex; struct list_head trans_list; struct list_head hashers; struct list_head dead_roots; struct list_head end_io_work_list; struct work_struct end_io_work; spinlock_t end_io_work_lock; atomic_t nr_async_submits; /* Loading @@ -543,13 +541,10 @@ struct btrfs_fs_info { struct btrfs_workers workers; struct btrfs_workers endio_workers; struct btrfs_workers submit_workers; struct task_struct *transaction_kthread; struct task_struct *cleaner_kthread; int thread_pool_size; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) struct work_struct trans_work; #else struct delayed_work trans_work; #endif struct kobject super_kobj; struct completion kobj_unregister; int do_barriers; Loading fs/btrfs/disk-io.c +107 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ * Boston, MA 021110-1307, USA. */ #include <linux/version.h> #include <linux/fs.h> #include <linux/blkdev.h> #include <linux/scatterlist.h> Loading @@ -24,6 +25,12 @@ #include <linux/writeback.h> #include <linux/buffer_head.h> // for block_sync_page #include <linux/workqueue.h> #include <linux/kthread.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) # include <linux/freezer.h> #else # include <linux/sched.h> #endif #include "crc32c.h" #include "ctree.h" #include "disk-io.h" Loading Loading @@ -1100,6 +1107,87 @@ static void end_workqueue_fn(struct btrfs_work *work) #endif } static int cleaner_kthread(void *arg) { struct btrfs_root *root = arg; do { smp_mb(); if (root->fs_info->closing) break; vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); mutex_lock(&root->fs_info->cleaner_mutex); printk("cleaner awake\n"); btrfs_clean_old_snapshots(root); printk("cleaner done\n"); mutex_unlock(&root->fs_info->cleaner_mutex); if (freezing(current)) { refrigerator(); } else { smp_mb(); if (root->fs_info->closing) break; set_current_state(TASK_INTERRUPTIBLE); schedule(); __set_current_state(TASK_RUNNING); } } while (!kthread_should_stop()); return 0; } static int transaction_kthread(void *arg) { struct btrfs_root *root = arg; struct btrfs_trans_handle *trans; struct btrfs_transaction *cur; unsigned long now; unsigned long delay; int ret; do { smp_mb(); if (root->fs_info->closing) break; delay = HZ * 30; vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); mutex_lock(&root->fs_info->transaction_kthread_mutex); mutex_lock(&root->fs_info->trans_mutex); cur = root->fs_info->running_transaction; if (!cur) { mutex_unlock(&root->fs_info->trans_mutex); goto sleep; } now = get_seconds(); if (now < cur->start_time || now - cur->start_time < 30) { mutex_unlock(&root->fs_info->trans_mutex); delay = HZ * 5; goto sleep; } mutex_unlock(&root->fs_info->trans_mutex); btrfs_defrag_dirty_roots(root->fs_info); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); sleep: wake_up_process(root->fs_info->cleaner_kthread); mutex_unlock(&root->fs_info->transaction_kthread_mutex); if (freezing(current)) { refrigerator(); } else { if (root->fs_info->closing) break; set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(delay); __set_current_state(TASK_RUNNING); } } while (!kthread_should_stop()); return 0; } struct btrfs_root *open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices, char *options) Loading Loading @@ -1189,11 +1277,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, fs_info->btree_inode->i_mapping, GFP_NOFS); fs_info->do_barriers = 1; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) INIT_WORK(&fs_info->trans_work, btrfs_transaction_cleaner, fs_info); #else INIT_DELAYED_WORK(&fs_info->trans_work, btrfs_transaction_cleaner); #endif BTRFS_I(fs_info->btree_inode)->root = tree_root; memset(&BTRFS_I(fs_info->btree_inode)->location, 0, sizeof(struct btrfs_key)); Loading @@ -1204,6 +1287,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, mutex_init(&fs_info->drop_mutex); mutex_init(&fs_info->alloc_mutex); mutex_init(&fs_info->chunk_mutex); mutex_init(&fs_info->transaction_kthread_mutex); mutex_init(&fs_info->cleaner_mutex); #if 0 ret = add_hasher(fs_info, "crc32c"); Loading Loading @@ -1247,7 +1332,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, btrfs_start_workers(&fs_info->submit_workers, 1); btrfs_start_workers(&fs_info->endio_workers, fs_info->thread_pool_size); err = -EINVAL; if (btrfs_super_num_devices(disk_super) > fs_devices->open_devices) { printk("Btrfs: wanted %llu devices, but found %llu\n", Loading Loading @@ -1341,9 +1425,22 @@ struct btrfs_root *open_ctree(struct super_block *sb, fs_info->data_alloc_profile = (u64)-1; fs_info->metadata_alloc_profile = (u64)-1; fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, "btrfs-cleaner"); if (!fs_info->cleaner_kthread) goto fail_extent_root; fs_info->transaction_kthread = kthread_run(transaction_kthread, tree_root, "btrfs-transaction"); if (!fs_info->transaction_kthread) goto fail_trans_kthread; return tree_root; fail_trans_kthread: kthread_stop(fs_info->cleaner_kthread); fail_extent_root: free_extent_buffer(extent_root->node); fail_tree_root: Loading Loading @@ -1562,8 +1659,11 @@ int close_ctree(struct btrfs_root *root) fs_info->closing = 1; smp_mb(); btrfs_transaction_flush_work(root); kthread_stop(root->fs_info->transaction_kthread); kthread_stop(root->fs_info->cleaner_kthread); btrfs_defrag_dirty_roots(root->fs_info); btrfs_clean_old_snapshots(root); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); /* run commit again to drop the original snapshot */ Loading @@ -1574,8 +1674,6 @@ int close_ctree(struct btrfs_root *root) write_ctree_super(NULL, root); btrfs_transaction_flush_work(root); if (fs_info->delalloc_bytes) { printk("btrfs: at unmount delalloc count %Lu\n", fs_info->delalloc_bytes); Loading fs/btrfs/extent-tree.c +5 −5 Original line number Diff line number Diff line Loading @@ -1216,15 +1216,16 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, if (ret == -ENOSPC) { printk("space info full %Lu\n", flags); space_info->full = 1; goto out; goto out_unlock; } BUG_ON(ret); ret = btrfs_make_block_group(trans, extent_root, 0, flags, BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes); BUG_ON(ret); out: out_unlock: mutex_unlock(&extent_root->fs_info->chunk_mutex); out: return 0; } Loading Loading @@ -2274,6 +2275,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, free_extent_buffer(next); mutex_unlock(&root->fs_info->alloc_mutex); if (path->slots[*level] == 0) reada_walk_down(root, cur, path->slots[*level]); next = read_tree_block(root, bytenr, blocksize, Loading Loading @@ -2446,8 +2448,6 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root break; if (wret < 0) ret = wret; ret = -EAGAIN; break; } for (i = 0; i <= orig_level; i++) { if (path->nodes[i]) { Loading fs/btrfs/super.c +6 −10 Original line number Diff line number Diff line Loading @@ -340,7 +340,6 @@ static int btrfs_fill_super(struct super_block * sb, goto fail_close; sb->s_root = root_dentry; btrfs_transaction_queue_work(tree_root, HZ * 30); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) save_mount_options(sb, data); Loading Loading @@ -416,9 +415,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, goto error_free_subvol_name; bdev = fs_devices->latest_bdev; btrfs_lock_volumes(); s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices); btrfs_unlock_volumes(); if (IS_ERR(s)) goto error_s; Loading Loading @@ -530,13 +527,15 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, static void btrfs_write_super_lockfs(struct super_block *sb) { struct btrfs_root *root = btrfs_sb(sb); btrfs_transaction_flush_work(root); mutex_lock(&root->fs_info->transaction_kthread_mutex); mutex_lock(&root->fs_info->cleaner_mutex); } static void btrfs_unlockfs(struct super_block *sb) { struct btrfs_root *root = btrfs_sb(sb); btrfs_transaction_queue_work(root, HZ * 30); mutex_unlock(&root->fs_info->cleaner_mutex); mutex_unlock(&root->fs_info->transaction_kthread_mutex); } static struct super_operations btrfs_super_ops = { Loading Loading @@ -589,10 +588,9 @@ static int __init init_btrfs_fs(void) if (err) return err; btrfs_init_transaction_sys(); err = btrfs_init_cachep(); if (err) goto free_transaction_sys; goto free_sysfs; err = extent_io_init(); if (err) Loading @@ -618,15 +616,13 @@ static int __init init_btrfs_fs(void) extent_io_exit(); free_cachep: btrfs_destroy_cachep(); free_transaction_sys: btrfs_exit_transaction_sys(); free_sysfs: btrfs_exit_sysfs(); return err; } static void __exit exit_btrfs_fs(void) { btrfs_exit_transaction_sys(); btrfs_destroy_cachep(); extent_map_exit(); extent_io_exit(); Loading Loading
fs/btrfs/ctree.c +4 −1 Original line number Diff line number Diff line Loading @@ -1352,6 +1352,8 @@ int btrfs_search_slot(struct btrfs_trans_handle *trans, struct btrfs_root free_extent_buffer(tmp); goto again; } else { if (tmp) free_extent_buffer(tmp); b = read_node_slot(root, b, slot); } } Loading Loading @@ -3048,6 +3050,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path) free_extent_buffer(c); path->nodes[level] = next; path->slots[level] = 0; if (!path->skip_locking) path->locks[level] = 1; if (!level) break; Loading
fs/btrfs/ctree.h +4 −9 Original line number Diff line number Diff line Loading @@ -23,7 +23,6 @@ #include <linux/mm.h> #include <linux/highmem.h> #include <linux/fs.h> #include <linux/workqueue.h> #include <linux/completion.h> #include <linux/backing-dev.h> #include <asm/kmap_types.h> Loading Loading @@ -519,15 +518,14 @@ struct btrfs_fs_info { struct backing_dev_info bdi; spinlock_t hash_lock; struct mutex trans_mutex; struct mutex transaction_kthread_mutex; struct mutex cleaner_mutex; struct mutex alloc_mutex; struct mutex chunk_mutex; struct mutex drop_mutex; struct list_head trans_list; struct list_head hashers; struct list_head dead_roots; struct list_head end_io_work_list; struct work_struct end_io_work; spinlock_t end_io_work_lock; atomic_t nr_async_submits; /* Loading @@ -543,13 +541,10 @@ struct btrfs_fs_info { struct btrfs_workers workers; struct btrfs_workers endio_workers; struct btrfs_workers submit_workers; struct task_struct *transaction_kthread; struct task_struct *cleaner_kthread; int thread_pool_size; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) struct work_struct trans_work; #else struct delayed_work trans_work; #endif struct kobject super_kobj; struct completion kobj_unregister; int do_barriers; Loading
fs/btrfs/disk-io.c +107 −9 Original line number Diff line number Diff line Loading @@ -16,6 +16,7 @@ * Boston, MA 021110-1307, USA. */ #include <linux/version.h> #include <linux/fs.h> #include <linux/blkdev.h> #include <linux/scatterlist.h> Loading @@ -24,6 +25,12 @@ #include <linux/writeback.h> #include <linux/buffer_head.h> // for block_sync_page #include <linux/workqueue.h> #include <linux/kthread.h> #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,20) # include <linux/freezer.h> #else # include <linux/sched.h> #endif #include "crc32c.h" #include "ctree.h" #include "disk-io.h" Loading Loading @@ -1100,6 +1107,87 @@ static void end_workqueue_fn(struct btrfs_work *work) #endif } static int cleaner_kthread(void *arg) { struct btrfs_root *root = arg; do { smp_mb(); if (root->fs_info->closing) break; vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); mutex_lock(&root->fs_info->cleaner_mutex); printk("cleaner awake\n"); btrfs_clean_old_snapshots(root); printk("cleaner done\n"); mutex_unlock(&root->fs_info->cleaner_mutex); if (freezing(current)) { refrigerator(); } else { smp_mb(); if (root->fs_info->closing) break; set_current_state(TASK_INTERRUPTIBLE); schedule(); __set_current_state(TASK_RUNNING); } } while (!kthread_should_stop()); return 0; } static int transaction_kthread(void *arg) { struct btrfs_root *root = arg; struct btrfs_trans_handle *trans; struct btrfs_transaction *cur; unsigned long now; unsigned long delay; int ret; do { smp_mb(); if (root->fs_info->closing) break; delay = HZ * 30; vfs_check_frozen(root->fs_info->sb, SB_FREEZE_WRITE); mutex_lock(&root->fs_info->transaction_kthread_mutex); mutex_lock(&root->fs_info->trans_mutex); cur = root->fs_info->running_transaction; if (!cur) { mutex_unlock(&root->fs_info->trans_mutex); goto sleep; } now = get_seconds(); if (now < cur->start_time || now - cur->start_time < 30) { mutex_unlock(&root->fs_info->trans_mutex); delay = HZ * 5; goto sleep; } mutex_unlock(&root->fs_info->trans_mutex); btrfs_defrag_dirty_roots(root->fs_info); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); sleep: wake_up_process(root->fs_info->cleaner_kthread); mutex_unlock(&root->fs_info->transaction_kthread_mutex); if (freezing(current)) { refrigerator(); } else { if (root->fs_info->closing) break; set_current_state(TASK_INTERRUPTIBLE); schedule_timeout(delay); __set_current_state(TASK_RUNNING); } } while (!kthread_should_stop()); return 0; } struct btrfs_root *open_ctree(struct super_block *sb, struct btrfs_fs_devices *fs_devices, char *options) Loading Loading @@ -1189,11 +1277,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, fs_info->btree_inode->i_mapping, GFP_NOFS); fs_info->do_barriers = 1; #if LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,18) INIT_WORK(&fs_info->trans_work, btrfs_transaction_cleaner, fs_info); #else INIT_DELAYED_WORK(&fs_info->trans_work, btrfs_transaction_cleaner); #endif BTRFS_I(fs_info->btree_inode)->root = tree_root; memset(&BTRFS_I(fs_info->btree_inode)->location, 0, sizeof(struct btrfs_key)); Loading @@ -1204,6 +1287,8 @@ struct btrfs_root *open_ctree(struct super_block *sb, mutex_init(&fs_info->drop_mutex); mutex_init(&fs_info->alloc_mutex); mutex_init(&fs_info->chunk_mutex); mutex_init(&fs_info->transaction_kthread_mutex); mutex_init(&fs_info->cleaner_mutex); #if 0 ret = add_hasher(fs_info, "crc32c"); Loading Loading @@ -1247,7 +1332,6 @@ struct btrfs_root *open_ctree(struct super_block *sb, btrfs_start_workers(&fs_info->submit_workers, 1); btrfs_start_workers(&fs_info->endio_workers, fs_info->thread_pool_size); err = -EINVAL; if (btrfs_super_num_devices(disk_super) > fs_devices->open_devices) { printk("Btrfs: wanted %llu devices, but found %llu\n", Loading Loading @@ -1341,9 +1425,22 @@ struct btrfs_root *open_ctree(struct super_block *sb, fs_info->data_alloc_profile = (u64)-1; fs_info->metadata_alloc_profile = (u64)-1; fs_info->system_alloc_profile = fs_info->metadata_alloc_profile; fs_info->cleaner_kthread = kthread_run(cleaner_kthread, tree_root, "btrfs-cleaner"); if (!fs_info->cleaner_kthread) goto fail_extent_root; fs_info->transaction_kthread = kthread_run(transaction_kthread, tree_root, "btrfs-transaction"); if (!fs_info->transaction_kthread) goto fail_trans_kthread; return tree_root; fail_trans_kthread: kthread_stop(fs_info->cleaner_kthread); fail_extent_root: free_extent_buffer(extent_root->node); fail_tree_root: Loading Loading @@ -1562,8 +1659,11 @@ int close_ctree(struct btrfs_root *root) fs_info->closing = 1; smp_mb(); btrfs_transaction_flush_work(root); kthread_stop(root->fs_info->transaction_kthread); kthread_stop(root->fs_info->cleaner_kthread); btrfs_defrag_dirty_roots(root->fs_info); btrfs_clean_old_snapshots(root); trans = btrfs_start_transaction(root, 1); ret = btrfs_commit_transaction(trans, root); /* run commit again to drop the original snapshot */ Loading @@ -1574,8 +1674,6 @@ int close_ctree(struct btrfs_root *root) write_ctree_super(NULL, root); btrfs_transaction_flush_work(root); if (fs_info->delalloc_bytes) { printk("btrfs: at unmount delalloc count %Lu\n", fs_info->delalloc_bytes); Loading
fs/btrfs/extent-tree.c +5 −5 Original line number Diff line number Diff line Loading @@ -1216,15 +1216,16 @@ static int do_chunk_alloc(struct btrfs_trans_handle *trans, if (ret == -ENOSPC) { printk("space info full %Lu\n", flags); space_info->full = 1; goto out; goto out_unlock; } BUG_ON(ret); ret = btrfs_make_block_group(trans, extent_root, 0, flags, BTRFS_FIRST_CHUNK_TREE_OBJECTID, start, num_bytes); BUG_ON(ret); out: out_unlock: mutex_unlock(&extent_root->fs_info->chunk_mutex); out: return 0; } Loading Loading @@ -2274,6 +2275,7 @@ static int noinline walk_down_tree(struct btrfs_trans_handle *trans, free_extent_buffer(next); mutex_unlock(&root->fs_info->alloc_mutex); if (path->slots[*level] == 0) reada_walk_down(root, cur, path->slots[*level]); next = read_tree_block(root, bytenr, blocksize, Loading Loading @@ -2446,8 +2448,6 @@ int btrfs_drop_snapshot(struct btrfs_trans_handle *trans, struct btrfs_root break; if (wret < 0) ret = wret; ret = -EAGAIN; break; } for (i = 0; i <= orig_level; i++) { if (path->nodes[i]) { Loading
fs/btrfs/super.c +6 −10 Original line number Diff line number Diff line Loading @@ -340,7 +340,6 @@ static int btrfs_fill_super(struct super_block * sb, goto fail_close; sb->s_root = root_dentry; btrfs_transaction_queue_work(tree_root, HZ * 30); #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,25) save_mount_options(sb, data); Loading Loading @@ -416,9 +415,7 @@ static int btrfs_get_sb(struct file_system_type *fs_type, int flags, goto error_free_subvol_name; bdev = fs_devices->latest_bdev; btrfs_lock_volumes(); s = sget(fs_type, btrfs_test_super, set_anon_super, fs_devices); btrfs_unlock_volumes(); if (IS_ERR(s)) goto error_s; Loading Loading @@ -530,13 +527,15 @@ static long btrfs_control_ioctl(struct file *file, unsigned int cmd, static void btrfs_write_super_lockfs(struct super_block *sb) { struct btrfs_root *root = btrfs_sb(sb); btrfs_transaction_flush_work(root); mutex_lock(&root->fs_info->transaction_kthread_mutex); mutex_lock(&root->fs_info->cleaner_mutex); } static void btrfs_unlockfs(struct super_block *sb) { struct btrfs_root *root = btrfs_sb(sb); btrfs_transaction_queue_work(root, HZ * 30); mutex_unlock(&root->fs_info->cleaner_mutex); mutex_unlock(&root->fs_info->transaction_kthread_mutex); } static struct super_operations btrfs_super_ops = { Loading Loading @@ -589,10 +588,9 @@ static int __init init_btrfs_fs(void) if (err) return err; btrfs_init_transaction_sys(); err = btrfs_init_cachep(); if (err) goto free_transaction_sys; goto free_sysfs; err = extent_io_init(); if (err) Loading @@ -618,15 +616,13 @@ static int __init init_btrfs_fs(void) extent_io_exit(); free_cachep: btrfs_destroy_cachep(); free_transaction_sys: btrfs_exit_transaction_sys(); free_sysfs: btrfs_exit_sysfs(); return err; } static void __exit exit_btrfs_fs(void) { btrfs_exit_transaction_sys(); btrfs_destroy_cachep(); extent_map_exit(); extent_io_exit(); Loading