Commit 6a6662ce authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (114 commits)
  Btrfs: check for a null fs root when writing to the backup root log
  Btrfs: fix race during transaction joins
  Btrfs: fix a potential btrfs_bio leak on scrub fixups
  Btrfs: rename btrfs_bio multi -> bbio for consistency
  Btrfs: stop leaking btrfs_bios on readahead
  Btrfs: stop the readahead threads on failed mount
  Btrfs: fix extent_buffer leak in the metadata IO error handling
  Btrfs: fix the new inspection ioctls for 32 bit compat
  Btrfs: fix delayed insertion reservation
  Btrfs: ClearPageError during writepage and clean_tree_block
  Btrfs: be smarter about committing the transaction in reserve_metadata_bytes
  Btrfs: make a delayed_block_rsv for the delayed item insertion
  Btrfs: add a log of past tree roots
  btrfs: separate superblock items out of fs_info
  Btrfs: use the global reserve when truncating the free space cache inode
  Btrfs: release metadata from global reserve if we have to fallback for unlink
  Btrfs: make sure to flush queued bios if write_cache_pages waits
  Btrfs: fix extent pinning bugs in the tree log
  Btrfs: make sure btrfs_remove_free_space doesn't leak EAGAIN
  Btrfs: don't wait as long for more batches during SSD log commit
  ...
