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:
Коммит
b25b550bb1
|
@ -60,6 +60,8 @@ static struct posix_acl *btrfs_get_acl(struct inode *inode, int type)
|
|||
size = __btrfs_getxattr(inode, name, value, size);
|
||||
if (size > 0) {
|
||||
acl = posix_acl_from_xattr(value, size);
|
||||
if (IS_ERR(acl))
|
||||
return acl;
|
||||
set_cached_acl(inode, type, acl);
|
||||
}
|
||||
kfree(value);
|
||||
|
@ -160,6 +162,12 @@ static int btrfs_xattr_acl_set(struct dentry *dentry, const char *name,
|
|||
int ret;
|
||||
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) {
|
||||
acl = posix_acl_from_xattr(value, size);
|
||||
if (acl == NULL) {
|
||||
|
|
|
@ -1941,8 +1941,11 @@ struct btrfs_root *open_ctree(struct super_block *sb,
|
|||
btrfs_level_size(tree_root,
|
||||
btrfs_super_log_root_level(disk_super));
|
||||
|
||||
log_tree_root = kzalloc(sizeof(struct btrfs_root),
|
||||
GFP_NOFS);
|
||||
log_tree_root = kzalloc(sizeof(struct btrfs_root), GFP_NOFS);
|
||||
if (!log_tree_root) {
|
||||
err = -ENOMEM;
|
||||
goto fail_trans_kthread;
|
||||
}
|
||||
|
||||
__setup_root(nodesize, leafsize, sectorsize, stripesize,
|
||||
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);
|
||||
if (!fs_info->fs_root)
|
||||
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)) {
|
||||
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);
|
||||
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 (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
|
||||
*/
|
||||
if (file && file->private_data)
|
||||
if (file->private_data)
|
||||
btrfs_ioctl_trans_end(file);
|
||||
|
||||
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)
|
||||
{
|
||||
vma->vm_ops = &btrfs_file_vm_ops;
|
||||
struct address_space *mapping = filp->f_mapping;
|
||||
|
||||
if (!mapping->a_ops->readpage)
|
||||
return -ENOEXEC;
|
||||
|
||||
file_accessed(filp);
|
||||
vma->vm_ops = &btrfs_file_vm_ops;
|
||||
vma->vm_flags |= VM_CAN_NONLINEAR;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct file_operations btrfs_file_operations = {
|
||||
.llseek = generic_file_llseek,
|
||||
.read = do_sync_read,
|
||||
.write = do_sync_write,
|
||||
.aio_read = generic_file_aio_read,
|
||||
.splice_read = generic_file_splice_read,
|
||||
.aio_write = btrfs_file_aio_write,
|
||||
|
|
|
@ -2673,7 +2673,7 @@ static int check_path_shared(struct btrfs_root *root,
|
|||
struct extent_buffer *eb;
|
||||
int level;
|
||||
int ret;
|
||||
u64 refs;
|
||||
u64 refs = 1;
|
||||
|
||||
for (level = 0; level < BTRFS_MAX_LEVEL; 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 ||
|
||||
(cur_offset >= inode->i_size &&
|
||||
!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,
|
||||
1 << inode->i_blkbits,
|
||||
offset + len,
|
||||
|
|
|
@ -1280,7 +1280,7 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
|
|||
trans = btrfs_start_transaction(root, 0);
|
||||
if (IS_ERR(trans)) {
|
||||
err = PTR_ERR(trans);
|
||||
goto out;
|
||||
goto out_up_write;
|
||||
}
|
||||
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);
|
||||
di = btrfs_lookup_dir_item(trans, root->fs_info->tree_root, path,
|
||||
dir_id, "default", 7, 1);
|
||||
if (!di) {
|
||||
if (IS_ERR_OR_NULL(di)) {
|
||||
btrfs_free_path(path);
|
||||
btrfs_end_transaction(trans, root);
|
||||
printk(KERN_ERR "Umm, you don't have the default dir item, "
|
||||
|
|
|
@ -784,16 +784,17 @@ again:
|
|||
struct btrfs_extent_ref_v0 *ref0;
|
||||
ref0 = btrfs_item_ptr(eb, path1->slots[0],
|
||||
struct btrfs_extent_ref_v0);
|
||||
root = find_tree_root(rc, eb, ref0);
|
||||
if (!root->ref_cows)
|
||||
cur->cowonly = 1;
|
||||
if (key.objectid == key.offset) {
|
||||
root = find_tree_root(rc, eb, ref0);
|
||||
if (root && !should_ignore_root(root))
|
||||
cur->root = root;
|
||||
else
|
||||
list_add(&cur->list, &useless);
|
||||
break;
|
||||
}
|
||||
if (is_cowonly_root(btrfs_ref_root_v0(eb,
|
||||
ref0)))
|
||||
cur->cowonly = 1;
|
||||
}
|
||||
#else
|
||||
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;
|
||||
int ret;
|
||||
u32 refs;
|
||||
struct btrfs_root_item *ri;
|
||||
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];
|
||||
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);
|
||||
out:
|
||||
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);
|
||||
di = btrfs_lookup_dir_item(NULL, root, path, dir_id, "default", 7, 0);
|
||||
if (IS_ERR(di))
|
||||
return ERR_CAST(di);
|
||||
if (!di) {
|
||||
/*
|
||||
* Ok the default dir item isn't there. This is weird since
|
||||
|
@ -390,8 +392,8 @@ setup_root:
|
|||
location.offset = 0;
|
||||
|
||||
inode = btrfs_iget(sb, &location, new_root, &new);
|
||||
if (!inode)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
if (IS_ERR(inode))
|
||||
return ERR_CAST(inode);
|
||||
|
||||
/*
|
||||
* If we're just mounting the root most subvol put the inode and return
|
||||
|
|
Загрузка…
Ссылка в новой задаче