aboutsummaryrefslogtreecommitdiff
path: root/fs/btrfs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2011-05-27 13:57:12 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2011-05-27 13:57:12 -0700
commita0c3061093c8b49facef95dc09a618c6e0d17cb5 (patch)
tree1d6ff7c06134b71a8bd0721395386e82e46e60c8 /fs/btrfs
parent10799db60cbc4f990dd69eb49883477095c66af7 (diff)
parent174ba50915b08dcfd07c8b5fb795b46a165fa09a (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: (58 commits) Btrfs: use the device_list_mutex during write_dev_supers Btrfs: setup free ino caching in a more asynchronous way btrfs scrub: don't coalesce pages that are logically discontiguous Btrfs: return -ENOMEM in clear_extent_bit Btrfs: add mount -o auto_defrag Btrfs: using rcu lock in the reader side of devices list Btrfs: drop unnecessary device lock Btrfs: fix the race between remove dev and alloc chunk Btrfs: fix the race between reading and updating devices Btrfs: fix bh leak on __btrfs_open_devices path Btrfs: fix unsafe usage of merge_state Btrfs: allocate extent state and check the result properly fs/btrfs: Add missing btrfs_free_path Btrfs: check return value of btrfs_inc_extent_ref() Btrfs: return error to caller if read_one_inode() fails Btrfs: BUG_ON is deleted from the caller of btrfs_truncate_item & btrfs_extend_item Btrfs: return error code to caller when btrfs_del_item fails Btrfs: return error code to caller when btrfs_previous_item fails btrfs: fix typo 'testeing' -> 'testing' btrfs: typo: 'btrfS' -> 'btrfs' ...
Diffstat (limited to 'fs/btrfs')
-rw-r--r--fs/btrfs/Makefile2
-rw-r--r--fs/btrfs/acl.c2
-rw-r--r--fs/btrfs/btrfs_inode.h15
-rw-r--r--fs/btrfs/compression.c47
-rw-r--r--fs/btrfs/compression.h2
-rw-r--r--fs/btrfs/ctree.c51
-rw-r--r--fs/btrfs/ctree.h244
-rw-r--r--fs/btrfs/delayed-inode.c1695
-rw-r--r--fs/btrfs/delayed-inode.h141
-rw-r--r--fs/btrfs/delayed-ref.c114
-rw-r--r--fs/btrfs/delayed-ref.h6
-rw-r--r--fs/btrfs/dir-item.c39
-rw-r--r--fs/btrfs/disk-io.c210
-rw-r--r--fs/btrfs/disk-io.h19
-rw-r--r--fs/btrfs/export.c25
-rw-r--r--fs/btrfs/extent-tree.c1788
-rw-r--r--fs/btrfs/extent_io.c324
-rw-r--r--fs/btrfs/extent_io.h40
-rw-r--r--fs/btrfs/extent_map.c8
-rw-r--r--fs/btrfs/extent_map.h4
-rw-r--r--fs/btrfs/file-item.c38
-rw-r--r--fs/btrfs/file.c302
-rw-r--r--fs/btrfs/free-space-cache.c993
-rw-r--r--fs/btrfs/free-space-cache.h48
-rw-r--r--fs/btrfs/inode-item.c2
-rw-r--r--fs/btrfs/inode-map.c444
-rw-r--r--fs/btrfs/inode-map.h13
-rw-r--r--fs/btrfs/inode.c700
-rw-r--r--fs/btrfs/ioctl.c624
-rw-r--r--fs/btrfs/ioctl.h107
-rw-r--r--fs/btrfs/locking.c25
-rw-r--r--fs/btrfs/locking.h2
-rw-r--r--fs/btrfs/ref-cache.c164
-rw-r--r--fs/btrfs/ref-cache.h24
-rw-r--r--fs/btrfs/relocation.c67
-rw-r--r--fs/btrfs/root-tree.c61
-rw-r--r--fs/btrfs/scrub.c1369
-rw-r--r--fs/btrfs/super.c51
-rw-r--r--fs/btrfs/sysfs.c77
-rw-r--r--fs/btrfs/transaction.c196
-rw-r--r--fs/btrfs/transaction.h5
-rw-r--r--fs/btrfs/tree-defrag.c2
-rw-r--r--fs/btrfs/tree-log.c208
-rw-r--r--fs/btrfs/tree-log.h1
-rw-r--r--fs/btrfs/version.sh43
-rw-r--r--fs/btrfs/volumes.c657
-rw-r--r--fs/btrfs/volumes.h27
-rw-r--r--fs/btrfs/xattr.c12
48 files changed, 6481 insertions, 4557 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile
index 31610ea73ae..9b72dcf1cd2 100644
--- a/fs/btrfs/Makefile
+++ b/fs/btrfs/Makefile
@@ -7,4 +7,4 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \
extent_map.o sysfs.o struct-funcs.o xattr.o ordered-data.o \
extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \
export.o tree-log.o acl.o free-space-cache.o zlib.o lzo.o \
- compression.o delayed-ref.o relocation.o
+ compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 44ea5b92e1b..f66fc995973 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -288,7 +288,7 @@ int btrfs_acl_chmod(struct inode *inode)
return 0;
acl = btrfs_get_acl(inode, ACL_TYPE_ACCESS);
- if (IS_ERR(acl) || !acl)
+ if (IS_ERR_OR_NULL(acl))
return PTR_ERR(acl);
clone = posix_acl_clone(acl, GFP_KERNEL);
diff --git a/fs/btrfs/btrfs_inode.h b/fs/btrfs/btrfs_inode.h
index 57c3bb2884c..93b1aa93201 100644
--- a/fs/btrfs/btrfs_inode.h
+++ b/fs/btrfs/btrfs_inode.h
@@ -22,6 +22,7 @@
#include "extent_map.h"
#include "extent_io.h"
#include "ordered-data.h"
+#include "delayed-inode.h"
/* in memory btrfs inode */
struct btrfs_inode {
@@ -152,20 +153,34 @@ struct btrfs_inode {
unsigned ordered_data_close:1;
unsigned orphan_meta_reserved:1;
unsigned dummy_inode:1;
+ unsigned in_defrag:1;
/*
* always compress this one file
*/
unsigned force_compress:4;
+ struct btrfs_delayed_node *delayed_node;
+
struct inode vfs_inode;
};
+extern unsigned char btrfs_filetype_table[];
+
static inline struct btrfs_inode *BTRFS_I(struct inode *inode)
{
return container_of(inode, struct btrfs_inode, vfs_inode);
}
+static inline u64 btrfs_ino(struct inode *inode)
+{
+ u64 ino = BTRFS_I(inode)->location.objectid;
+
+ if (ino <= BTRFS_FIRST_FREE_OBJECTID)
+ ino = inode->i_ino;
+ return ino;
+}
+
static inline void btrfs_i_size_write(struct inode *inode, u64 size)
{
i_size_write(inode, size);
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c
index 41d1d7c70e2..bfe42b03eaf 100644
--- a/fs/btrfs/compression.c
+++ b/fs/btrfs/compression.c
@@ -125,9 +125,10 @@ static int check_compressed_csum(struct inode *inode,
kunmap_atomic(kaddr, KM_USER0);
if (csum != *cb_sum) {
- printk(KERN_INFO "btrfs csum failed ino %lu "
+ printk(KERN_INFO "btrfs csum failed ino %llu "
"extent %llu csum %u "
- "wanted %u mirror %d\n", inode->i_ino,
+ "wanted %u mirror %d\n",
+ (unsigned long long)btrfs_ino(inode),
(unsigned long long)disk_start,
csum, *cb_sum, cb->mirror_num);
ret = -EIO;
@@ -332,7 +333,7 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
struct compressed_bio *cb;
unsigned long bytes_left;
struct extent_io_tree *io_tree = &BTRFS_I(inode)->io_tree;
- int page_index = 0;
+ int pg_index = 0;
struct page *page;
u64 first_byte = disk_start;
struct block_device *bdev;
@@ -366,8 +367,8 @@ int btrfs_submit_compressed_write(struct inode *inode, u64 start,
/* create and submit bios for the compressed pages */
bytes_left = compressed_len;
- for (page_index = 0; page_index < cb->nr_pages; page_index++) {
- page = compressed_pages[page_index];
+ for (pg_index = 0; pg_index < cb->nr_pages; pg_index++) {
+ page = compressed_pages[pg_index];
page->mapping = inode->i_mapping;
if (bio->bi_size)
ret = io_tree->ops->merge_bio_hook(page, 0,
@@ -432,7 +433,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
struct compressed_bio *cb)
{
unsigned long end_index;
- unsigned long page_index;
+ unsigned long pg_index;
u64 last_offset;
u64 isize = i_size_read(inode);
int ret;
@@ -456,13 +457,13 @@ static noinline int add_ra_bio_pages(struct inode *inode,
end_index = (i_size_read(inode) - 1) >> PAGE_CACHE_SHIFT;
while (last_offset < compressed_end) {
- page_index = last_offset >> PAGE_CACHE_SHIFT;
+ pg_index = last_offset >> PAGE_CACHE_SHIFT;
- if (page_index > end_index)
+ if (pg_index > end_index)
break;
rcu_read_lock();
- page = radix_tree_lookup(&mapping->page_tree, page_index);
+ page = radix_tree_lookup(&mapping->page_tree, pg_index);
rcu_read_unlock();
if (page) {
misses++;
@@ -476,7 +477,7 @@ static noinline int add_ra_bio_pages(struct inode *inode,
if (!page)
break;
- if (add_to_page_cache_lru(page, mapping, page_index,
+ if (add_to_page_cache_lru(page, mapping, pg_index,
GFP_NOFS)) {
page_cache_release(page);
goto next;
@@ -560,7 +561,7 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
unsigned long uncompressed_len = bio->bi_vcnt * PAGE_CACHE_SIZE;
unsigned long compressed_len;
unsigned long nr_pages;
- unsigned long page_index;
+ unsigned long pg_index;
struct page *page;
struct block_device *bdev;
struct bio *comp_bio;
@@ -613,10 +614,10 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
bdev = BTRFS_I(inode)->root->fs_info->fs_devices->latest_bdev;
- for (page_index = 0; page_index < nr_pages; page_index++) {
- cb->compressed_pages[page_index] = alloc_page(GFP_NOFS |
+ for (pg_index = 0; pg_index < nr_pages; pg_index++) {
+ cb->compressed_pages[pg_index] = alloc_page(GFP_NOFS |
__GFP_HIGHMEM);
- if (!cb->compressed_pages[page_index])
+ if (!cb->compressed_pages[pg_index])
goto fail2;
}
cb->nr_pages = nr_pages;
@@ -634,8 +635,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
comp_bio->bi_end_io = end_compressed_bio_read;
atomic_inc(&cb->pending_bios);
- for (page_index = 0; page_index < nr_pages; page_index++) {
- page = cb->compressed_pages[page_index];
+ for (pg_index = 0; pg_index < nr_pages; pg_index++) {
+ page = cb->compressed_pages[pg_index];
page->mapping = inode->i_mapping;
page->index = em_start >> PAGE_CACHE_SHIFT;
@@ -702,8 +703,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio,
return 0;
fail2:
- for (page_index = 0; page_index < nr_pages; page_index++)
- free_page((unsigned long)cb->compressed_pages[page_index]);
+ for (pg_index = 0; pg_index < nr_pages; pg_index++)
+ free_page((unsigned long)cb->compressed_pages[pg_index]);
kfree(cb->compressed_pages);
fail1:
@@ -945,7 +946,7 @@ void btrfs_exit_compress(void)
int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
unsigned long total_out, u64 disk_start,
struct bio_vec *bvec, int vcnt,
- unsigned long *page_index,
+ unsigned long *pg_index,
unsigned long *pg_offset)
{
unsigned long buf_offset;
@@ -954,7 +955,7 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
unsigned long working_bytes = total_out - buf_start;
unsigned long bytes;
char *kaddr;
- struct page *page_out = bvec[*page_index].bv_page;
+ struct page *page_out = bvec[*pg_index].bv_page;
/*
* start byte is the first byte of the page we're currently
@@ -995,11 +996,11 @@ int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
/* check if we need to pick another page */
if (*pg_offset == PAGE_CACHE_SIZE) {
- (*page_index)++;
- if (*page_index >= vcnt)
+ (*pg_index)++;
+ if (*pg_index >= vcnt)
return 0;
- page_out = bvec[*page_index].bv_page;
+ page_out = bvec[*pg_index].bv_page;
*pg_offset = 0;
start_byte = page_offset(page_out) - disk_start;
diff --git a/fs/btrfs/compression.h b/fs/btrfs/compression.h
index 51000174b9d..a12059f4f0f 100644
--- a/fs/btrfs/compression.h
+++ b/fs/btrfs/compression.h
@@ -37,7 +37,7 @@ int btrfs_decompress(int type, unsigned char *data_in, struct page *dest_page,
int btrfs_decompress_buf2page(char *buf, unsigned long buf_start,
unsigned long total_out, u64 disk_start,
struct bio_vec *bvec, int vcnt,
- unsigned long *page_index,
+ unsigned long *pg_index,
unsigned long *pg_offset);
int btrfs_submit_compressed_write(struct inode *inode, u64 start,
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c
index 84d7ca1fe0b..b0e18d986e0 100644
--- a/fs/btrfs/ctree.c
+++ b/fs/btrfs/ctree.c
@@ -38,11 +38,6 @@ static int balance_node_right(struct btrfs_trans_handle *trans,
struct extent_buffer *src_buf);
static int del_ptr(struct btrfs_trans_handle *trans, struct btrfs_root *root,
struct btrfs_path *path, int level, int slot);
-static int setup_items_for_insert(struct btrfs_trans_handle *trans,
- struct btrfs_root *root, struct btrfs_path *path,
- struct btrfs_key *cpu_key, u32 *data_size,
- u32 total_data, u32 total_size, int nr);
-
struct btrfs_path *btrfs_alloc_path(void)
{
@@ -107,7 +102,7 @@ void btrfs_free_path(struct btrfs_path *p)
{
if (!p)
return;
- btrfs_release_path(NULL, p);
+ btrfs_release_path(p);
kmem_cache_free(btrfs_path_cachep, p);
}
@@ -117,7 +112,7 @@ void btrfs_free_path(struct btrfs_path *p)
*
* It is safe to call this on paths that no locks or extent buffers held.
*/
-noinline void btrfs_release_path(struct btrfs_root *root, struct btrfs_path *p)
+noinline void btrfs_release_path(struct btrfs_path *p)
{
int i;
@@ -1328,7 +1323,7 @@ static noinline int reada_for_balance(struct btrfs_root *root,
ret = -EAGAIN;
/* release the whole path */
- btrfs_release_path(root, path);
+ btrfs_release_path(path);
/* read the blocks */
if (block1)
@@ -1475,7 +1470,7 @@ read_block_for_search(struct btrfs_trans_handle *trans,
return 0;
}
free_extent_buffer(tmp);
- btrfs_release_path(NULL, p);
+ btrfs_release_path(p);
return -EIO;
}
}
@@ -1494,7 +1489,7 @@ read_block_for_search(struct btrfs_trans_handle *trans,
if (p->reada)
reada_for_search(root, p, level, slot, key->objectid);
- btrfs_release_path(NULL, p);
+ btrfs_release_path(p);
ret = -EAGAIN;
tmp = read_tree_block(root, blocknr, blocksize, 0);
@@ -1563,7 +1558,7 @@ setup_nodes_for_search(struct btrfs_trans_handle *trans,
}
b = p->nodes[level];
if (!b) {
- btrfs_release_path(NULL, p);
+ btrfs_release_path(p);
goto again;
}
BUG_ON(btrfs_header_nritems(b) == 1);
@@ -1753,7 +1748,7 @@ done:
if (!p->leave_spinning)
btrfs_set_path_blocking(p);
if (ret < 0)
- btrfs_release_path(root, p);
+ btrfs_release_path(p);
return ret;
}
@@ -3026,7 +3021,7 @@ static noinline int setup_leaf_for_split(struct btrfs_trans_handle *trans,
struct btrfs_file_extent_item);
extent_len = btrfs_file_extent_num_bytes(leaf, fi);
}
- btrfs_release_path(root, path);
+ btrfs_release_path(path);
path->keep_locks = 1;
path->search_for_split = 1;
@@ -3216,7 +3211,6 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
struct btrfs_path *path,
u32 new_size, int from_end)
{
- int ret = 0;
int slot;
struct extent_buffer *leaf;
struct btrfs_item *item;
@@ -3314,12 +3308,11 @@ int btrfs_truncate_item(struct btrfs_trans_handle *trans,
btrfs_set_item_size(leaf, item, new_size);
btrfs_mark_buffer_dirty(leaf);
- ret = 0;
if (btrfs_leaf_free_space(root, leaf) < 0) {
btrfs_print_leaf(root, leaf);
BUG();
}
- return ret;
+ return 0;
}
/*
@@ -3329,7 +3322,6 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
struct btrfs_root *root, struct btrfs_path *path,
u32 data_size)
{
- int ret = 0;
int slot;
struct extent_buffer *leaf;
struct btrfs_item *item;
@@ -3394,12 +3386,11 @@ int btrfs_extend_item(struct btrfs_trans_handle *trans,
btrfs_set_item_size(leaf, item, old_size + data_size);
btrfs_mark_buffer_dirty(leaf);
- ret = 0;
if (btrfs_leaf_free_space(root, leaf) < 0) {
btrfs_print_leaf(root, leaf);
BUG();
}
- return ret;
+ return 0;
}
/*
@@ -3559,11 +3550,10 @@ out:
* to save stack depth by doing the bulk of the work in a function
* that doesn't call btrfs_search_slot
*/
-static noinline_for_stack int
-setup_items_for_insert(struct btrfs_trans_handle *trans,
- struct btrfs_root *root, struct btrfs_path *path,
- struct btrfs_key *cpu_key, u32 *data_size,
- u32 total_data, u32 total_size, int nr)
+int setup_items_for_insert(struct btrfs_trans_handle *trans,
+ struct btrfs_root *root, struct btrfs_path *path,
+ struct btrfs_key *cpu_key, u32 *data_size,
+ u32 total_data, u32 total_size, int nr)
{
struct btrfs_item *item;
int i;
@@ -3647,7 +3637,6 @@ setup_items_for_insert(struct btrfs_trans_handle *trans,
ret = 0;
if (slot == 0) {
- struct btrfs_disk_key disk_key;
btrfs_cpu_key_to_disk(&disk_key, cpu_key);
ret = fixup_low_keys(trans, root, path, &disk_key, 1);
}
@@ -3949,7 +3938,7 @@ int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path)
else
return 1;
- btrfs_release_path(root, path);
+ btrfs_release_path(path);
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0)
return ret;
@@ -4073,7 +4062,7 @@ find_next_key:
sret = btrfs_find_next_key(root, path, min_key, level,
cache_only, min_trans);
if (sret == 0) {
- btrfs_release_path(root, path);
+ btrfs_release_path(path);
goto again;
} else {
goto out;
@@ -4152,7 +4141,7 @@ next:
btrfs_node_key_to_cpu(c, &cur_key, slot);
orig_lowest = path->lowest_level;
- btrfs_release_path(root, path);
+ btrfs_release_path(path);
path->lowest_level = level;
ret = btrfs_search_slot(NULL, root, &cur_key, path,
0, 0);
@@ -4229,7 +4218,7 @@ int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path)
again:
level = 1;
next = NULL;
- btrfs_release_path(root, path);
+ btrfs_release_path(path);
path->keep_locks = 1;
@@ -4285,7 +4274,7 @@ again:
goto again;
if (ret < 0) {
- btrfs_release_path(root, path);
+ btrfs_release_path(path);
goto done;
}
@@ -4324,7 +4313,7 @@ again:
goto again;
if (ret < 0) {
- btrfs_release_path(root, path);
+ btrfs_release_path(path);
goto done;
}
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 8f4b81de3ae..332323e19dd 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -23,6 +23,7 @@
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/fs.h>
+#include <linux/rwsem.h>
#include <linux/completion.h>
#include <linux/backing-dev.h>
#include <linux/wait.h>
@@ -33,6 +34,7 @@
#include "extent_io.h"
#include "extent_map.h"
#include "async-thread.h"
+#include "ioctl.h"
struct btrfs_trans_handle;
struct btrfs_transaction;
@@ -105,6 +107,12 @@ struct btrfs_ordered_sum;
/* For storing free space cache */
#define BTRFS_FREE_SPACE_OBJECTID -11ULL
+/*
+ * The inode number assigned to the special inode for sotring
+ * free ino cache
+ */
+#define BTRFS_FREE_INO_OBJECTID -12ULL
+
/* dummy objectid represents multiple objectids */
#define BTRFS_MULTIPLE_OBJECTIDS -255ULL
@@ -187,7 +195,6 @@ struct btrfs_mapping_tree {
struct extent_map_tree map_tree;
};
-#define BTRFS_UUID_SIZE 16
struct btrfs_dev_item {
/* the internal btrfs device id */
__le64 devid;
@@ -294,7 +301,6 @@ static inline unsigned long btrfs_chunk_item_size(int num_stripes)
sizeof(struct btrfs_stripe) * (num_stripes - 1);
}
-#define BTRFS_FSID_SIZE 16
#define BTRFS_HEADER_FLAG_WRITTEN (1ULL << 0)
#define BTRFS_HEADER_FLAG_RELOC (1ULL << 1)
@@ -510,6 +516,12 @@ struct btrfs_extent_item_v0 {
/* use full backrefs for extent pointers in the block */
#define BTRFS_BLOCK_FLAG_FULL_BACKREF (1ULL << 8)
+/*
+ * this flag is only used internally by scrub and may be changed at any time
+ * it is only declared here to avoid collisions
+ */
+#define BTRFS_EXTENT_FLAG_SUPER (1ULL << 48)
+
struct btrfs_tree_block_info {
struct btrfs_disk_key key;
u8 level;
@@ -740,12 +752,12 @@ struct btrfs_space_info {
*/
unsigned long reservation_progress;
- int full:1; /* indicates that we cannot allocate any more
+ unsigned int full:1; /* indicates that we cannot allocate any more
chunks for this space */
- int chunk_alloc:1; /* set if we are allocating a chunk */
+ unsigned int chunk_alloc:1; /* set if we are allocating a chunk */
- int force_alloc; /* set if we need to force a chunk alloc for
- this space */
+ unsigned int force_alloc; /* set if we need to force a chunk
+ alloc for this space */
struct list_head list;
@@ -830,9 +842,6 @@ struct btrfs_block_group_cache {
u64 bytes_super;
u64 flags;
u64 sectorsize;
- int extents_thresh;
- int free_extents;
- int total_bitmaps;
unsigned int ro:1;
unsigned int dirty:1;
unsigned int iref:1;
@@ -847,9 +856,7 @@ struct btrfs_block_group_cache {
struct btrfs_space_info *space_info;
/* free space cache stuff */
- spinlock_t tree_lock;
- struct rb_root free_space_offset;
- u64 free_space;
+ struct btrfs_free_space_ctl *free_space_ctl;
/* block group cache stuff */
struct rb_node cache_node;
@@ -869,6 +876,7 @@ struct btrfs_block_group_cache {
struct reloc_control;
struct btrfs_device;
struct btrfs_fs_devices;
+struct btrfs_delayed_root;
struct btrfs_fs_info {
u8 fsid[BTRFS_FSID_SIZE];
u8 chunk_tree_uuid[BTRFS_UUID_SIZE];
@@ -895,7 +903,10 @@ struct btrfs_fs_info {
/* logical->physical extent mapping */
struct btrfs_mapping_tree mapping_tree;
- /* block reservation for extent, checksum and root tree */
+ /*
+ * block reservation for extent, checksum, root tree and
+ * delayed dir index item
+ */
struct btrfs_block_rsv global_block_rsv;
/* block reservation for delay allocation */
struct btrfs_block_rsv delalloc_block_rsv;
@@ -1022,6 +1033,7 @@ struct btrfs_fs_info {
* for the sys_munmap function call path
*/
struct btrfs_workers fixup_workers;
+ struct btrfs_workers delayed_workers;
struct task_struct *transaction_kthread;
struct task_struct *cleaner_kthread;
int thread_pool_size;
@@ -1062,6 +1074,11 @@ struct btrfs_fs_info {
/* all metadata allocations go through this cluster */
struct btrfs_free_cluster meta_alloc_cluster;
+ /* auto defrag inodes go here */
+ spinlock_t defrag_inodes_lock;
+ struct rb_root defrag_inodes;
+ atomic_t defrag_running;
+
spinlock_t ref_cache_lock;
u64 total_ref_cache_size;
@@ -1077,8 +1094,21 @@ struct btrfs_fs_info {
void *bdev_holder;
+ /* private scrub information */
+ struct mutex scrub_lock;
+ atomic_t scrubs_running;
+ atomic_t scrub_pause_req;
+ atomic_t scrubs_paused;
+ atomic_t scrub_cancel_req;
+ wait_queue_head_t scrub_pause_wait;
+ struct rw_semaphore scrub_super_lock;
+ int scrub_workers_refcnt;
+ struct btrfs_workers scrub_workers;
+
/* filesystem state */
u64 fs_state;
+
+ struct btrfs_delayed_root *delayed_root;
};
/*
@@ -1088,9 +1118,6 @@ struct btrfs_fs_info {
struct btrfs_root {
struct extent_buffer *node;
- /* the node lock is held while changing the node pointer */
- spinlock_t node_lock;
-
struct extent_buffer *commit_root;
struct btrfs_root *log_root;
struct btrfs_root *reloc_root;
@@ -1107,6 +1134,16 @@ struct btrfs_root {
spinlock_t accounting_lock;
struct btrfs_block_rsv *block_rsv;
+ /* free ino cache stuff */
+ struct mutex fs_commit_mutex;
+ struct btrfs_free_space_ctl *free_ino_ctl;
+ enum btrfs_caching_type cached;
+ spinlock_t cache_lock;
+ wait_queue_head_t cache_wait;
+ struct btrfs_free_space_ctl *free_ino_pinned;
+ u64 cache_progress;
+ struct inode *cache_inode;
+
struct mutex log_mutex;
wait_queue_head_t log_writer_wait;
wait_queue_head_t log_commit_wait[2];
@@ -1162,12 +1199,49 @@ struct btrfs_root {
struct rb_root inode_tree;
/*
+ * radix tree that keeps track of delayed nodes of every inode,
+ * protected by inode_lock
+ */
+ struct radix_tree_root delayed_nodes_tree;
+ /*
* right now this just gets used so that a root has its own devid
* for stat. It may be used for more later
*/
struct super_block anon_super;
};
+struct btrfs_ioctl_defrag_range_args {
+ /* start of the defrag operation */
+ __u64 start;
+
+ /* number of bytes to defrag, use (u64)-1 to say all */
+ __u64 len;
+
+ /*
+ * flags for the operation, which can include turning
+ * on compression for this one defrag
+ */
+ __u64 flags;
+
+ /*
+ * any extent bigger than this will be considered
+ * already defragged. Use 0 to take the kernel default
+ * Use 1 to say every single extent must be rewritten
+ */
+ __u32 extent_thresh;
+
+ /*
+ * which compression method to use if turning on compression
+ * for this defrag operation. If unspecified, zlib will
+ * be used
+ */
+ __u32 compress_type;
+
+ /* spare for later */
+ __u32 unused[4];
+};
+
+
/*
* 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
@@ -1265,6 +1339,7 @@ struct btrfs_root {
#define BTRFS_MOUNT_CLEAR_CACHE (1 << 13)
#define BTRFS_MOUNT_USER_SUBVOL_RM_ALLOWED (1 << 14)
#define BTRFS_MOUNT_ENOSPC_DEBUG (1 << 15)
+#define BTRFS_MOUNT_AUTO_DEFRAG (1 << 16)
#define btrfs_clear_opt(o, opt) ((o) &= ~BTRFS_MOUNT_##opt)
#define btrfs_set_opt(o, opt) ((o) |= BTRFS_MOUNT_##opt)
@@ -1440,26 +1515,12 @@ static inline u64 btrfs_stripe_offset_nr(struct extent_buffer *eb,
return btrfs_stripe_offset(eb, btrfs_stripe_nr(c, nr));
}
-static inline void btrfs_set_stripe_offset_nr(struct extent_buffer *eb,
- struct btrfs_chunk *c, int nr,
- u64 val)
-{
- btrfs_set_stripe_offs