forked from Minki/linux
Merge branch 'hotfixes-20111024/josef/for-chris' into btrfs-next-stable
This commit is contained in:
commit
a81d3b1ba2
@ -59,22 +59,19 @@ struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
|
||||
if (!value)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
size = __btrfs_getxattr(inode, name, value, size);
|
||||
if (size > 0) {
|
||||
acl = posix_acl_from_xattr(value, size);
|
||||
if (IS_ERR(acl)) {
|
||||
kfree(value);
|
||||
return acl;
|
||||
}
|
||||
set_cached_acl(inode, type, acl);
|
||||
}
|
||||
kfree(value);
|
||||
}
|
||||
if (size > 0) {
|
||||
acl = posix_acl_from_xattr(value, size);
|
||||
} else if (size == -ENOENT || size == -ENODATA || size == 0) {
|
||||
/* FIXME, who returns -ENOENT? I think nobody */
|
||||
acl = NULL;
|
||||
set_cached_acl(inode, type, acl);
|
||||
} else {
|
||||
acl = ERR_PTR(-EIO);
|
||||
}
|
||||
kfree(value);
|
||||
|
||||
if (!IS_ERR(acl))
|
||||
set_cached_acl(inode, type, acl);
|
||||
|
||||
return acl;
|
||||
}
|
||||
|
@ -902,9 +902,10 @@ static noinline int balance_level(struct btrfs_trans_handle *trans,
|
||||
|
||||
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];
|
||||
pslot = path->slots[level + 1];
|
||||
pslot = path->slots[level + 1];
|
||||
}
|
||||
|
||||
/*
|
||||
* 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,
|
||||
mid = path->nodes[level];
|
||||
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];
|
||||
pslot = path->slots[level + 1];
|
||||
pslot = path->slots[level + 1];
|
||||
}
|
||||
|
||||
if (!parent)
|
||||
return 1;
|
||||
|
@ -4954,6 +4954,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
|
||||
bool failed_cluster_refill = false;
|
||||
bool failed_alloc = false;
|
||||
bool use_cluster = true;
|
||||
bool have_caching_bg = false;
|
||||
u64 ideal_cache_percent = 0;
|
||||
u64 ideal_cache_offset = 0;
|
||||
|
||||
@ -5036,6 +5037,7 @@ ideal_cache:
|
||||
}
|
||||
}
|
||||
search:
|
||||
have_caching_bg = false;
|
||||
down_read(&space_info->groups_sem);
|
||||
list_for_each_entry(block_group, &space_info->block_groups[index],
|
||||
list) {
|
||||
@ -5244,6 +5246,8 @@ refill_cluster:
|
||||
failed_alloc = true;
|
||||
goto have_block_group;
|
||||
} else if (!offset) {
|
||||
if (!cached)
|
||||
have_caching_bg = true;
|
||||
goto loop;
|
||||
}
|
||||
checks:
|
||||
@ -5294,6 +5298,9 @@ loop:
|
||||
}
|
||||
up_read(&space_info->groups_sem);
|
||||
|
||||
if (!ins->objectid && loop >= LOOP_CACHING_WAIT && have_caching_bg)
|
||||
goto search;
|
||||
|
||||
if (!ins->objectid && ++index < BTRFS_NR_RAID_TYPES)
|
||||
goto search;
|
||||
|
||||
@ -7312,7 +7319,7 @@ int btrfs_remove_block_group(struct btrfs_trans_handle *trans,
|
||||
goto out;
|
||||
}
|
||||
|
||||
inode = lookup_free_space_inode(root, block_group, path);
|
||||
inode = lookup_free_space_inode(tree_root, block_group, path);
|
||||
if (!IS_ERR(inode)) {
|
||||
ret = btrfs_orphan_add(trans, inode);
|
||||
BUG_ON(ret);
|
||||
|
@ -1107,7 +1107,7 @@ int set_extent_delalloc(struct extent_io_tree *tree, u64 start, u64 end,
|
||||
struct extent_state **cached_state, gfp_t mask)
|
||||
{
|
||||
return set_extent_bit(tree, start, end,
|
||||
EXTENT_DELALLOC | EXTENT_DIRTY | EXTENT_UPTODATE,
|
||||
EXTENT_DELALLOC | EXTENT_UPTODATE,
|
||||
0, NULL, cached_state, mask);
|
||||
}
|
||||
|
||||
|
@ -393,7 +393,10 @@ again:
|
||||
(BTRFS_I(inode)->flags & BTRFS_INODE_COMPRESS))) {
|
||||
WARN_ON(pages);
|
||||
pages = kzalloc(sizeof(struct page *) * nr_pages, GFP_NOFS);
|
||||
BUG_ON(!pages);
|
||||
if (!pages) {
|
||||
/* just bail out to the uncompressed code */
|
||||
goto cont;
|
||||
}
|
||||
|
||||
if (BTRFS_I(inode)->force_compress)
|
||||
compress_type = BTRFS_I(inode)->force_compress;
|
||||
@ -424,6 +427,7 @@ again:
|
||||
will_compress = 1;
|
||||
}
|
||||
}
|
||||
cont:
|
||||
if (start == 0) {
|
||||
trans = btrfs_join_transaction(root);
|
||||
BUG_ON(IS_ERR(trans));
|
||||
@ -5773,8 +5777,7 @@ again:
|
||||
if (test_bit(BTRFS_ORDERED_NOCOW, &ordered->flags)) {
|
||||
ret = btrfs_ordered_update_i_size(inode, 0, ordered);
|
||||
if (!ret)
|
||||
ret = btrfs_update_inode(trans, root, inode);
|
||||
err = ret;
|
||||
err = btrfs_update_inode(trans, root, inode);
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
@ -282,6 +282,7 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
|
||||
struct fstrim_range range;
|
||||
u64 minlen = ULLONG_MAX;
|
||||
u64 num_devices = 0;
|
||||
u64 total_bytes = btrfs_super_total_bytes(&root->fs_info->super_copy);
|
||||
int ret;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
@ -300,12 +301,15 @@ static noinline int btrfs_ioctl_fitrim(struct file *file, void __user *arg)
|
||||
}
|
||||
}
|
||||
rcu_read_unlock();
|
||||
|
||||
if (!num_devices)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
if (copy_from_user(&range, arg, sizeof(range)))
|
||||
return -EFAULT;
|
||||
if (range.start > total_bytes)
|
||||
return -EINVAL;
|
||||
|
||||
range.len = min(range.len, total_bytes - range.start);
|
||||
range.minlen = max(range.minlen, minlen);
|
||||
ret = btrfs_trim_fs(root, &range);
|
||||
if (ret < 0)
|
||||
@ -765,7 +769,7 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len,
|
||||
int ret = 1;
|
||||
|
||||
/*
|
||||
* make sure that once we start defragging and extent, we keep on
|
||||
* make sure that once we start defragging an extent, we keep on
|
||||
* defragging it
|
||||
*/
|
||||
if (start < *defrag_end)
|
||||
@ -810,7 +814,6 @@ static int should_defrag_range(struct inode *inode, u64 start, u64 len,
|
||||
* extent will force at least part of that big extent to be defragged.
|
||||
*/
|
||||
if (ret) {
|
||||
*last_len += len;
|
||||
*defrag_end = extent_map_end(em);
|
||||
} else {
|
||||
*last_len = 0;
|
||||
@ -978,18 +981,20 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||
struct btrfs_super_block *disk_super;
|
||||
struct file_ra_state *ra = NULL;
|
||||
unsigned long last_index;
|
||||
u64 isize = i_size_read(inode);
|
||||
u64 features;
|
||||
u64 last_len = 0;
|
||||
u64 skip = 0;
|
||||
u64 defrag_end = 0;
|
||||
u64 newer_off = range->start;
|
||||
int newer_left = 0;
|
||||
unsigned long i;
|
||||
unsigned long ra_index = 0;
|
||||
int ret;
|
||||
int defrag_count = 0;
|
||||
int compress_type = BTRFS_COMPRESS_ZLIB;
|
||||
int extent_thresh = range->extent_thresh;
|
||||
int newer_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT;
|
||||
int max_cluster = (256 * 1024) >> PAGE_CACHE_SHIFT;
|
||||
int cluster = max_cluster;
|
||||
u64 new_align = ~((u64)128 * 1024 - 1);
|
||||
struct page **pages = NULL;
|
||||
|
||||
@ -1003,7 +1008,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||
compress_type = range->compress_type;
|
||||
}
|
||||
|
||||
if (inode->i_size == 0)
|
||||
if (isize == 0)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@ -1019,7 +1024,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||
ra = &file->f_ra;
|
||||
}
|
||||
|
||||
pages = kmalloc(sizeof(struct page *) * newer_cluster,
|
||||
pages = kmalloc(sizeof(struct page *) * max_cluster,
|
||||
GFP_NOFS);
|
||||
if (!pages) {
|
||||
ret = -ENOMEM;
|
||||
@ -1028,10 +1033,10 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||
|
||||
/* find the last page to defrag */
|
||||
if (range->start + range->len > range->start) {
|
||||
last_index = min_t(u64, inode->i_size - 1,
|
||||
last_index = min_t(u64, isize - 1,
|
||||
range->start + range->len - 1) >> PAGE_CACHE_SHIFT;
|
||||
} else {
|
||||
last_index = (inode->i_size - 1) >> PAGE_CACHE_SHIFT;
|
||||
last_index = (isize - 1) >> PAGE_CACHE_SHIFT;
|
||||
}
|
||||
|
||||
if (newer_than) {
|
||||
@ -1044,14 +1049,13 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||
* the extents in the file evenly spaced
|
||||
*/
|
||||
i = (newer_off & new_align) >> PAGE_CACHE_SHIFT;
|
||||
newer_left = newer_cluster;
|
||||
} else
|
||||
goto out_ra;
|
||||
} else {
|
||||
i = range->start >> PAGE_CACHE_SHIFT;
|
||||
}
|
||||
if (!max_to_defrag)
|
||||
max_to_defrag = last_index - 1;
|
||||
max_to_defrag = last_index;
|
||||
|
||||
/*
|
||||
* make writeback starts from i, so the defrag range can be
|
||||
@ -1085,18 +1089,31 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||
i = max(i + 1, next);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!newer_than) {
|
||||
cluster = (PAGE_CACHE_ALIGN(defrag_end) >>
|
||||
PAGE_CACHE_SHIFT) - i;
|
||||
cluster = min(cluster, max_cluster);
|
||||
} else {
|
||||
cluster = max_cluster;
|
||||
}
|
||||
|
||||
if (range->flags & BTRFS_DEFRAG_RANGE_COMPRESS)
|
||||
BTRFS_I(inode)->force_compress = compress_type;
|
||||
|
||||
btrfs_force_ra(inode->i_mapping, ra, file, i, newer_cluster);
|
||||
if (i + cluster > ra_index) {
|
||||
ra_index = max(i, ra_index);
|
||||
btrfs_force_ra(inode->i_mapping, ra, file, ra_index,
|
||||
cluster);
|
||||
ra_index += max_cluster;
|
||||
}
|
||||
|
||||
ret = cluster_pages_for_defrag(inode, pages, i, newer_cluster);
|
||||
ret = cluster_pages_for_defrag(inode, pages, i, cluster);
|
||||
if (ret < 0)
|
||||
goto out_ra;
|
||||
|
||||
defrag_count += ret;
|
||||
balance_dirty_pages_ratelimited_nr(inode->i_mapping, ret);
|
||||
i += ret;
|
||||
|
||||
if (newer_than) {
|
||||
if (newer_off == (u64)-1)
|
||||
@ -1111,12 +1128,17 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||
if (!ret) {
|
||||
range->start = newer_off;
|
||||
i = (newer_off & new_align) >> PAGE_CACHE_SHIFT;
|
||||
newer_left = newer_cluster;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
i++;
|
||||
if (ret > 0) {
|
||||
i += ret;
|
||||
last_len += ret << PAGE_CACHE_SHIFT;
|
||||
} else {
|
||||
i++;
|
||||
last_len = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1149,9 +1171,7 @@ int btrfs_defrag_file(struct inode *inode, struct file *file,
|
||||
btrfs_set_super_incompat_flags(disk_super, features);
|
||||
}
|
||||
|
||||
if (!file)
|
||||
kfree(ra);
|
||||
return defrag_count;
|
||||
ret = defrag_count;
|
||||
|
||||
out_ra:
|
||||
if (!file)
|
||||
|
@ -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)
|
||||
{
|
||||
int i;
|
||||
u32 type;
|
||||
u32 nr = btrfs_header_nritems(l);
|
||||
u32 type, nr;
|
||||
struct btrfs_item *item;
|
||||
struct btrfs_root_item *ri;
|
||||
struct btrfs_dir_item *di;
|
||||
@ -172,6 +171,11 @@ void btrfs_print_leaf(struct btrfs_root *root, struct extent_buffer *l)
|
||||
struct btrfs_key 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",
|
||||
(unsigned long long)btrfs_header_bytenr(l), nr,
|
||||
btrfs_leaf_free_space(root, l));
|
||||
|
@ -3322,8 +3322,11 @@ static int find_data_references(struct reloc_control *rc,
|
||||
}
|
||||
|
||||
key.objectid = ref_objectid;
|
||||
key.offset = ref_offset;
|
||||
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->skip_locking = 1;
|
||||
|
@ -419,7 +419,7 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
|
||||
u64 *subvol_rootid, struct btrfs_fs_devices **fs_devices)
|
||||
{
|
||||
substring_t args[MAX_OPT_ARGS];
|
||||
char *opts, *orig, *p;
|
||||
char *device_name, *opts, *orig, *p;
|
||||
int error = 0;
|
||||
int intarg;
|
||||
|
||||
@ -470,8 +470,14 @@ static int btrfs_parse_early_options(const char *options, fmode_t flags,
|
||||
}
|
||||
break;
|
||||
case Opt_device:
|
||||
error = btrfs_scan_one_device(match_strdup(&args[0]),
|
||||
device_name = match_strdup(&args[0]);
|
||||
if (!device_name) {
|
||||
error = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
error = btrfs_scan_one_device(device_name,
|
||||
flags, holder, fs_devices);
|
||||
kfree(device_name);
|
||||
if (error)
|
||||
goto out;
|
||||
break;
|
||||
@ -734,6 +740,16 @@ static int btrfs_set_super(struct super_block *s, void *data)
|
||||
return set_anon_super(s, data);
|
||||
}
|
||||
|
||||
/*
|
||||
* subvolumes are identified by ino 256
|
||||
*/
|
||||
static inline int is_subvolume_inode(struct inode *inode)
|
||||
{
|
||||
if (inode && inode->i_ino == BTRFS_FIRST_FREE_OBJECTID)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* This will strip out the subvol=%s argument for an argument string and add
|
||||
* subvolid=0 to make sure we get the actual tree root for path walking to the
|
||||
@ -837,6 +853,15 @@ static struct dentry *mount_subvol(const char *subvol_name, int flags,
|
||||
if (error)
|
||||
return ERR_PTR(error);
|
||||
|
||||
if (!is_subvolume_inode(path.dentry->d_inode)) {
|
||||
path_put(&path);
|
||||
mntput(mnt);
|
||||
error = -EINVAL;
|
||||
printk(KERN_ERR "btrfs: '%s' is not a valid subvolume\n",
|
||||
subvol_name);
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
/* Get a ref to the sb and the dentry we found and return it */
|
||||
s = path.mnt->mnt_sb;
|
||||
atomic_inc(&s->s_active);
|
||||
@ -933,6 +958,7 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
||||
|
||||
s->s_flags = flags | MS_NOSEC;
|
||||
strlcpy(s->s_id, bdevname(bdev, b), sizeof(s->s_id));
|
||||
btrfs_sb(s)->fs_info->bdev_holder = fs_type;
|
||||
error = btrfs_fill_super(s, fs_devices, data,
|
||||
flags & MS_SILENT ? 1 : 0);
|
||||
if (error) {
|
||||
@ -940,7 +966,6 @@ static struct dentry *btrfs_mount(struct file_system_type *fs_type, int flags,
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
btrfs_sb(s)->fs_info->bdev_holder = fs_type;
|
||||
s->s_flags |= MS_ACTIVE;
|
||||
}
|
||||
|
||||
|
@ -597,10 +597,8 @@ static int __btrfs_open_devices(struct btrfs_fs_devices *fs_devices,
|
||||
set_blocksize(bdev, 4096);
|
||||
|
||||
bh = btrfs_read_dev_super(bdev);
|
||||
if (!bh) {
|
||||
ret = -EINVAL;
|
||||
if (!bh)
|
||||
goto error_close;
|
||||
}
|
||||
|
||||
disk_super = (struct btrfs_super_block *)bh->b_data;
|
||||
devid = btrfs_stack_device_id(&disk_super->dev_item);
|
||||
@ -655,7 +653,7 @@ error:
|
||||
continue;
|
||||
}
|
||||
if (fs_devices->open_devices == 0) {
|
||||
ret = -EIO;
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
fs_devices->seeding = seeding;
|
||||
|
Loading…
Reference in New Issue
Block a user