Commit b9834717 authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable

* git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable:
  Btrfs: BUG to BUG_ON changes
  Btrfs: remove dead code
  Btrfs: remove dead code
  Btrfs: fix typos in comments
  Btrfs: remove unused ftrace include
  Btrfs: fix __ucmpdi2 compile bug on 32 bit builds
  Btrfs: free inode struct when btrfs_new_inode fails
  Btrfs: fix race in worker_loop
  Btrfs: add flushoncommit mount option
  Btrfs: notreelog mount option
  Btrfs: introduce btrfs_show_options
  Btrfs: rework allocation clustering
  Btrfs: Optimize locking in btrfs_next_leaf()
  Btrfs: break up btrfs_search_slot into smaller pieces
  Btrfs: kill the pinned_mutex
  Btrfs: kill the block group alloc mutex
  Btrfs: clean up find_free_extent
  Btrfs: free space cache cleanups
  Btrfs: unplug in the async bio submission threads
  Btrfs: keep processing bios for a given bdev if our proc is batching
parents 5a3ae276 c293498b
...@@ -20,7 +20,6 @@ ...@@ -20,7 +20,6 @@
#include <linux/list.h> #include <linux/list.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
#include <linux/freezer.h> #include <linux/freezer.h>
#include <linux/ftrace.h>
#include "async-thread.h" #include "async-thread.h"
#define WORK_QUEUED_BIT 0 #define WORK_QUEUED_BIT 0
...@@ -195,6 +194,9 @@ static int worker_loop(void *arg) ...@@ -195,6 +194,9 @@ static int worker_loop(void *arg)
if (!list_empty(&worker->pending)) if (!list_empty(&worker->pending))
continue; continue;
if (kthread_should_stop())
break;
/* still no more work?, sleep for real */ /* still no more work?, sleep for real */
spin_lock_irq(&worker->lock); spin_lock_irq(&worker->lock);
set_current_state(TASK_INTERRUPTIBLE); set_current_state(TASK_INTERRUPTIBLE);
...@@ -208,7 +210,8 @@ static int worker_loop(void *arg) ...@@ -208,7 +210,8 @@ static int worker_loop(void *arg)
worker->working = 0; worker->working = 0;
spin_unlock_irq(&worker->lock); spin_unlock_irq(&worker->lock);
schedule(); if (!kthread_should_stop())
schedule();
} }
__set_current_state(TASK_RUNNING); __set_current_state(TASK_RUNNING);
} }
......
This diff is collapsed.
...@@ -143,12 +143,15 @@ static int btrfs_csum_sizes[] = { 4, 0 }; ...@@ -143,12 +143,15 @@ static int btrfs_csum_sizes[] = { 4, 0 };
#define BTRFS_FT_MAX 9 #define BTRFS_FT_MAX 9
/* /*
* the key defines the order in the tree, and so it also defines (optimal) * The key defines the order in the tree, and so it also defines (optimal)
* block layout. objectid corresonds to the inode number. The flags * block layout.
* tells us things about the object, and is a kind of stream selector. *
* so for a given inode, keys with flags of 1 might refer to the inode * objectid corresponds to the inode number.
* data, flags of 2 may point to file data in the btree and flags == 3 *
* may point to extents. * type tells us things about the object, and is a kind of stream selector.
* so for a given inode, keys with type of 1 might refer to the inode data,
* type of 2 may point to file data in the btree and type == 3 may point to
* extents.
* *
* offset is the starting byte offset for this key in the stream. * offset is the starting byte offset for this key in the stream.
* *
...@@ -200,7 +203,7 @@ struct btrfs_dev_item { ...@@ -200,7 +203,7 @@ struct btrfs_dev_item {
/* /*
* starting byte of this partition on the device, * starting byte of this partition on the device,
* to allowr for stripe alignment in the future * to allow for stripe alignment in the future
*/ */
__le64 start_offset; __le64 start_offset;
...@@ -633,18 +636,35 @@ struct btrfs_space_info { ...@@ -633,18 +636,35 @@ struct btrfs_space_info {
struct rw_semaphore groups_sem; struct rw_semaphore groups_sem;
}; };
struct btrfs_free_space { /*
struct rb_node bytes_index; * free clusters are used to claim free space in relatively large chunks,
struct rb_node offset_index; * allowing us to do less seeky writes. They are used for all metadata
u64 offset; * allocations and data allocations in ssd mode.
u64 bytes; */
struct btrfs_free_cluster {
spinlock_t lock;
spinlock_t refill_lock;
struct rb_root root;
/* largest extent in this cluster */
u64 max_size;
/* first extent starting offset */
u64 window_start;
struct btrfs_block_group_cache *block_group;
/*
* when a cluster is allocated from a block group, we put the
* cluster onto a list in the block group so that it can
* be freed before the block group is freed.
*/
struct list_head block_group_list;
}; };
struct btrfs_block_group_cache { struct btrfs_block_group_cache {
struct btrfs_key key; struct btrfs_key key;
struct btrfs_block_group_item item; struct btrfs_block_group_item item;
spinlock_t lock; spinlock_t lock;
struct mutex alloc_mutex;
struct mutex cache_mutex; struct mutex cache_mutex;
u64 pinned; u64 pinned;
u64 reserved; u64 reserved;
...@@ -656,6 +676,7 @@ struct btrfs_block_group_cache { ...@@ -656,6 +676,7 @@ struct btrfs_block_group_cache {
struct btrfs_space_info *space_info; struct btrfs_space_info *space_info;
/* free space cache stuff */ /* free space cache stuff */
spinlock_t tree_lock;
struct rb_root free_space_bytes; struct rb_root free_space_bytes;
struct rb_root free_space_offset; struct rb_root free_space_offset;
...@@ -667,6 +688,11 @@ struct btrfs_block_group_cache { ...@@ -667,6 +688,11 @@ struct btrfs_block_group_cache {
/* usage count */ /* usage count */
atomic_t count; atomic_t count;
/* List of struct btrfs_free_clusters for this block group.
* Today it will only have one thing on it, but that may change
*/
struct list_head cluster_list;
}; };
struct btrfs_leaf_ref_tree { struct btrfs_leaf_ref_tree {
...@@ -728,7 +754,6 @@ struct btrfs_fs_info { ...@@ -728,7 +754,6 @@ struct btrfs_fs_info {
struct mutex tree_log_mutex; struct mutex tree_log_mutex;
struct mutex transaction_kthread_mutex; struct mutex transaction_kthread_mutex;
struct mutex cleaner_mutex; struct mutex cleaner_mutex;
struct mutex pinned_mutex;
struct mutex chunk_mutex; struct mutex chunk_mutex;
struct mutex drop_mutex; struct mutex drop_mutex;
struct mutex volume_mutex; struct mutex volume_mutex;
...@@ -839,8 +864,12 @@ struct btrfs_fs_info { ...@@ -839,8 +864,12 @@ struct btrfs_fs_info {
spinlock_t delalloc_lock; spinlock_t delalloc_lock;
spinlock_t new_trans_lock; spinlock_t new_trans_lock;
u64 delalloc_bytes; u64 delalloc_bytes;
u64 last_alloc;
u64 last_data_alloc; /* data_alloc_cluster is only used in ssd mode */
struct btrfs_free_cluster data_alloc_cluster;
/* all metadata allocations go through this cluster */
struct btrfs_free_cluster meta_alloc_cluster;
spinlock_t ref_cache_lock; spinlock_t ref_cache_lock;
u64 total_ref_cache_size; u64 total_ref_cache_size;
...@@ -932,7 +961,6 @@ struct btrfs_root { ...@@ -932,7 +961,6 @@ struct btrfs_root {
}; };
/* /*
* inode items have the data typically returned from stat and store other * inode items have the data typically returned from stat and store other
* info about object characteristics. There is one for every file and dir in * info about object characteristics. There is one for every file and dir in
* the FS * the FS
...@@ -963,7 +991,7 @@ struct btrfs_root { ...@@ -963,7 +991,7 @@ struct btrfs_root {
#define BTRFS_EXTENT_CSUM_KEY 128 #define BTRFS_EXTENT_CSUM_KEY 128
/* /*
* root items point to tree roots. There are typically in the root * root items point to tree roots. They are typically in the root
* tree used by the super block to find all the other trees * tree used by the super block to find all the other trees
*/ */
#define BTRFS_ROOT_ITEM_KEY 132 #define BTRFS_ROOT_ITEM_KEY 132
...@@ -1010,6 +1038,8 @@ struct btrfs_root { ...@@ -1010,6 +1038,8 @@ struct btrfs_root {
#define BTRFS_MOUNT_SSD (1 << 3) #define BTRFS_MOUNT_SSD (1 << 3)
#define BTRFS_MOUNT_DEGRADED (1 << 4) #define BTRFS_MOUNT_DEGRADED (1 << 4)
#define BTRFS_MOUNT_COMPRESS (1 << 5) #define BTRFS_MOUNT_COMPRESS (1 << 5)
#define BTRFS_MOUNT_NOTREELOG (1 << 6)
#define BTRFS_MOUNT_FLUSHONCOMMIT (1 << 7)
#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt) #define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt) #define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
...@@ -1748,6 +1778,7 @@ static inline struct dentry *fdentry(struct file *file) ...@@ -1748,6 +1778,7 @@ static inline struct dentry *fdentry(struct file *file)
} }
/* extent-tree.c */ /* extent-tree.c */
void btrfs_put_block_group(struct btrfs_block_group_cache *cache);
int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
struct btrfs_root *root, unsigned long count); struct btrfs_root *root, unsigned long count);
int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len); int btrfs_lookup_extent(struct btrfs_root *root, u64 start, u64 len);
...@@ -2174,21 +2205,4 @@ int btrfs_check_acl(struct inode *inode, int mask); ...@@ -2174,21 +2205,4 @@ int btrfs_check_acl(struct inode *inode, int mask);
int btrfs_init_acl(struct inode *inode, struct inode *dir); int btrfs_init_acl(struct inode *inode, struct inode *dir);
int btrfs_acl_chmod(struct inode *inode); int btrfs_acl_chmod(struct inode *inode);
/* free-space-cache.c */
int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
u64 bytenr, u64 size);
int btrfs_add_free_space_lock(struct btrfs_block_group_cache *block_group,
u64 offset, u64 bytes);
int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
u64 bytenr, u64 size);
int btrfs_remove_free_space_lock(struct btrfs_block_group_cache *block_group,
u64 offset, u64 bytes);
void btrfs_remove_free_space_cache(struct btrfs_block_group_cache
*block_group);
struct btrfs_free_space *btrfs_find_free_space(struct btrfs_block_group_cache
*block_group, u64 offset,
u64 bytes);
void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
u64 bytes);
u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group);
#endif #endif
...@@ -18,7 +18,6 @@ ...@@ -18,7 +18,6 @@
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sort.h> #include <linux/sort.h>
#include <linux/ftrace.h>
#include "ctree.h" #include "ctree.h"
#include "delayed-ref.h" #include "delayed-ref.h"
#include "transaction.h" #include "transaction.h"
......
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include "locking.h" #include "locking.h"
#include "ref-cache.h" #include "ref-cache.h"
#include "tree-log.h" #include "tree-log.h"
#include "free-space-cache.h"
static struct extent_io_ops btree_extent_io_ops; static struct extent_io_ops btree_extent_io_ops;
static void end_workqueue_fn(struct btrfs_work *work); static void end_workqueue_fn(struct btrfs_work *work);
...@@ -1412,8 +1413,6 @@ static int bio_ready_for_csum(struct bio *bio) ...@@ -1412,8 +1413,6 @@ static int bio_ready_for_csum(struct bio *bio)
ret = extent_range_uptodate(io_tree, start + length, ret = extent_range_uptodate(io_tree, start + length,
start + buf_len - 1); start + buf_len - 1);
if (ret == 1)
return ret;
return ret; return ret;
} }
...@@ -1647,12 +1646,15 @@ struct btrfs_root *open_ctree(struct super_block *sb, ...@@ -1647,12 +1646,15 @@ struct btrfs_root *open_ctree(struct super_block *sb,
mutex_init(&fs_info->ordered_operations_mutex); mutex_init(&fs_info->ordered_operations_mutex);
mutex_init(&fs_info->tree_log_mutex); mutex_init(&fs_info->tree_log_mutex);
mutex_init(&fs_info->drop_mutex); mutex_init(&fs_info->drop_mutex);
mutex_init(&fs_info->pinned_mutex);
mutex_init(&fs_info->chunk_mutex); mutex_init(&fs_info->chunk_mutex);
mutex_init(&fs_info->transaction_kthread_mutex); mutex_init(&fs_info->transaction_kthread_mutex);
mutex_init(&fs_info->cleaner_mutex); mutex_init(&fs_info->cleaner_mutex);
mutex_init(&fs_info->volume_mutex); mutex_init(&fs_info->volume_mutex);
mutex_init(&fs_info->tree_reloc_mutex); mutex_init(&fs_info->tree_reloc_mutex);
btrfs_init_free_cluster(&fs_info->meta_alloc_cluster);
btrfs_init_free_cluster(&fs_info->data_alloc_cluster);
init_waitqueue_head(&fs_info->transaction_throttle); init_waitqueue_head(&fs_info->transaction_throttle);
init_waitqueue_head(&fs_info->transaction_wait); init_waitqueue_head(&fs_info->transaction_wait);
init_waitqueue_head(&fs_info->async_submit_wait); init_waitqueue_head(&fs_info->async_submit_wait);
......
This diff is collapsed.
...@@ -2884,25 +2884,19 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo, ...@@ -2884,25 +2884,19 @@ int extent_fiemap(struct inode *inode, struct fiemap_extent_info *fieinfo,
disko = 0; disko = 0;
flags = 0; flags = 0;
switch (em->block_start) { if (em->block_start == EXTENT_MAP_LAST_BYTE) {
case EXTENT_MAP_LAST_BYTE:
end = 1; end = 1;
flags |= FIEMAP_EXTENT_LAST; flags |= FIEMAP_EXTENT_LAST;
break; } else if (em->block_start == EXTENT_MAP_HOLE) {
case EXTENT_MAP_HOLE:
flags |= FIEMAP_EXTENT_UNWRITTEN; flags |= FIEMAP_EXTENT_UNWRITTEN;
break; } else if (em->block_start == EXTENT_MAP_INLINE) {
case EXTENT_MAP_INLINE:
flags |= (FIEMAP_EXTENT_DATA_INLINE | flags |= (FIEMAP_EXTENT_DATA_INLINE |
FIEMAP_EXTENT_NOT_ALIGNED); FIEMAP_EXTENT_NOT_ALIGNED);
break; } else if (em->block_start == EXTENT_MAP_DELALLOC) {
case EXTENT_MAP_DELALLOC:
flags |= (FIEMAP_EXTENT_DELALLOC | flags |= (FIEMAP_EXTENT_DELALLOC |
FIEMAP_EXTENT_UNKNOWN); FIEMAP_EXTENT_UNKNOWN);
break; } else {
default:
disko = em->block_start; disko = em->block_start;
break;
} }
if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) if (test_bit(EXTENT_FLAG_COMPRESSED, &em->flags))
flags |= FIEMAP_EXTENT_ENCODED; flags |= FIEMAP_EXTENT_ENCODED;
......
...@@ -234,7 +234,6 @@ int add_extent_mapping(struct extent_map_tree *tree, ...@@ -234,7 +234,6 @@ int add_extent_mapping(struct extent_map_tree *tree,
rb = tree_insert(&tree->map, em->start, &em->rb_node); rb = tree_insert(&tree->map, em->start, &em->rb_node);
if (rb) { if (rb) {
ret = -EEXIST; ret = -EEXIST;
free_extent_map(merge);
goto out; goto out;
} }
atomic_inc(&em->refs); atomic_inc(&em->refs);
......
This diff is collapsed.
/*
* Copyright (C) 2009 Oracle. All rights reserved.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License v2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 021110-1307, USA.
*/
#ifndef __BTRFS_FREE_SPACE_CACHE
#define __BTRFS_FREE_SPACE_CACHE
int btrfs_add_free_space(struct btrfs_block_group_cache *block_group,
u64 bytenr, u64 size);
int btrfs_remove_free_space(struct btrfs_block_group_cache *block_group,
u64 bytenr, u64 size);
void btrfs_remove_free_space_cache(struct btrfs_block_group_cache
*block_group);
u64 btrfs_find_space_for_alloc(struct btrfs_block_group_cache *block_group,
u64 offset, u64 bytes, u64 empty_size);
void btrfs_dump_free_space(struct btrfs_block_group_cache *block_group,
u64 bytes);
u64 btrfs_block_group_free_space(struct btrfs_block_group_cache *block_group);
int btrfs_find_space_cluster(struct btrfs_trans_handle *trans,
struct btrfs_block_group_cache *block_group,
struct btrfs_free_cluster *cluster,
u64 offset, u64 bytes, u64 empty_size);
void btrfs_init_free_cluster(struct btrfs_free_cluster *cluster);
u64 btrfs_alloc_from_cluster(struct btrfs_block_group_cache *block_group,
struct btrfs_free_cluster *cluster, u64 bytes,
u64 min_start);
int btrfs_return_cluster_to_free_space(
struct btrfs_block_group_cache *block_group,
struct btrfs_free_cluster *cluster);
#endif
...@@ -3481,8 +3481,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, ...@@ -3481,8 +3481,10 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
if (dir) { if (dir) {
ret = btrfs_set_inode_index(dir, index); ret = btrfs_set_inode_index(dir, index);
if (ret) if (ret) {
iput(inode);
return ERR_PTR(ret); return ERR_PTR(ret);
}
} }
/* /*
* index_cnt is ignored for everything but a dir, * index_cnt is ignored for everything but a dir,
...@@ -3565,6 +3567,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans, ...@@ -3565,6 +3567,7 @@ static struct inode *btrfs_new_inode(struct btrfs_trans_handle *trans,
if (dir) if (dir)
BTRFS_I(dir)->index_cnt--; BTRFS_I(dir)->index_cnt--;
btrfs_free_path(path); btrfs_free_path(path);
iput(inode);
return ERR_PTR(ret); return ERR_PTR(ret);
} }
......
...@@ -60,8 +60,8 @@ void btrfs_clear_lock_blocking(struct extent_buffer *eb) ...@@ -60,8 +60,8 @@ void btrfs_clear_lock_blocking(struct extent_buffer *eb)
/* /*
* unfortunately, many of the places that currently set a lock to blocking * unfortunately, many of the places that currently set a lock to blocking
* don't end up blocking for every long, and often they don't block * don't end up blocking for very long, and often they don't block
* at all. For a dbench 50 run, if we don't spin one the blocking bit * at all. For a dbench 50 run, if we don't spin on the blocking bit
* at all, the context switch rate can jump up to 400,000/sec or more. * at all, the context switch rate can jump up to 400,000/sec or more.
* *
* So, we're still stuck with this crummy spin on the blocking bit, * So, we're still stuck with this crummy spin on the blocking bit,
......
...@@ -24,6 +24,7 @@ ...@@ -24,6 +24,7 @@
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/time.h> #include <linux/time.h>
#include <linux/init.h> #include <linux/init.h>
#include <linux/seq_file.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/backing-dev.h> #include <linux/backing-dev.h>
...@@ -66,7 +67,8 @@ static void btrfs_put_super(struct super_block *sb) ...@@ -66,7 +67,8 @@ static void btrfs_put_super(struct super_block *sb)
enum { enum {
Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow, Opt_degraded, Opt_subvol, Opt_device, Opt_nodatasum, Opt_nodatacow,
Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier, Opt_max_extent, Opt_max_inline, Opt_alloc_start, Opt_nobarrier,
Opt_ssd, Opt_thread_pool, Opt_noacl, Opt_compress, Opt_err, Opt_ssd, Opt_thread_pool, Opt_noacl, Opt_compress, Opt_notreelog,
Opt_flushoncommit, Opt_err,
}; };
static match_table_t tokens = { static match_table_t tokens = {
...@@ -83,6 +85,8 @@ static match_table_t tokens = { ...@@ -83,6 +85,8 @@ static match_table_t tokens = {
{Opt_compress, "compress"}, {Opt_compress, "compress"},
{Opt_ssd, "ssd"}, {Opt_ssd, "ssd"},
{Opt_noacl, "noacl"}, {Opt_noacl, "noacl"},
{Opt_notreelog, "notreelog"},
{Opt_flushoncommit, "flushoncommit"},
{Opt_err, NULL}, {Opt_err, NULL},
}; };
...@@ -222,6 +226,14 @@ int btrfs_parse_options(struct btrfs_root *root, char *options) ...@@ -222,6 +226,14 @@ int btrfs_parse_options(struct btrfs_root *root, char *options)
case Opt_noacl: case Opt_noacl:
root->fs_info->sb->s_flags &= ~MS_POSIXACL; root->fs_info->sb->s_flags &= ~MS_POSIXACL;
break; break;
case Opt_notreelog:
printk(KERN_INFO "btrfs: disabling tree log\n");
btrfs_set_opt(info->mount_opt, NOTREELOG);
break;
case Opt_flushoncommit:
printk(KERN_INFO "btrfs: turning on flush-on-commit\n");
btrfs_set_opt(info->mount_opt, FLUSHONCOMMIT);
break;
default: default:
break; break;
} }
...@@ -363,9 +375,8 @@ static int btrfs_fill_super(struct super_block *sb, ...@@ -363,9 +375,8 @@ static int btrfs_fill_super(struct super_block *sb,
int btrfs_sync_fs(struct super_block *sb, int wait) int btrfs_sync_fs(struct super_block *sb, int wait)
{ {
struct btrfs_trans_handle *trans; struct btrfs_trans_handle *trans;
struct btrfs_root *root; struct btrfs_root *root = btrfs_sb(sb);
int ret; int ret;
root = btrfs_sb(sb);
if (sb->s_flags & MS_RDONLY) if (sb->s_flags & MS_RDONLY)
return 0; return 0;
...@@ -385,6 +396,41 @@ int btrfs_sync_fs(struct super_block *sb, int wait) ...@@ -385,6 +396,41 @@ int btrfs_sync_fs(struct super_block *sb, int wait)
return ret; return ret;
} }
static int btrfs_show_options(struct seq_file *seq, struct vfsmount *vfs)
{
struct btrfs_root *root = btrfs_sb(vfs->mnt_sb);
struct btrfs_fs_info *info = root->fs_info;
if (btrfs_test_opt(root, DEGRADED))
seq_puts(seq, ",degraded");
if (btrfs_test_opt(root, NODATASUM))
seq_puts(seq, ",nodatasum");
if (btrfs_test_opt(root, NODATACOW))
seq_puts(seq, ",nodatacow");
if (btrfs_test_opt(root, NOBARRIER))
seq_puts(seq, ",nobarrier");
if (info->max_extent != (u64)-1)
seq_printf(seq, ",max_extent=%llu", info->max_extent);
if (info->max_inline != 8192 * 1024)
seq_printf(seq, ",max_inline=%llu", info->max_inline);
if (info->alloc_start != 0)
seq_printf(seq, ",alloc_start=%llu", info->alloc_start);
if (info->thread_pool_size != min_t(unsigned long,
num_online_cpus() + 2, 8))
seq_printf(seq, ",thread_pool=%d", info->thread_pool_size);
if (btrfs_test_opt(root, COMPRESS))
seq_puts(seq, ",compress");
if (btrfs_test_opt(root, SSD))
seq_puts(seq, ",ssd");
if (btrfs_test_opt(root, NOTREELOG))
seq_puts(seq, ",no-treelog");
if (btrfs_test_opt(root, FLUSHONCOMMIT))
seq_puts(seq, ",flush-on-commit");
if (!(root->fs_info->sb->s_flags & MS_POSIXACL))
seq_puts(seq, ",noacl");
return 0;
}
static void btrfs_write_super(struct super_block *sb) static void btrfs_write_super(struct super_block *sb)
{ {
sb->s_dirt = 0; sb->s_dirt = 0;
...@@ -630,7 +676,7 @@ static struct super_operations btrfs_super_ops = { ...@@ -630,7 +676,7 @@ static struct super_operations btrfs_super_ops = {
.put_super = btrfs_put_super, .put_super = btrfs_put_super,
.write_super = btrfs_write_super, .write_super = btrfs_write_super,
.sync_fs = btrfs_sync_fs, .sync_fs = btrfs_sync_fs,
.show_options = generic_show_options, .show_options = btrfs_show_options,
.write_inode = btrfs_write_inode, .write_inode = btrfs_write_inode,
.dirty_inode = btrfs_dirty_inode, .dirty_inode = btrfs_dirty_inode,
.alloc_inode = btrfs_alloc_inode, .alloc_inode = btrfs_alloc_inode,
......
...@@ -53,8 +53,6 @@ static noinline int join_transaction(struct btrfs_root *root) ...@@ -53,8 +53,6 @@ static noinline int join_transaction(struct btrfs_root *root)
GFP_NOFS); GFP_NOFS);
BUG_ON(!cur_trans); BUG_ON(!cur_trans);
root->fs_info->generation++; root->fs_info->generation++;
root->fs_info->last_alloc = 0;
root->fs_info->last_data_alloc = 0;
cur_trans->num_writers = 1; cur_trans->num_writers = 1;
cur_trans->num_joined = 0; cur_trans->num_joined = 0;
cur_trans->transid = root->fs_info->generation; cur_trans->transid = root->fs_info->generation;
...@@ -974,6 +972,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, ...@@ -974,6 +972,7 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
int ret; int ret;
int should_grow = 0; int should_grow = 0;
unsigned long now = get_seconds(); unsigned long now = get_seconds();
int flush_on_commit = btrfs_test_opt(root, FLUSHONCOMMIT);
btrfs_run_ordered_operations(root, 0); btrfs_run_ordered_operations(root, 0);
...@@ -1053,7 +1052,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans, ...@@ -1053,7 +1052,9 @@ int btrfs_commit_transaction(struct btrfs_trans_handle *trans,
mutex_unlock(&root->fs_info->trans_mutex); mutex_unlock(&root->fs_info->trans_mutex);
if (snap_pending) { if (flush_on_commit || snap_pending) {
if (flush_on_commit)
btrfs_start_delalloc_inodes(root);
ret = btrfs_wait_ordered_extents(root, 1); ret = btrfs_wait_ordered_extents(root, 1);
BUG_ON(ret); BUG_ON(ret);
} }
......
...@@ -262,11 +262,9 @@ static int process_one_buffer(struct btrfs_root *log, ...@@ -262,11 +262,9 @@ static int process_one_buffer(struct btrfs_root *log,
struct extent_buffer *eb, struct extent_buffer *eb,
struct walk_control *wc, u64 gen) struct walk_control *wc, u64 gen)
{ {
if (wc->pin) { if (wc->pin)
mutex_lock(&log->fs_info->pinned_mutex);
btrfs_update_pinned_extents(log->fs_info->extent_root, btrfs_update_pinned_extents(log->fs_info->extent_root,
eb->start, eb->len, 1); eb->start, eb->len, 1);
}
if (btrfs_buffer_uptodate(eb, gen)) { if (btrfs_buffer_uptodate(eb, gen)) {
if (wc->write) if (wc->write)
...@@ -1224,8 +1222,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans, ...@@ -1224,8 +1222,7 @@ static noinline int replay_one_name(struct btrfs_trans_handle *trans,
ret = insert_one_name(trans, root, path, key->objectid, key->offset, ret = insert_one_name(trans, root, path, key->objectid, key->offset,
name, name_len, log_type, &log_key); name, name_len, log_type, &log_key);
if (ret && ret != -ENOENT) BUG_ON(ret && ret != -ENOENT);
BUG();
goto out; goto out;
} }
...@@ -2900,6 +2897,11 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans, ...@@ -2900,6 +2897,11 @@ int btrfs_log_inode_parent(struct btrfs_trans_handle *trans,
sb = inode->i_sb; sb = inode->i_sb;
if (btrfs_test_opt(root, NOTREELOG)) {
ret = 1;
goto end_no_trans;
}
if (root->fs_info->last_trans_log_full_commit > if (root->fs_info->last_trans_log_full_commit >
root->fs_info->last_trans_committed) { root->fs_info->last_trans_committed) {
ret = 1; ret = 1;
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
#include <linux/buffer_head.h> #include <linux/buffer_head.h>
#include <linux/blkdev.h> #include <linux/blkdev.h>
#include <linux/random.h> #include <linux/random.h>
#include <linux/iocontext.h>
#include <asm/div64.h> #include <asm/div64.h>
#include "compat.h" #include "compat.h"
#include "ctree.h" #include "ctree.h"
...@@ -145,8 +146,9 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) ...@@ -145,8 +146,9 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
int again = 0; int again = 0;
unsigned long num_run = 0; unsigned long num_run = 0;
unsigned long limit; unsigned long limit;
unsigned long last_waited = 0;
bdi = device->bdev->bd_inode->i_mapping->backing_dev_info; bdi = blk_get_backing_dev_info(device->bdev);
fs_info = device->dev_root->fs_info; fs_info = device->dev_root->fs_info;
limit = btrfs_async_submit_limit(fs_info); limit = btrfs_async_submit_limit(fs_info);
limit = limit * 2 / 3; limit = limit * 2 / 3;
...@@ -207,7 +209,32 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) ...@@ -207,7 +209,32 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
if (pending && bdi_write_congested(bdi) && num_run > 16 && if (pending && bdi_write_congested(bdi) && num_run > 16 &&
fs_info->fs_devices->open_devices > 1) { fs_info->fs_devices->open_devices > 1) {
struct bio *old_head; struct bio *old_head;
struct io_context *ioc;
ioc = current->io_context;
/*
* the main goal here is that we don't want to
* block if we're going to be able to submit
* more requests without blocking.
*
* This code does two great things, it pokes into
* the elevator code from a filesystem _and_
* it makes assumptions about how batching works.
*/
if (ioc && ioc->nr_batch_requests > 0 &&
time_before(jiffies, ioc->last_waited + HZ/50UL) &&
(last_waited == 0 ||
ioc->last_waited == last_waited)) {
/*
* we want to go through our batch of
* requests and stop. So, we copy out
* the ioc->last_waited time and test
* against it before looping
*/
last_waited = ioc->last_waited;
continue;
}
spin_lock(&device->io_lock); spin_lock(&device->io_lock);
old_head = device->pending_bios; old_head = device->pending_bios;
...@@ -231,6 +258,18 @@ static noinline int run_scheduled_bios(struct btrfs_device *device) ...@@ -231,6 +258,18 @@ static noinline int run_scheduled_bios(struct btrfs_device *device)
if (device->pending_bios) if (device->pending_bios)
goto loop_lock; goto loop_lock;
spin_unlock(&device->io_lock); spin_unlock(&device->io_lock);
/*
* IO has already been through a long path to get here. Checksumming,
* async helper threads, perhaps compression. We've done a pretty
* good job of collecting a batch of IO and should just unplug
* the device right away.
*
* This will help anyone who is waiting on the IO, they might have
* already unplugged, but managed to do so before the bio they
* cared about found its way down here.
*/
blk_run_backing_dev(bdi, NULL);
done: done:
return 0; return 0;
} }
......
...@@ -76,7 +76,7 @@ struct btrfs_device { ...@@ -76,7 +76,7 @@ struct btrfs_device {
struct btrfs_fs_devices { struct btrfs_fs_devices {
u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */ u8 fsid[BTRFS_FSID_SIZE]; /* FS specific uuid */
/* the device with this id has the most recent coyp of the super */ /* the device with this id has the most recent copy of the super */
u64 latest_devid; u64 latest_devid;
u64 latest_trans; u64 latest_trans;
u64 num_devices; u64 num_devices;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment