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) { }
acl = posix_acl_from_xattr(value, size); if (size > 0) {
if (IS_ERR(acl)) { acl = posix_acl_from_xattr(value, size);
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.
This diff is collapsed.
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