Commit b25b550b authored by Linus Torvalds's avatar Linus Torvalds

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
parents eda05477 6f902af4
...@@ -60,6 +60,8 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type) ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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 = { ...@@ -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, ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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 @@ struct backref_node *build_backref_tree(struct reloc_control *rc, ...@@ -784,16 +784,17 @@ struct backref_node *build_backref_tree(struct reloc_control *rc,
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, ...@@ -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, ...@@ -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, ...@@ -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 @@ static struct dentry *get_default_root(struct super_block *sb, ...@@ -390,8 +392,8 @@ static struct dentry *get_default_root(struct super_block *sb,
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
......
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