parents 32aaeffb 7c7e82a7
...@@ -7,6 +7,7 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ ...@@ -7,6 +7,7 @@ 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_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 \ extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \
export.o tree-log.o free-space-cache.o zlib.o lzo.o \ export.o tree-log.o free-space-cache.o zlib.o lzo.o \
compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \
reada.o backref.o
btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o
...@@ -59,22 +59,19 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type) ...@@ -59,22 +59,19 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
if (!value) if (!value)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
size = __btrfs_getxattr(inode, name, value, size); size = __btrfs_getxattr(inode, name, value, size);
}
if (size > 0) { if (size > 0) {
acl = posix_acl_from_xattr(value, size); acl = posix_acl_from_xattr(value, size);
if (IS_ERR(acl)) {
kfree(value);
return acl;
}
set_cached_acl(inode, type, acl);
}
kfree(value);
} else if (size == -ENOENT || size == -ENODATA || size == 0) { } else if (size == -ENOENT || size == -ENODATA || size == 0) {
/* FIXME, who returns -ENOENT? I think nobody */ /* FIXME, who returns -ENOENT? I think nobody */
acl = NULL; acl = NULL;
set_cached_acl(inode, type, acl);
} else { } else {
acl = ERR_PTR(-EIO); acl = ERR_PTR(-EIO);
} }
kfree(value);
if (!IS_ERR(acl))
set_cached_acl(inode, type, acl);
return acl; return acl;
} }
......
This diff is collapsed.
/*
* Copyright (C) 2011 STRATO. 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_BACKREF__
#define __BTRFS_BACKREF__
#include "ioctl.h"
struct inode_fs_paths {
struct btrfs_path *btrfs_path;
struct btrfs_root *fs_root;
struct btrfs_data_container *fspath;
};
typedef int (iterate_extent_inodes_t)(u64 inum, u64 offset, u64 root,
void *ctx);
typedef int (iterate_irefs_t)(u64 parent, struct btrfs_inode_ref *iref,
struct extent_buffer *eb, void *ctx);
int inode_item_info(u64 inum, u64 ioff, struct btrfs_root *fs_root,
struct btrfs_path *path);
int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical,
struct btrfs_path *path, struct btrfs_key *found_key);
int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb,
struct btrfs_extent_item *ei, u32 item_size,
u64 *out_root, u8 *out_level);
int iterate_extent_inodes(struct btrfs_fs_info *fs_info,
struct btrfs_path *path,
u64 extent_item_objectid,
u64 extent_offset,
iterate_extent_inodes_t *iterate, void *ctx);
int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info,
struct btrfs_path *path,
iterate_extent_inodes_t *iterate, void *ctx);
int paths_from_inode(u64 inum, struct inode_fs_paths *ipath);
struct btrfs_data_container *init_data_container(u32 total_bytes);
struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root,
struct btrfs_path *path);
void free_ipath(struct inode_fs_paths *ipath);
#endif
...@@ -103,11 +103,6 @@ struct btrfs_inode { ...@@ -103,11 +103,6 @@ struct btrfs_inode {
*/ */
u64 delalloc_bytes; u64 delalloc_bytes;
/* total number of bytes that may be used for this inode for
* delalloc
*/
u64 reserved_bytes;
/* /*
* the size of the file stored in the metadata on disk. data=ordered * the size of the file stored in the metadata on disk. data=ordered
* means the in-memory i_size might be larger than the size on disk * means the in-memory i_size might be larger than the size on disk
...@@ -115,9 +110,6 @@ struct btrfs_inode { ...@@ -115,9 +110,6 @@ struct btrfs_inode {
*/ */
u64 disk_i_size; u64 disk_i_size;
/* flags field from the on disk inode */
u32 flags;
/* /*
* if this is a directory then index_cnt is the counter for the index * if this is a directory then index_cnt is the counter for the index
* number for new files that are created * number for new files that are created
...@@ -131,6 +123,15 @@ struct btrfs_inode { ...@@ -131,6 +123,15 @@ struct btrfs_inode {
*/ */
u64 last_unlink_trans; u64 last_unlink_trans;
/*
* Number of bytes outstanding that are going to need csums. This is
* used in ENOSPC accounting.
*/
u64 csum_bytes;
/* flags field from the on disk inode */
u32 flags;
/* /*
* Counters to keep track of the number of extent item's we may use due * Counters to keep track of the number of extent item's we may use due
* to delalloc and such. outstanding_extents is the number of extent * to delalloc and such. outstanding_extents is the number of extent
......
...@@ -85,7 +85,8 @@ struct compressed_bio { ...@@ -85,7 +85,8 @@ struct compressed_bio {
static inline int compressed_bio_size(struct btrfs_root *root, static inline int compressed_bio_size(struct btrfs_root *root,
unsigned long disk_size) unsigned long disk_size)
{ {
u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy); u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
return sizeof(struct compressed_bio) + return sizeof(struct compressed_bio) +
((disk_size + root->sectorsize - 1) / root->sectorsize) * ((disk_size + root->sectorsize - 1) / root->sectorsize) *
csum_size; csum_size;
......
...@@ -902,9 +902,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, ...@@ -902,9 +902,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
orig_ptr = btrfs_node_blockptr(mid, orig_slot); orig_ptr = btrfs_node_blockptr(mid, orig_slot);
if (level < BTRFS_MAX_LEVEL - 1) if (level < BTRFS_MAX_LEVEL - 1) {
parent = path->nodes[level + 1]; parent = path->nodes[level + 1];
pslot = path->slots[level + 1]; pslot = path->slots[level + 1];
}
/* /*
* deal with the case where there is only one pointer in the root * deal with the case where there is only one pointer in the root
...@@ -1107,9 +1108,10 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans, ...@@ -1107,9 +1108,10 @@ static noinline int push_nodes_for_insert(struct btrfs_trans_handle *trans,
mid = path->nodes[level]; mid = path->nodes[level];
WARN_ON(btrfs_header_generation(mid) != trans->transid); WARN_ON(btrfs_header_generation(mid) != trans->transid);
if (level < BTRFS_MAX_LEVEL - 1) if (level < BTRFS_MAX_LEVEL - 1) {
parent = path->nodes[level + 1]; parent = path->nodes[level + 1];
pslot = path->slots[level + 1]; pslot = path->slots[level + 1];
}
if (!parent) if (!parent)
return 1; return 1;
......
This diff is collapsed.
...@@ -591,7 +591,7 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, ...@@ -591,7 +591,7 @@ static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
return 0; return 0;
src_rsv = trans->block_rsv; src_rsv = trans->block_rsv;
dst_rsv = &root->fs_info->global_block_rsv; dst_rsv = &root->fs_info->delayed_block_rsv;
num_bytes = btrfs_calc_trans_metadata_size(root, 1); num_bytes = btrfs_calc_trans_metadata_size(root, 1);
ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
...@@ -609,7 +609,7 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root, ...@@ -609,7 +609,7 @@ static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
if (!item->bytes_reserved) if (!item->bytes_reserved)
return; return;
rsv = &root->fs_info->global_block_rsv; rsv = &root->fs_info->delayed_block_rsv;
btrfs_block_rsv_release(root, rsv, btrfs_block_rsv_release(root, rsv,
item->bytes_reserved); item->bytes_reserved);
} }
...@@ -624,13 +624,36 @@ static int btrfs_delayed_inode_reserve_metadata( ...@@ -624,13 +624,36 @@ static int btrfs_delayed_inode_reserve_metadata(
u64 num_bytes; u64 num_bytes;
int ret; int ret;
if (!trans->bytes_reserved)
return 0;
src_rsv = trans->block_rsv; src_rsv = trans->block_rsv;
dst_rsv = &root->fs_info->global_block_rsv; dst_rsv = &root->fs_info->delayed_block_rsv;
num_bytes = btrfs_calc_trans_metadata_size(root, 1); num_bytes = btrfs_calc_trans_metadata_size(root, 1);
/*
* btrfs_dirty_inode will update the inode under btrfs_join_transaction
* which doesn't reserve space for speed. This is a problem since we
* still need to reserve space for this update, so try to reserve the
* space.
*
* Now if src_rsv == delalloc_block_rsv we'll let it just steal since
* we're accounted for.
*/
if (!trans->bytes_reserved &&
src_rsv != &root->fs_info->delalloc_block_rsv) {
ret = btrfs_block_rsv_add_noflush(root, dst_rsv, num_bytes);
/*
* Since we're under a transaction reserve_metadata_bytes could
* try to commit the transaction which will make it return
* EAGAIN to make us stop the transaction we have, so return
* ENOSPC instead so that btrfs_dirty_inode knows what to do.
*/
if (ret == -EAGAIN)
ret = -ENOSPC;
if (!ret)
node->bytes_reserved = num_bytes;
return ret;
}
ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes); ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes);
if (!ret) if (!ret)
node->bytes_reserved = num_bytes; node->bytes_reserved = num_bytes;
...@@ -646,7 +669,7 @@ static void btrfs_delayed_inode_release_metadata(struct btrfs_root *root, ...@@ -646,7 +669,7 @@ static void btrfs_delayed_inode_release_metadata(struct btrfs_root *root,
if (!node->bytes_reserved) if (!node->bytes_reserved)
return; return;
rsv = &root->fs_info->global_block_rsv; rsv = &root->fs_info->delayed_block_rsv;
btrfs_block_rsv_release(root, rsv, btrfs_block_rsv_release(root, rsv,
node->bytes_reserved); node->bytes_reserved);
node->bytes_reserved = 0; node->bytes_reserved = 0;
...@@ -1026,7 +1049,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans, ...@@ -1026,7 +1049,7 @@ int btrfs_run_delayed_items(struct btrfs_trans_handle *trans,
path->leave_spinning = 1; path->leave_spinning = 1;
block_rsv = trans->block_rsv; block_rsv = trans->block_rsv;
trans->block_rsv = &root->fs_info->global_block_rsv; trans->block_rsv = &root->fs_info->delayed_block_rsv;
delayed_root = btrfs_get_delayed_root(root); delayed_root = btrfs_get_delayed_root(root);
...@@ -1069,7 +1092,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, ...@@ -1069,7 +1092,7 @@ static int __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
path->leave_spinning = 1; path->leave_spinning = 1;
block_rsv = trans->block_rsv; block_rsv = trans->block_rsv;
trans->block_rsv = &node->root->fs_info->global_block_rsv; trans->block_rsv = &node->root->fs_info->delayed_block_rsv;
ret = btrfs_insert_delayed_items(trans, path, node->root, node); ret = btrfs_insert_delayed_items(trans, path, node->root, node);
if (!ret) if (!ret)
...@@ -1149,7 +1172,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work) ...@@ -1149,7 +1172,7 @@ static void btrfs_async_run_delayed_node_done(struct btrfs_work *work)
goto free_path; goto free_path;
block_rsv = trans->block_rsv; block_rsv = trans->block_rsv;
trans->block_rsv = &root->fs_info->global_block_rsv; trans->block_rsv = &root->fs_info->delayed_block_rsv;
ret = btrfs_insert_delayed_items(trans, path, root, delayed_node); ret = btrfs_insert_delayed_items(trans, path, root, delayed_node);
if (!ret) if (!ret)
...@@ -1686,11 +1709,8 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, ...@@ -1686,11 +1709,8 @@ int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
} }
ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node); ret = btrfs_delayed_inode_reserve_metadata(trans, root, delayed_node);
/* if (ret)
* we must reserve enough space when we start a new transaction, goto release_node;
* so reserving metadata failure is impossible
*/
BUG_ON(ret);
fill_stack_inode_item(trans, &delayed_node->inode_item, inode); fill_stack_inode_item(trans, &delayed_node->inode_item, inode);
delayed_node->inode_dirty = 1; delayed_node->inode_dirty = 1;
......
This diff is collapsed.
...@@ -40,6 +40,8 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr, ...@@ -40,6 +40,8 @@ struct extent_buffer *read_tree_block(struct btrfs_root *root, u64 bytenr,
u32 blocksize, u64 parent_transid); u32 blocksize, u64 parent_transid);
int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize, int readahead_tree_block(struct btrfs_root *root, u64 bytenr, u32 blocksize,
u64 parent_transid); u64 parent_transid);
int reada_tree_block_flagged(struct btrfs_root *root, u64 bytenr, u32 blocksize,
int mirror_num, struct extent_buffer **eb);
struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root, struct extent_buffer *btrfs_find_create_tree_block(struct btrfs_root *root,
u64 bytenr, u32 blocksize); u64 bytenr, u32 blocksize);
int clean_tree_block(struct btrfs_trans_handle *trans, int clean_tree_block(struct btrfs_trans_handle *trans,
...@@ -83,8 +85,6 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans, ...@@ -83,8 +85,6 @@ int btrfs_init_log_root_tree(struct btrfs_trans_handle *trans,
struct btrfs_fs_info *fs_info); struct btrfs_fs_info *fs_info);
int btrfs_add_log_tree(struct btrfs_trans_handle *trans, int btrfs_add_log_tree(struct btrfs_trans_handle *trans,
struct btrfs_root *root); struct btrfs_root *root);
int btree_lock_page_hook(struct page *page);
#ifdef CONFIG_DEBUG_LOCK_ALLOC #ifdef CONFIG_DEBUG_LOCK_ALLOC
void btrfs_init_lockdep(void); void btrfs_init_lockdep(void);
......
This diff is collapsed.
This diff is collapsed.
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
#define EXTENT_NODATASUM (1 << 10) #define EXTENT_NODATASUM (1 << 10)
#define EXTENT_DO_ACCOUNTING (1 << 11) #define EXTENT_DO_ACCOUNTING (1 << 11)
#define EXTENT_FIRST_DELALLOC (1 << 12) #define EXTENT_FIRST_DELALLOC (1 << 12)
#define EXTENT_NEED_WAIT (1 << 13)
#define EXTENT_DAMAGED (1 << 14)
#define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK) #define EXTENT_IOBITS (EXTENT_LOCKED | EXTENT_WRITEBACK)
#define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC) #define EXTENT_CTLBITS (EXTENT_DO_ACCOUNTING | EXTENT_FIRST_DELALLOC)
...@@ -32,6 +34,7 @@ ...@@ -32,6 +34,7 @@
#define EXTENT_BUFFER_BLOCKING 1 #define EXTENT_BUFFER_BLOCKING 1
#define EXTENT_BUFFER_DIRTY 2 #define EXTENT_BUFFER_DIRTY 2
#define EXTENT_BUFFER_CORRUPT 3 #define EXTENT_BUFFER_CORRUPT 3
#define EXTENT_BUFFER_READAHEAD 4 /* this got triggered by readahead */
/* these are flags for extent_clear_unlock_delalloc */ /* these are flags for extent_clear_unlock_delalloc */
#define EXTENT_CLEAR_UNLOCK_PAGE 0x1 #define EXTENT_CLEAR_UNLOCK_PAGE 0x1
...@@ -67,7 +70,7 @@ struct extent_io_ops { ...@@ -67,7 +70,7 @@ struct extent_io_ops {
unsigned long bio_flags); unsigned long bio_flags);
int (*readpage_io_hook)(struct page *page, u64 start, u64 end); int (*readpage_io_hook)(struct page *page, u64 start, u64 end);
int (*readpage_io_failed_hook)(struct bio *bio, struct page *page, int (*readpage_io_failed_hook)(struct bio *bio, struct page *page,
u64 start, u64 end, u64 start, u64 end, u64 failed_mirror,
struct extent_state *state); struct extent_state *state);
int (*writepage_io_failed_hook)(struct bio *bio, struct page *page, int (*writepage_io_failed_hook)(struct bio *bio, struct page *page,
u64 start, u64 end, u64 start, u64 end,
...@@ -85,7 +88,8 @@ struct extent_io_ops { ...@@ -85,7 +88,8 @@ struct extent_io_ops {
struct extent_state *other); struct extent_state *other);
void (*split_extent_hook)(struct inode *inode, void (*split_extent_hook)(struct inode *inode,
struct extent_state *orig, u64 split); struct extent_state *orig, u64 split);
int (*write_cache_pages_lock_hook)(struct page *page); int (*write_cache_pages_lock_hook)(struct page *page, void *data,
void (*flush_fn)(void *));
}; };
struct extent_io_tree { struct extent_io_tree {
...@@ -185,7 +189,7 @@ int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end, ...@@ -185,7 +189,7 @@ int unlock_extent_cached(struct extent_io_tree *tree, u64 start, u64 end,
int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end, int try_lock_extent(struct extent_io_tree *tree, u64 start, u64 end,
gfp_t mask); gfp_t mask);
int extent_read_full_page(struct extent_io_tree *tree, struct page *page, int extent_read_full_page(struct extent_io_tree *tree, struct page *page,
get_extent_t *get_extent); get_extent_t *get_extent, int mirror_num);
int __init extent_io_init(void); int __init extent_io_init(void);
void extent_io_exit(void); void extent_io_exit(void);
...@@ -214,6 +218,8 @@ int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, ...@@ -214,6 +218,8 @@ int set_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
gfp_t mask); gfp_t mask);
int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end, int clear_extent_dirty(struct extent_io_tree *tree, u64 start, u64 end,
gfp_t mask); gfp_t mask);
int convert_extent_bit(struct extent_io_tree *tree, u64 start, u64 end,
int bits, int clear_bits, gfp_t mask);
int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end, int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
struct extent_state **cached_state, gfp_t mask); struct extent_state **cached_state, gfp_t mask);
int find_first_extent_bit(struct extent_io_tree *tree, u64 start, int find_first_extent_bit(struct extent_io_tree *tree, u64 start,
...@@ -248,9 +254,14 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree, ...@@ -248,9 +254,14 @@ struct extent_buffer *alloc_extent_buffer(struct extent_io_tree *tree,
struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree, struct extent_buffer *find_extent_buffer(struct extent_io_tree *tree,
u64 start, unsigned long len); u64 start, unsigned long len);
void free_extent_buffer(struct extent_buffer *eb); void free_extent_buffer(struct extent_buffer *eb);
#define WAIT_NONE 0
#define WAIT_COMPLETE 1
#define WAIT_PAGE_LOCK 2
int read_extent_buffer_pages(struct extent_io_tree *tree, int read_extent_buffer_pages(struct extent_io_tree *tree,
struct extent_buffer *eb, u64 start, int wait, struct extent_buffer *eb, u64 start, int wait,
get_extent_t *get_extent, int mirror_num); get_extent_t *get_extent, int mirror_num);
unsigned long num_extent_pages(u64 start, u64 len);
struct page *extent_buffer_page(struct extent_buffer *eb, unsigned long i);
static inline void extent_buffer_get(struct extent_buffer *eb) static inline void extent_buffer_get(struct extent_buffer *eb)
{ {
...@@ -300,4 +311,10 @@ int extent_clear_unlock_delalloc(struct inode *inode, ...@@ -300,4 +311,10 @@ int extent_clear_unlock_delalloc(struct inode *inode,
struct bio * struct bio *
btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs, btrfs_bio_alloc(struct block_device *bdev, u64 first_sector, int nr_vecs,
gfp_t gfp_flags); gfp_t gfp_flags);
struct btrfs_mapping_tree;
int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start,
u64 length, u64 logical, struct page *page,
int mirror_num);
#endif #endif
...@@ -91,8 +91,7 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans, ...@@ -91,8 +91,7 @@ struct btrfs_csum_item *btrfs_lookup_csum(struct btrfs_trans_handle *trans,
struct btrfs_csum_item *item; struct btrfs_csum_item *item;
struct extent_buffer *leaf; struct extent_buffer *leaf;
u64 csum_offset = 0; u64 csum_offset = 0;
u16 csum_size = u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
btrfs_super_csum_size(&root->fs_info->super_copy);
int csums_in_item; int csums_in_item;
file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID; file_key.objectid = BTRFS_EXTENT_CSUM_OBJECTID;
...@@ -162,8 +161,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root, ...@@ -162,8 +161,7 @@ static int __btrfs_lookup_bio_sums(struct btrfs_root *root,
u64 item_last_offset = 0; u64 item_last_offset = 0;
u64 disk_bytenr; u64 disk_bytenr;
u32 diff; u32 diff;
u16 csum_size = u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
btrfs_super_csum_size(&root->fs_info->super_copy);
int ret; int ret;
struct btrfs_path *path; struct btrfs_path *path;
struct btrfs_csum_item *item = NULL; struct btrfs_csum_item *item = NULL;
...@@ -290,7 +288,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end, ...@@ -290,7 +288,7 @@ int btrfs_lookup_csums_range(struct btrfs_root *root, u64 start, u64 end,
int ret; int ret;
size_t size; size_t size;
u64 csum_end; u64 csum_end;
u16 csum_size = btrfs_super_csum_size(&root->fs_info->super_copy); u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
path = btrfs_alloc_path(); path = btrfs_alloc_path();
if (!path) if (!path)
...@@ -492,8 +490,7 @@ static noinline int truncate_one_csum(struct btrfs_trans_handle *trans, ...@@ -492,8 +490,7 @@ static noinline int truncate_one_csum(struct btrfs_trans_handle *trans,
u64 bytenr, u64 len) u64 bytenr, u64 len)
{ {
struct extent_buffer *leaf; struct extent_buffer *leaf;
u16 csum_size = u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
btrfs_super_csum_size(&root->fs_info->super_copy);
u64 csum_end; u64 csum_end;
u64 end_byte = bytenr + len; u64 end_byte = bytenr + len;
u32 blocksize_bits = root->fs_info->sb->s_blocksize_bits; u32 blocksize_bits = root->fs_info->sb->s_blocksize_bits;
...@@ -549,8 +546,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans, ...@@ -549,8 +546,7 @@ int btrfs_del_csums(struct btrfs_trans_handle *trans,
u64 csum_end; u64 csum_end;
struct extent_buffer *leaf; struct extent_buffer *leaf;
int ret; int ret;
u16 csum_size = u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
btrfs_super_csum_size(&root->fs_info->super_copy);
int blocksize_bits = root->fs_info->sb->s_blocksize_bits; int blocksize_bits = root->fs_info->sb->s_blocksize_bits;
root = root->fs_info->csum_root; root = root->fs_info->csum_root;
...@@ -676,8 +672,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans, ...@@ -676,8 +672,7 @@ int btrfs_csum_file_blocks(struct btrfs_trans_handle *trans,
struct btrfs_sector_sum *sector_sum; struct btrfs_sector_sum *sector_sum;
u32 nritems; u32 nritems;
u32 ins_size; u32 ins_size;
u16 csum_size = u16 csum_size = btrfs_super_csum_size(root->fs_info->super_copy);
btrfs_super_csum_size(&root->fs_info->super_copy);
path = btrfs_alloc_path(); path = btrfs_alloc_path();
if (!path) if (!path)
......
...@@ -1069,6 +1069,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, ...@@ -1069,6 +1069,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
int i; int i;
unsigned long index = pos >> PAGE_CACHE_SHIFT; unsigned long index = pos >> PAGE_CACHE_SHIFT;
struct inode *inode = fdentry(file)->d_inode; struct inode *inode = fdentry(file)->d_inode;
gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
int err = 0; int err = 0;
int faili = 0; int faili = 0;
u64 start_pos; u64 start_pos;
...@@ -1080,7 +1081,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file, ...@@ -1080,7 +1081,7 @@ static noinline int prepare_pages(struct btrfs_root *root, struct file *file,
again: again:
for (i = 0; i < num_pages; i++) { for (i = 0; i < num_pages; i++) {
pages[i] = find_or_create_page(inode->i_mapping, index + i, pages[i] = find_or_create_page(inode->i_mapping, index + i,
GFP_NOFS); mask);
if (!pages[i]) { if (!pages[i]) {
faili = i - 1; faili = i - 1;
err = -ENOMEM; err = -ENOMEM;
...@@ -1615,10 +1616,6 @@ static long btrfs_fallocate(struct file *file, int mode, ...@@ -1615,10 +1616,6 @@ static long btrfs_fallocate(struct file *file, int mode,
goto out; goto out;
} }
ret = btrfs_check_data_free_space(inode, alloc_end - alloc_start);
if (ret)
goto out;
locked_end = alloc_end - 1; locked_end = alloc_end - 1;
while (1) { while (1) {
struct btrfs_ordered_extent *ordered; struct btrfs_ordered_extent *ordered;
...@@ -1664,11 +1661,27 @@ static long btrfs_fallocate(struct file *file, int mode, ...@@ -1664,11 +1661,27 @@ static long btrfs_fallocate(struct file *file, int mode,
if (em->block_start == EXTENT_MAP_HOLE || if (em->block_start == EXTENT_MAP_HOLE ||
(cur_offset >= inode->i_size && (cur_offset >= inode->i_size &&
!test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) {
/*
* Make sure we have enough space before we do the
* allocation.
*/
ret = btrfs_check_data_free_space(inode, last_byte -
cur_offset);
if (ret) {
free_extent_map(em);
break;
}
ret = btrfs_prealloc_file_range(inode, mode, cur_offset, ret = btrfs_prealloc_file_range(inode, mode, cur_offset,
last_byte - cur_offset, last_byte - cur_offset,
1 << inode->i_blkbits, 1 << inode->i_blkbits,
offset + len, offset + len,
&alloc_hint); &alloc_hint);
/* Let go of our reservation. */
btrfs_free_reserved_data_space(inode, last_byte -
cur_offset);
if (ret < 0) { if (ret < 0) {
free_extent_map(em); free_extent_map(em);
break; break;
...@@ -1694,8 +1707,6 @@ static long btrfs_fallocate(struct file *file, int mode, ...@@ -1694,8 +1707,6 @@ static long btrfs_fallocate(struct file *file, int mode,
} }
unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end, unlock_extent_cached(&BTRFS_I(inode)->io_tree, alloc_start, locked_end,
&cached_state, GFP_NOFS); &cached_state, GFP_NOFS);
btrfs_free_reserved_data_space(inode, alloc_end - alloc_start);
out: out:
mutex_unlock(&inode->i_mutex); mutex_unlock(&inode->i_mutex);
return ret; return ret;
......
This diff is collapsed.
...@@ -465,14 +465,16 @@ int btrfs_save_ino_cache(struct btrfs_root *root, ...@@ -465,14 +465,16 @@ int btrfs_save_ino_cache(struct btrfs_root *root,
/* Just to make sure we have enough space */ /* Just to make sure we have enough space */
prealloc += 8 * PAGE_CACHE_SIZE; prealloc += 8 * PAGE_CACHE_SIZE;
ret = btrfs_check_data_free_space(inode, prealloc); ret = btrfs_delalloc_reserve_space(inode, prealloc);
if (ret) if (ret)
goto out_put; goto out_put;
ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, prealloc, ret = btrfs_prealloc_file_range_trans(inode, trans, 0, 0, prealloc,
prealloc, prealloc, &alloc_hint); prealloc, prealloc, &alloc_hint);
if (ret) if (ret) {
btrfs_delalloc_release_space(inode, prealloc);
goto out_put; goto out_put;
}
btrfs_free_reserved_data_space(inode, prealloc); btrfs_free_reserved_data_space(inode, prealloc);
out_put: out_put:
......
This diff is collapsed.
This diff is collapsed.
...@@ -193,6 +193,30 @@ struct btrfs_ioctl_space_args { ...@@ -193,6 +193,30 @@ struct btrfs_ioctl_space_args {
struct btrfs_ioctl_space_info spaces[0]; struct btrfs_ioctl_space_info spaces[0];
}; };
struct btrfs_data_container {
__u32 bytes_left; /* out -- bytes not needed to deliver output */
__u32 bytes_missing; /* out -- additional bytes needed for result */
__u32 elem_cnt; /* out */
__u32 elem_missed; /* out */
__u64 val[0]; /* out */
};
struct btrfs_ioctl_ino_path_args {
__u64 inum; /* in */
__u32 size; /* in */
__u64 reserved[4];
/* struct btrfs_data_container *fspath; out */
__u64 fspath; /* out */
};
struct btrfs_ioctl_logical_ino_args {
__u64 logical; /* in */
__u32 size; /* in */
__u64 reserved[4];
/* struct btrfs_data_container *inodes; out */
__u64 inodes;
};
#define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \ #define BTRFS_IOC_SNAP_CREATE _IOW(BTRFS_IOCTL_MAGIC, 1, \
struct btrfs_ioctl_vol_args) struct btrfs_ioctl_vol_args)
#define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \ #define BTRFS_IOC_DEFRAG _IOW(BTRFS_IOCTL_MAGIC, 2, \
...@@ -248,4 +272,9 @@ struct btrfs_ioctl_space_args { ...@@ -248,4 +272,9 @@ struct btrfs_ioctl_space_args {
struct btrfs_ioctl_dev_info_args) struct btrfs_ioctl_dev_info_args)
#define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \ #define BTRFS_IOC_FS_INFO _IOR(BTRFS_IOCTL_MAGIC, 31, \
struct btrfs_ioctl_fs_info_args) struct btrfs_ioctl_fs_info_args)
#define BTRFS_IOC_INO_PATHS _IOWR(BTRFS_IOCTL_MAGIC, 35, \
struct btrfs_ioctl_ino_path_args)
#define BTRFS_IOC_LOGICAL_INO _IOWR(BTRFS_IOCTL_MAGIC, 36, \
struct btrfs_ioctl_ino_path_args)
#endif #endif
...@@ -158,8 +158,7 @@ static void print_extent_ref_v0(struct extent_buffer *eb, int slot) ...@@ -158,8 +158,7 @@ static void print_extent_ref_v0(struct extent_buffer *eb, int slot)
void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
{ {
int i; int i;
u32 type; u32 type, nr;
u32 nr = btrfs_header_nritems(l);
struct btrfs_item *item; struct btrfs_item *item;
struct btrfs_root_item *ri; struct btrfs_root_item *ri;
struct btrfs_dir_item *di; struct btrfs_dir_item *di;
...@@ -172,6 +171,11 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l) ...@@ -172,6 +171,11 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
struct btrfs_key key; struct btrfs_key key;
struct btrfs_key found_key; struct btrfs_key found_key;
if (!l)
return;
nr = btrfs_header_nritems(l);
printk(KERN_INFO "leaf %llu total ptrs %d free space %d\n", printk(KERN_INFO "leaf %llu total ptrs %d free space %d\n",
(unsigned long long)btrfs_header_bytenr(l), nr, (unsigned long long)btrfs_header_bytenr(l), nr,
btrfs_leaf_free_space(root, l)); btrfs_leaf_free_space(root, l));
......
This diff is collapsed.
...@@ -2041,8 +2041,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc, ...@@ -2041,8 +2041,7 @@ static noinline_for_stack int merge_reloc_root(struct reloc_control *rc,
BUG_ON(IS_ERR(trans)); BUG_ON(IS_ERR(trans));
trans->block_rsv = rc->block_rsv; trans->block_rsv = rc->block_rsv;
ret = btrfs_block_rsv_check(trans, root, rc->block_rsv, ret = btrfs_block_rsv_refill(root, rc->block_rsv, min_reserved);
min_reserved, 0);
if (ret) { if (ret) {
BUG_ON(ret != -EAGAIN); BUG_ON(ret != -EAGAIN);
ret = btrfs_commit_transaction(trans, root); ret = btrfs_commit_transaction(trans, root);
...@@ -2152,8 +2151,7 @@ int prepare_to_merge(struct reloc_control *rc, int err) ...@@ -2152,8 +2151,7 @@ int prepare_to_merge(struct reloc_control *rc, int err)
again: again:
if (!err) { if (!err) {
num_bytes = rc->merging_rsv_size; num_bytes = rc->merging_rsv_size;
ret = btrfs_block_rsv_add(NULL, root, rc->block_rsv, ret = btrfs_block_rsv_add(root, rc->block_rsv, num_bytes);
num_bytes);
if (ret) if (ret)
err = ret; err = ret;
} }
...@@ -2427,7 +2425,7 @@ static int reserve_metadata_space(struct btrfs_trans_handle *trans, ...@@ -2427,7 +2425,7 @@ static int reserve_metadata_space(struct btrfs_trans_handle *trans,
num_bytes = calcu_metadata_size(rc, node, 1) * 2; num_bytes = calcu_metadata_size(rc, node, 1) * 2;
trans->block_rsv = rc->block_rsv; trans->block_rsv = rc->block_rsv;
ret = btrfs_block_rsv_add(trans, root, rc->block_rsv, num_bytes); ret = btrfs_block_rsv_add(root, rc->block_rsv, num_bytes);
if (ret) { if (ret) {
if (ret == -EAGAIN) if (ret == -EAGAIN)
rc->commit_transaction = 1; rc->commit_transaction = 1;
...@@ -2922,6 +2920,7 @@ static int relocate_file_extent_cluster(struct inode *inode, ...@@ -2922,6 +2920,7 @@ static int relocate_file_extent_cluster(struct inode *inode,
unsigned long last_index; unsigned long last_index;
struct page *page; struct page *page;
struct file_ra_state *ra; struct file_ra_state *ra;
gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping);
int nr = 0; int nr = 0;
int ret = 0; int ret = 0;
...@@ -2956,7 +2955,7 @@ static int relocate_file_extent_cluster(struct inode *inode, ...@@ -2956,7 +2955,7 @@ static int relocate_file_extent_cluster(struct inode *inode,
ra, NULL, index, ra, NULL, index,
last_index + 1 - index); last_index + 1 - index);
page = find_or_create_page(inode->i_mapping, index, page = find_or_create_page(inode->i_mapping, index,
GFP_NOFS); mask);
if (!page) { if (!page) {
btrfs_delalloc_release_metadata(inode, btrfs_delalloc_release_metadata(inode,
PAGE_CACHE_SIZE); PAGE_CACHE_SIZE);
...@@ -3323,8 +3322,11 @@ static int find_data_references(struct reloc_control *rc, ...@@ -3323,8 +3322,11 @@ static int find_data_references(struct reloc_control *rc,
} }
key.objectid = ref_objectid; key.objectid = ref_objectid;
key.offset = ref_offset;
key.type = BTRFS_EXTENT_DATA_KEY; key.type = BTRFS_EXTENT_DATA_KEY;
if (ref_offset > ((u64)-1 << 32))
key.offset = 0;
else
key.offset = ref_offset;
path->search_commit_root = 1; path->search_commit_root = 1;
path->skip_locking = 1; path->skip_locking = 1;
...@@ -3645,14 +3647,11 @@ int prepare_to_relocate(struct reloc_control *rc) ...@@ -3645,14 +3647,11 @@ int prepare_to_relocate(struct reloc_control *rc)
* btrfs_init_reloc_root will use them when there * btrfs_init_reloc_root will use them when there
* is no reservation in transaction handle. * is no reservation in transaction handle.
*/ */
ret = btrfs_block_rsv_add(NULL, rc->extent_root, rc->block_rsv, ret = btrfs_block_rsv_add(rc->extent_root, rc->block_rsv,
rc->extent_root->nodesize * 256); rc->extent_root->nodesize * 256);
if (ret) if (ret)
return ret; return ret;
rc->block_rsv->refill_used = 1;
btrfs_add_durable_block_rsv(rc->extent_root->fs_info, rc->block_rsv);
memset(&rc->cluster, 0, sizeof(rc->cluster)); memset(&rc->cluster, 0, sizeof(rc->cluster));
rc->search_start = rc->block_group->key.objectid; rc->search_start = rc->block_group->key.objectid;
rc->extents_found = 0; rc->extents_found = 0;
...@@ -3777,8 +3776,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc) ...@@ -3777,8 +3776,7 @@ static noinline_for_stack int relocate_block_group(struct reloc_control *rc)
} }
} }
ret = btrfs_block_rsv_check(trans, rc->extent_root, ret = btrfs_block_rsv_check(rc->extent_root, rc->block_rsv, 5);
rc->block_rsv, 0, 5);
if (ret < 0) { if (ret < 0) {
if (ret != -EAGAIN) { if (ret != -EAGAIN) {
err = ret; err = ret;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
...@@ -276,8 +276,9 @@ static int process_one_buffer(struct btrfs_root *log, ...@@ -276,8 +276,9 @@ static int process_one_buffer(struct btrfs_root *log,
struct walk_control *wc, u64 gen) struct walk_control *wc, u64 gen)
{ {
if (wc->pin) if (wc->pin)
btrfs_pin_extent(log->fs_info->extent_root, btrfs_pin_extent_for_log_replay(wc->trans,
eb->start, eb->len, 0); log->fs_info->extent_root,
eb->start, eb->len);
if (btrfs_buffer_uptodate(eb, gen)) { if (btrfs_buffer_uptodate(eb, gen)) {
if (wc->write) if (wc->write)
...@@ -1760,7 +1761,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans, ...@@ -1760,7 +1761,7 @@ static noinline int walk_down_log_tree(struct btrfs_trans_handle *trans,
WARN_ON(root_owner != WARN_ON(root_owner !=
BTRFS_TREE_LOG_OBJECTID); BTRFS_TREE_LOG_OBJECTID);
ret = btrfs_free_reserved_extent(root, ret = btrfs_free_and_pin_reserved_extent(root,
bytenr, blocksize); bytenr, blocksize);
BUG_ON(ret); BUG_ON(ret);
} }
...@@ -1828,7 +1829,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans, ...@@ -1828,7 +1829,7 @@ static noinline int walk_up_log_tree(struct btrfs_trans_handle *trans,
btrfs_tree_unlock(next); btrfs_tree_unlock(next);
WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID); WARN_ON(root_owner != BTRFS_TREE_LOG_OBJECTID);
ret = btrfs_free_reserved_extent(root, ret = btrfs_free_and_pin_reserved_extent(root,
path->nodes[*level]->start, path->nodes[*level]->start,
path->nodes[*level]->len); path->nodes[*level]->len);
BUG_ON(ret); BUG_ON(ret);
...@@ -1897,7 +1898,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans, ...@@ -1897,7 +1898,7 @@ static int walk_log_tree(struct btrfs_trans_handle *trans,
WARN_ON(log->root_key.objectid != WARN_ON(log->root_key.objectid !=
BTRFS_TREE_LOG_OBJECTID); BTRFS_TREE_LOG_OBJECTID);
ret = btrfs_free_reserved_extent(log, next->start, ret = btrfs_free_and_pin_reserved_extent(log, next->start,
next->len); next->len);
BUG_ON(ret); BUG_ON(ret);
} }
...@@ -2013,10 +2014,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2013,10 +2014,10 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
/* wait for previous tree log sync to complete */ /* wait for previous tree log sync to complete */
if (atomic_read(&root->log_commit[(index1 + 1) % 2])) if (atomic_read(&root->log_commit[(index1 + 1) % 2]))
wait_log_commit(trans, root, root->log_transid - 1); wait_log_commit(trans, root, root->log_transid - 1);
while (1) { while (1) {
unsigned long batch = root->log_batch; unsigned long batch = root->log_batch;
if (root->log_multiple_pids) { /* when we're on an ssd, just kick the log commit out */
if (!btrfs_test_opt(root, SSD) && root->log_multiple_pids) {
mutex_unlock(&root->log_mutex); mutex_unlock(&root->log_mutex);
schedule_timeout_uninterruptible(1); schedule_timeout_uninterruptible(1);
mutex_lock(&root->log_mutex); mutex_lock(&root->log_mutex);
...@@ -2117,9 +2118,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans, ...@@ -2117,9 +2118,9 @@ int btrfs_sync_log(struct btrfs_trans_handle *trans,
BUG_ON(ret); BUG_ON(ret);
btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark); btrfs_wait_marked_extents(log, &log->dirty_log_pages, mark);
btrfs_set_super_log_root(&root->fs_info->super_for_commit, btrfs_set_super_log_root(root->fs_info->super_for_commit,
log_root_tree->node->start); log_root_tree->node->start);
btrfs_set_super_log_root_level(&root->fs_info->super_for_commit, btrfs_set_super_log_root_level(root->fs_info->super_for_commit,
btrfs_header_level(log_root_tree->node)); btrfs_header_level(log_root_tree->node));
log_root_tree->log_batch = 0; log_root_tree->log_batch = 0;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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