Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable: Btrfs: The file argument for fsync() is never null Btrfs: handle ERR_PTR from posix_acl_from_xattr() Btrfs: avoid BUG when dropping root and reference in same transaction Btrfs: prohibit a operation of changing acl's mask when noacl mount option used Btrfs: should add a permission check for setfacl Btrfs: btrfs_lookup_dir_item() can return ERR_PTR Btrfs: btrfs_read_fs_root_no_name() returns ERR_PTRs Btrfs: unwind after btrfs_start_transaction() errors Btrfs: btrfs_iget() returns ERR_PTR Btrfs: handle kzalloc() failure in open_ctree() Btrfs: handle error returns from btrfs_lookup_dir_item() Btrfs: Fix BUG_ON for fs converted from extN Btrfs: Fix null dereference in relocation.c Btrfs: fix remap_file_pages error Btrfs: uninitialized data is check_path_shared() Btrfs: fix fallocate regression Btrfs: fix loop device on top of btrfs
This commit is contained in:
commit
b25b550bb1
|
@ -60,6 +60,8 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
|
||||||
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))
|
||||||
|
return acl;
|
||||||
set_cached_acl(inode, type, acl);
|
set_cached_acl(inode, type, acl);
|
||||||
}
|
}
|
||||||
kfree(value);
|
kfree(value);
|
||||||
|
@ -160,6 +162,12 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name,
|
||||||
int ret;
|
int ret;
|
||||||
struct posix_acl *acl = NULL;
|
struct posix_acl *acl = NULL;
|
||||||
|
|
||||||
|
if (!is_owner_or_cap(dentry->d_inode))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
if (!IS_POSIXACL(dentry->d_inode))
|
||||||
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
acl = posix_acl_from_xattr(value, size);
|
acl = posix_acl_from_xattr(value, size);
|
||||||
if (acl == NULL) {
|
if (acl == NULL) {
|
||||||
|
|
|
@ -1941,8 +1941,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
||||||
btrfs_level_size(tree_root,
|
btrfs_level_size(tree_root,
|
||||||
btrfs_super_log_root_level(disk_super));
|
btrfs_super_log_root_level(disk_super));
|
||||||
|
|
||||||
log_tree_root = kzalloc(sizeof(struct btrfs_root),
|
log_tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
|
||||||
GFP_NOFS);
|
if (!log_tree_root) {
|
||||||
|
err = -ENOMEM;
|
||||||
|
goto fail_trans_kthread;
|
||||||
|
}
|
||||||
|
|
||||||
__setup_root(nodesize, leafsize, sectorsize, stripesize,
|
__setup_root(nodesize, leafsize, sectorsize, stripesize,
|
||||||
log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID);
|
log_tree_root, fs_info, BTRFS_TREE_LOG_OBJECTID);
|
||||||
|
@ -1982,6 +1985,10 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
||||||
fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location);
|
fs_info->fs_root = btrfs_read_fs_root_no_name(fs_info, &location);
|
||||||
if (!fs_info->fs_root)
|
if (!fs_info->fs_root)
|
||||||
goto fail_trans_kthread;
|
goto fail_trans_kthread;
|
||||||
|
if (IS_ERR(fs_info->fs_root)) {
|
||||||
|
err = PTR_ERR(fs_info->fs_root);
|
||||||
|
goto fail_trans_kthread;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(sb->s_flags & MS_RDONLY)) {
|
if (!(sb->s_flags & MS_RDONLY)) {
|
||||||
down_read(&fs_info->cleanup_work_sem);
|
down_read(&fs_info->cleanup_work_sem);
|
||||||
|
|
|
@ -4360,7 +4360,8 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
|
||||||
|
|
||||||
block_rsv = get_block_rsv(trans, root);
|
block_rsv = get_block_rsv(trans, root);
|
||||||
cache = btrfs_lookup_block_group(root->fs_info, buf->start);
|
cache = btrfs_lookup_block_group(root->fs_info, buf->start);
|
||||||
BUG_ON(block_rsv->space_info != cache->space_info);
|
if (block_rsv->space_info != cache->space_info)
|
||||||
|
goto out;
|
||||||
|
|
||||||
if (btrfs_header_generation(buf) == trans->transid) {
|
if (btrfs_header_generation(buf) == trans->transid) {
|
||||||
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
|
if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
|
||||||
|
|
|
@ -1140,7 +1140,7 @@ int btrfs_sync_file(struct file *file, int datasync)
|
||||||
/*
|
/*
|
||||||
* ok we haven't committed the transaction yet, lets do a commit
|
* ok we haven't committed the transaction yet, lets do a commit
|
||||||
*/
|
*/
|
||||||
if (file && file->private_data)
|
if (file->private_data)
|
||||||
btrfs_ioctl_trans_end(file);
|
btrfs_ioctl_trans_end(file);
|
||||||
|
|
||||||
trans = btrfs_start_transaction(root, 0);
|
trans = btrfs_start_transaction(root, 0);
|
||||||
|
@ -1190,14 +1190,22 @@ static const struct vm_operations_struct btrfs_file_vm_ops = {
|
||||||
|
|
||||||
static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
|
static int btrfs_file_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||||
{
|
{
|
||||||
vma->vm_ops = &btrfs_file_vm_ops;
|
struct address_space *mapping = filp->f_mapping;
|
||||||
|
|
||||||
|
if (!mapping->a_ops->readpage)
|
||||||
|
return -ENOEXEC;
|
||||||
|
|
||||||
file_accessed(filp);
|
file_accessed(filp);
|
||||||
|
vma->vm_ops = &btrfs_file_vm_ops;
|
||||||
|
vma->vm_flags |= VM_CAN_NONLINEAR;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const struct file_operations btrfs_file_operations = {
|
const struct file_operations btrfs_file_operations = {
|
||||||
.llseek = generic_file_llseek,
|
.llseek = generic_file_llseek,
|
||||||
.read = do_sync_read,
|
.read = do_sync_read,
|
||||||
|
.write = do_sync_write,
|
||||||
.aio_read = generic_file_aio_read,
|
.aio_read = generic_file_aio_read,
|
||||||
.splice_read = generic_file_splice_read,
|
.splice_read = generic_file_splice_read,
|
||||||
.aio_write = btrfs_file_aio_write,
|
.aio_write = btrfs_file_aio_write,
|
||||||
|
|
|
@ -2673,7 +2673,7 @@ static int check_path_shared(struct btrfs_root *root,
|
||||||
struct extent_buffer *eb;
|
struct extent_buffer *eb;
|
||||||
int level;
|
int level;
|
||||||
int ret;
|
int ret;
|
||||||
u64 refs;
|
u64 refs = 1;
|
||||||
|
|
||||||
for (level = 0; level < BTRFS_MAX_LEVEL; level++) {
|
for (level = 0; level < BTRFS_MAX_LEVEL; level++) {
|
||||||
if (!path->nodes[level])
|
if (!path->nodes[level])
|
||||||
|
@ -6884,7 +6884,7 @@ static long btrfs_fallocate(struct inode *inode, 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))) {
|
||||||
ret = btrfs_prealloc_file_range(inode, 0, 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,
|
||||||
|
|
|
@ -1280,7 +1280,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
|
||||||
trans = btrfs_start_transaction(root, 0);
|
trans = btrfs_start_transaction(root, 0);
|
||||||
if (IS_ERR(trans)) {
|
if (IS_ERR(trans)) {
|
||||||
err = PTR_ERR(trans);
|
err = PTR_ERR(trans);
|
||||||
goto out;
|
goto out_up_write;
|
||||||
}
|
}
|
||||||
trans->block_rsv = &root->fs_info->global_block_rsv;
|
trans->block_rsv = &root->fs_info->global_block_rsv;
|
||||||
|
|
||||||
|
@ -1845,7 +1845,7 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
|
||||||
dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
|
dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
|
||||||
di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path,
|
di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path,
|
||||||
dir_id, "default", 7, 1);
|
dir_id, "default", 7, 1);
|
||||||
if (!di) {
|
if (IS_ERR_OR_NULL(di)) {
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
btrfs_end_transaction(trans, root);
|
btrfs_end_transaction(trans, root);
|
||||||
printk(KERN_ERR "Umm, you don't have the default dir item, "
|
printk(KERN_ERR "Umm, you don't have the default dir item, "
|
||||||
|
|
|
@ -784,16 +784,17 @@ again:
|
||||||
struct btrfs_extent_ref_v0 *ref0;
|
struct btrfs_extent_ref_v0 *ref0;
|
||||||
ref0 = btrfs_item_ptr(eb, path1->slots[0],
|
ref0 = btrfs_item_ptr(eb, path1->slots[0],
|
||||||
struct btrfs_extent_ref_v0);
|
struct btrfs_extent_ref_v0);
|
||||||
root = find_tree_root(rc, eb, ref0);
|
|
||||||
if (!root->ref_cows)
|
|
||||||
cur->cowonly = 1;
|
|
||||||
if (key.objectid == key.offset) {
|
if (key.objectid == key.offset) {
|
||||||
|
root = find_tree_root(rc, eb, ref0);
|
||||||
if (root && !should_ignore_root(root))
|
if (root && !should_ignore_root(root))
|
||||||
cur->root = root;
|
cur->root = root;
|
||||||
else
|
else
|
||||||
list_add(&cur->list, &useless);
|
list_add(&cur->list, &useless);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (is_cowonly_root(btrfs_ref_root_v0(eb,
|
||||||
|
ref0)))
|
||||||
|
cur->cowonly = 1;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY);
|
BUG_ON(key.type == BTRFS_EXTENT_REF_V0_KEY);
|
||||||
|
|
|
@ -330,7 +330,6 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||||
{
|
{
|
||||||
struct btrfs_path *path;
|
struct btrfs_path *path;
|
||||||
int ret;
|
int ret;
|
||||||
u32 refs;
|
|
||||||
struct btrfs_root_item *ri;
|
struct btrfs_root_item *ri;
|
||||||
struct extent_buffer *leaf;
|
struct extent_buffer *leaf;
|
||||||
|
|
||||||
|
@ -344,8 +343,6 @@ int btrfs_del_root(struct btrfs_trans_handle *trans, struct btrfs_root *root,
|
||||||
leaf = path->nodes[0];
|
leaf = path->nodes[0];
|
||||||
ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item);
|
ri = btrfs_item_ptr(leaf, path->slots[0], struct btrfs_root_item);
|
||||||
|
|
||||||
refs = btrfs_disk_root_refs(leaf, ri);
|
|
||||||
BUG_ON(refs != 0);
|
|
||||||
ret = btrfs_del_item(trans, root, path);
|
ret = btrfs_del_item(trans, root, path);
|
||||||
out:
|
out:
|
||||||
btrfs_free_path(path);
|
btrfs_free_path(path);
|
||||||
|
|
|
@ -360,6 +360,8 @@ static struct dentry *get_default_root(struct super_block *sb,
|
||||||
*/
|
*/
|
||||||
dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
|
dir_id = btrfs_super_root_dir(&root->fs_info->super_copy);
|
||||||
di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
|
di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
|
||||||
|
if (IS_ERR(di))
|
||||||
|
return ERR_CAST(di);
|
||||||
if (!di) {
|
if (!di) {
|
||||||
/*
|
/*
|
||||||
* Ok the default dir item isn't there. This is weird since
|
* Ok the default dir item isn't there. This is weird since
|
||||||
|
@ -390,8 +392,8 @@ setup_root:
|
||||||
location.offset = 0;
|
location.offset = 0;
|
||||||
|
|
||||||
inode = btrfs_iget(sb, &location, new_root, &new);
|
inode = btrfs_iget(sb, &location, new_root, &new);
|
||||||
if (!inode)
|
if (IS_ERR(inode))
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_CAST(inode);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we're just mounting the root most subvol put the inode and return
|
* If we're just mounting the root most subvol put the inode and return
|
||||||
|
|
Loading…
Reference in New Issue