Merge branch 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull more btrfs updates from Chris Mason: "These are mostly fixes that we've been testing, but also we grabbed and tested a few small cleanups that had been on the list for a while. Zhao Lei's patchset also fixes some early ENOSPC buglets" * 'for-linus-4.5' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (21 commits) btrfs: raid56: Use raid_write_end_io for scrub btrfs: Remove unnecessary ClearPageUptodate for raid56 btrfs: use rbio->nr_pages to reduce calculation btrfs: Use unified stripe_page's index calculation btrfs: Fix calculation of rbio->dbitmap's size calculation btrfs: Fix no_space in write and rm loop btrfs: merge functions for wait snapshot creation btrfs: delete unused argument in btrfs_copy_from_user btrfs: Use direct way to determine raid56 write/recover mode btrfs: Small cleanup for get index_srcdev loop btrfs: Enhance chunk validation check btrfs: Enhance super validation check Btrfs: fix deadlock running delayed iputs at transaction commit time Btrfs: fix typo in log message when starting a balance btrfs: remove duplicate const specifier btrfs: initialize the seq counter in struct btrfs_device Btrfs: clean up an error code in btrfs_init_space_info() btrfs: fix iterator with update error in backref.c Btrfs: fix output of compression message in btrfs_parse_options() Btrfs: Initialize btrfs_root->highest_objectid when loading tree root and subvolume roots ...
This commit is contained in:
@@ -55,6 +55,12 @@
|
||||
#include <asm/cpufeature.h>
|
||||
#endif
|
||||
|
||||
#define BTRFS_SUPER_FLAG_SUPP (BTRFS_HEADER_FLAG_WRITTEN |\
|
||||
BTRFS_HEADER_FLAG_RELOC |\
|
||||
BTRFS_SUPER_FLAG_ERROR |\
|
||||
BTRFS_SUPER_FLAG_SEEDING |\
|
||||
BTRFS_SUPER_FLAG_METADUMP)
|
||||
|
||||
static const struct extent_io_ops btree_extent_io_ops;
|
||||
static void end_workqueue_fn(struct btrfs_work *work);
|
||||
static void free_fs_root(struct btrfs_root *root);
|
||||
@@ -1583,8 +1589,23 @@ int btrfs_init_fs_root(struct btrfs_root *root)
|
||||
ret = get_anon_bdev(&root->anon_dev);
|
||||
if (ret)
|
||||
goto free_writers;
|
||||
|
||||
mutex_lock(&root->objectid_mutex);
|
||||
ret = btrfs_find_highest_objectid(root,
|
||||
&root->highest_objectid);
|
||||
if (ret) {
|
||||
mutex_unlock(&root->objectid_mutex);
|
||||
goto free_root_dev;
|
||||
}
|
||||
|
||||
ASSERT(root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID);
|
||||
|
||||
mutex_unlock(&root->objectid_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
free_root_dev:
|
||||
free_anon_bdev(root->anon_dev);
|
||||
free_writers:
|
||||
btrfs_free_subvolume_writers(root->subv_writers);
|
||||
fail:
|
||||
@@ -1786,7 +1807,10 @@ static int cleaner_kthread(void *arg)
|
||||
goto sleep;
|
||||
}
|
||||
|
||||
mutex_lock(&root->fs_info->cleaner_delayed_iput_mutex);
|
||||
btrfs_run_delayed_iputs(root);
|
||||
mutex_unlock(&root->fs_info->cleaner_delayed_iput_mutex);
|
||||
|
||||
again = btrfs_clean_one_deleted_snapshot(root);
|
||||
mutex_unlock(&root->fs_info->cleaner_mutex);
|
||||
|
||||
@@ -2556,8 +2580,8 @@ int open_ctree(struct super_block *sb,
|
||||
mutex_init(&fs_info->delete_unused_bgs_mutex);
|
||||
mutex_init(&fs_info->reloc_mutex);
|
||||
mutex_init(&fs_info->delalloc_root_mutex);
|
||||
mutex_init(&fs_info->cleaner_delayed_iput_mutex);
|
||||
seqlock_init(&fs_info->profiles_lock);
|
||||
init_rwsem(&fs_info->delayed_iput_sem);
|
||||
|
||||
INIT_LIST_HEAD(&fs_info->dirty_cowonly_roots);
|
||||
INIT_LIST_HEAD(&fs_info->space_info);
|
||||
@@ -2742,26 +2766,6 @@ int open_ctree(struct super_block *sb,
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Leafsize and nodesize were always equal, this is only a sanity check.
|
||||
*/
|
||||
if (le32_to_cpu(disk_super->__unused_leafsize) !=
|
||||
btrfs_super_nodesize(disk_super)) {
|
||||
printk(KERN_ERR "BTRFS: couldn't mount because metadata "
|
||||
"blocksizes don't match. node %d leaf %d\n",
|
||||
btrfs_super_nodesize(disk_super),
|
||||
le32_to_cpu(disk_super->__unused_leafsize));
|
||||
err = -EINVAL;
|
||||
goto fail_alloc;
|
||||
}
|
||||
if (btrfs_super_nodesize(disk_super) > BTRFS_MAX_METADATA_BLOCKSIZE) {
|
||||
printk(KERN_ERR "BTRFS: couldn't mount because metadata "
|
||||
"blocksize (%d) was too large\n",
|
||||
btrfs_super_nodesize(disk_super));
|
||||
err = -EINVAL;
|
||||
goto fail_alloc;
|
||||
}
|
||||
|
||||
features = btrfs_super_incompat_flags(disk_super);
|
||||
features |= BTRFS_FEATURE_INCOMPAT_MIXED_BACKREF;
|
||||
if (tree_root->fs_info->compress_type == BTRFS_COMPRESS_LZO)
|
||||
@@ -2833,17 +2837,6 @@ int open_ctree(struct super_block *sb,
|
||||
sb->s_blocksize = sectorsize;
|
||||
sb->s_blocksize_bits = blksize_bits(sectorsize);
|
||||
|
||||
if (btrfs_super_magic(disk_super) != BTRFS_MAGIC) {
|
||||
printk(KERN_ERR "BTRFS: valid FS not found on %s\n", sb->s_id);
|
||||
goto fail_sb_buffer;
|
||||
}
|
||||
|
||||
if (sectorsize != PAGE_SIZE) {
|
||||
printk(KERN_ERR "BTRFS: incompatible sector size (%lu) "
|
||||
"found on %s\n", (unsigned long)sectorsize, sb->s_id);
|
||||
goto fail_sb_buffer;
|
||||
}
|
||||
|
||||
mutex_lock(&fs_info->chunk_mutex);
|
||||
ret = btrfs_read_sys_array(tree_root);
|
||||
mutex_unlock(&fs_info->chunk_mutex);
|
||||
@@ -2915,6 +2908,18 @@ retry_root_backup:
|
||||
tree_root->commit_root = btrfs_root_node(tree_root);
|
||||
btrfs_set_root_refs(&tree_root->root_item, 1);
|
||||
|
||||
mutex_lock(&tree_root->objectid_mutex);
|
||||
ret = btrfs_find_highest_objectid(tree_root,
|
||||
&tree_root->highest_objectid);
|
||||
if (ret) {
|
||||
mutex_unlock(&tree_root->objectid_mutex);
|
||||
goto recovery_tree_root;
|
||||
}
|
||||
|
||||
ASSERT(tree_root->highest_objectid <= BTRFS_LAST_FREE_OBJECTID);
|
||||
|
||||
mutex_unlock(&tree_root->objectid_mutex);
|
||||
|
||||
ret = btrfs_read_roots(fs_info, tree_root);
|
||||
if (ret)
|
||||
goto recovery_tree_root;
|
||||
@@ -4018,8 +4023,17 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
int read_only)
|
||||
{
|
||||
struct btrfs_super_block *sb = fs_info->super_copy;
|
||||
u64 nodesize = btrfs_super_nodesize(sb);
|
||||
u64 sectorsize = btrfs_super_sectorsize(sb);
|
||||
int ret = 0;
|
||||
|
||||
if (btrfs_super_magic(sb) != BTRFS_MAGIC) {
|
||||
printk(KERN_ERR "BTRFS: no valid FS found\n");
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP)
|
||||
printk(KERN_WARNING "BTRFS: unrecognized super flag: %llu\n",
|
||||
btrfs_super_flags(sb) & ~BTRFS_SUPER_FLAG_SUPP);
|
||||
if (btrfs_super_root_level(sb) >= BTRFS_MAX_LEVEL) {
|
||||
printk(KERN_ERR "BTRFS: tree_root level too big: %d >= %d\n",
|
||||
btrfs_super_root_level(sb), BTRFS_MAX_LEVEL);
|
||||
@@ -4037,31 +4051,46 @@ static int btrfs_check_super_valid(struct btrfs_fs_info *fs_info,
|
||||
}
|
||||
|
||||
/*
|
||||
* The common minimum, we don't know if we can trust the nodesize/sectorsize
|
||||
* items yet, they'll be verified later. Issue just a warning.
|
||||
* Check sectorsize and nodesize first, other check will need it.
|
||||
* Check all possible sectorsize(4K, 8K, 16K, 32K, 64K) here.
|
||||
*/
|
||||
if (!IS_ALIGNED(btrfs_super_root(sb), 4096))
|
||||
printk(KERN_WARNING "BTRFS: tree_root block unaligned: %llu\n",
|
||||
btrfs_super_root(sb));
|
||||
if (!IS_ALIGNED(btrfs_super_chunk_root(sb), 4096))
|
||||
printk(KERN_WARNING "BTRFS: chunk_root block unaligned: %llu\n",
|
||||
btrfs_super_chunk_root(sb));
|
||||
if (!IS_ALIGNED(btrfs_super_log_root(sb), 4096))
|
||||
printk(KERN_WARNING "BTRFS: log_root block unaligned: %llu\n",
|
||||
btrfs_super_log_root(sb));
|
||||
|
||||
/*
|
||||
* Check the lower bound, the alignment and other constraints are
|
||||
* checked later.
|
||||
*/
|
||||
if (btrfs_super_nodesize(sb) < 4096) {
|
||||
printk(KERN_ERR "BTRFS: nodesize too small: %u < 4096\n",
|
||||
btrfs_super_nodesize(sb));
|
||||
if (!is_power_of_2(sectorsize) || sectorsize < 4096 ||
|
||||
sectorsize > BTRFS_MAX_METADATA_BLOCKSIZE) {
|
||||
printk(KERN_ERR "BTRFS: invalid sectorsize %llu\n", sectorsize);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (btrfs_super_sectorsize(sb) < 4096) {
|
||||
printk(KERN_ERR "BTRFS: sectorsize too small: %u < 4096\n",
|
||||
btrfs_super_sectorsize(sb));
|
||||
/* Only PAGE SIZE is supported yet */
|
||||
if (sectorsize != PAGE_CACHE_SIZE) {
|
||||
printk(KERN_ERR "BTRFS: sectorsize %llu not supported yet, only support %lu\n",
|
||||
sectorsize, PAGE_CACHE_SIZE);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!is_power_of_2(nodesize) || nodesize < sectorsize ||
|
||||
nodesize > BTRFS_MAX_METADATA_BLOCKSIZE) {
|
||||
printk(KERN_ERR "BTRFS: invalid nodesize %llu\n", nodesize);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (nodesize != le32_to_cpu(sb->__unused_leafsize)) {
|
||||
printk(KERN_ERR "BTRFS: invalid leafsize %u, should be %llu\n",
|
||||
le32_to_cpu(sb->__unused_leafsize),
|
||||
nodesize);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
/* Root alignment check */
|
||||
if (!IS_ALIGNED(btrfs_super_root(sb), sectorsize)) {
|
||||
printk(KERN_WARNING "BTRFS: tree_root block unaligned: %llu\n",
|
||||
btrfs_super_root(sb));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!IS_ALIGNED(btrfs_super_chunk_root(sb), sectorsize)) {
|
||||
printk(KERN_WARNING "BTRFS: chunk_root block unaligned: %llu\n",
|
||||
btrfs_super_chunk_root(sb));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
if (!IS_ALIGNED(btrfs_super_log_root(sb), sectorsize)) {
|
||||
printk(KERN_WARNING "BTRFS: log_root block unaligned: %llu\n",
|
||||
btrfs_super_log_root(sb));
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user