mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2025-01-12 08:48:48 +00:00
Merge branch 'for-chris' of git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs-next into linus
This commit is contained in:
commit
daf2c08911
@ -3997,7 +3997,7 @@ again:
|
||||
* We make the other tasks wait for the flush only when we can flush
|
||||
* all things.
|
||||
*/
|
||||
if (ret && flush == BTRFS_RESERVE_FLUSH_ALL) {
|
||||
if (ret && flush != BTRFS_RESERVE_NO_FLUSH) {
|
||||
flushing = true;
|
||||
space_info->flush = 1;
|
||||
}
|
||||
@ -5560,7 +5560,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans,
|
||||
int empty_cluster = 2 * 1024 * 1024;
|
||||
struct btrfs_space_info *space_info;
|
||||
int loop = 0;
|
||||
int index = 0;
|
||||
int index = __get_raid_index(data);
|
||||
int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ?
|
||||
RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC;
|
||||
bool found_uncached_bg = false;
|
||||
@ -6788,11 +6788,13 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans,
|
||||
&wc->flags[level]);
|
||||
if (ret < 0) {
|
||||
btrfs_tree_unlock_rw(eb, path->locks[level]);
|
||||
path->locks[level] = 0;
|
||||
return ret;
|
||||
}
|
||||
BUG_ON(wc->refs[level] == 0);
|
||||
if (wc->refs[level] == 1) {
|
||||
btrfs_tree_unlock_rw(eb, path->locks[level]);
|
||||
path->locks[level] = 0;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
@ -2242,6 +2242,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
|
||||
if (lockend <= lockstart)
|
||||
lockend = lockstart + root->sectorsize;
|
||||
|
||||
lockend--;
|
||||
len = lockend - lockstart + 1;
|
||||
|
||||
len = max_t(u64, len, root->sectorsize);
|
||||
@ -2308,9 +2309,12 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin)
|
||||
}
|
||||
}
|
||||
|
||||
*offset = start;
|
||||
free_extent_map(em);
|
||||
break;
|
||||
if (!test_bit(EXTENT_FLAG_PREALLOC,
|
||||
&em->flags)) {
|
||||
*offset = start;
|
||||
free_extent_map(em);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = {
|
||||
[S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK,
|
||||
};
|
||||
|
||||
static int btrfs_setsize(struct inode *inode, loff_t newsize);
|
||||
static int btrfs_setsize(struct inode *inode, struct iattr *attr);
|
||||
static int btrfs_truncate(struct inode *inode);
|
||||
static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent);
|
||||
static noinline int cow_file_range(struct inode *inode,
|
||||
@ -2478,6 +2478,18 @@ int btrfs_orphan_cleanup(struct btrfs_root *root)
|
||||
continue;
|
||||
}
|
||||
nr_truncate++;
|
||||
|
||||
/* 1 for the orphan item deletion. */
|
||||
trans = btrfs_start_transaction(root, 1);
|
||||
if (IS_ERR(trans)) {
|
||||
ret = PTR_ERR(trans);
|
||||
goto out;
|
||||
}
|
||||
ret = btrfs_orphan_add(trans, inode);
|
||||
btrfs_end_transaction(trans, root);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
ret = btrfs_truncate(inode);
|
||||
} else {
|
||||
nr_unlink++;
|
||||
@ -3665,6 +3677,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size)
|
||||
block_end - cur_offset, 0);
|
||||
if (IS_ERR(em)) {
|
||||
err = PTR_ERR(em);
|
||||
em = NULL;
|
||||
break;
|
||||
}
|
||||
last_byte = min(extent_map_end(em), block_end);
|
||||
@ -3748,16 +3761,27 @@ next:
|
||||
return err;
|
||||
}
|
||||
|
||||
static int btrfs_setsize(struct inode *inode, loff_t newsize)
|
||||
static int btrfs_setsize(struct inode *inode, struct iattr *attr)
|
||||
{
|
||||
struct btrfs_root *root = BTRFS_I(inode)->root;
|
||||
struct btrfs_trans_handle *trans;
|
||||
loff_t oldsize = i_size_read(inode);
|
||||
loff_t newsize = attr->ia_size;
|
||||
int mask = attr->ia_valid;
|
||||
int ret;
|
||||
|
||||
if (newsize == oldsize)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a
|
||||
* special case where we need to update the times despite not having
|
||||
* these flags set. For all other operations the VFS set these flags
|
||||
* explicitly if it wants a timestamp update.
|
||||
*/
|
||||
if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME))))
|
||||
inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb);
|
||||
|
||||
if (newsize > oldsize) {
|
||||
truncate_pagecache(inode, oldsize, newsize);
|
||||
ret = btrfs_cont_expand(inode, oldsize, newsize);
|
||||
@ -3783,9 +3807,34 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize)
|
||||
set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE,
|
||||
&BTRFS_I(inode)->runtime_flags);
|
||||
|
||||
/*
|
||||
* 1 for the orphan item we're going to add
|
||||
* 1 for the orphan item deletion.
|
||||
*/
|
||||
trans = btrfs_start_transaction(root, 2);
|
||||
if (IS_ERR(trans))
|
||||
return PTR_ERR(trans);
|
||||
|
||||
/*
|
||||
* We need to do this in case we fail at _any_ point during the
|
||||
* actual truncate. Once we do the truncate_setsize we could
|
||||
* invalidate pages which forces any outstanding ordered io to
|
||||
* be instantly completed which will give us extents that need
|
||||
* to be truncated. If we fail to get an orphan inode down we
|
||||
* could have left over extents that were never meant to live,
|
||||
* so we need to garuntee from this point on that everything
|
||||
* will be consistent.
|
||||
*/
|
||||
ret = btrfs_orphan_add(trans, inode);
|
||||
btrfs_end_transaction(trans, root);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* we don't support swapfiles, so vmtruncate shouldn't fail */
|
||||
truncate_setsize(inode, newsize);
|
||||
ret = btrfs_truncate(inode);
|
||||
if (ret && inode->i_nlink)
|
||||
btrfs_orphan_del(NULL, inode);
|
||||
}
|
||||
|
||||
return ret;
|
||||
@ -3805,7 +3854,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr)
|
||||
return err;
|
||||
|
||||
if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) {
|
||||
err = btrfs_setsize(inode, attr->ia_size);
|
||||
err = btrfs_setsize(inode, attr);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
@ -5586,10 +5635,13 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag
|
||||
return em;
|
||||
if (em) {
|
||||
/*
|
||||
* if our em maps to a hole, there might
|
||||
* actually be delalloc bytes behind it
|
||||
* if our em maps to
|
||||
* - a hole or
|
||||
* - a pre-alloc extent,
|
||||
* there might actually be delalloc bytes behind it.
|
||||
*/
|
||||
if (em->block_start != EXTENT_MAP_HOLE)
|
||||
if (em->block_start != EXTENT_MAP_HOLE &&
|
||||
!test_bit(EXTENT_FLAG_PREALLOC, &em->flags))
|
||||
return em;
|
||||
else
|
||||
hole_em = em;
|
||||
@ -5671,6 +5723,8 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag
|
||||
*/
|
||||
em->block_start = hole_em->block_start;
|
||||
em->block_len = hole_len;
|
||||
if (test_bit(EXTENT_FLAG_PREALLOC, &hole_em->flags))
|
||||
set_bit(EXTENT_FLAG_PREALLOC, &em->flags);
|
||||
} else {
|
||||
em->start = range_start;
|
||||
em->len = found;
|
||||
@ -6929,11 +6983,9 @@ static int btrfs_truncate(struct inode *inode)
|
||||
|
||||
/*
|
||||
* 1 for the truncate slack space
|
||||
* 1 for the orphan item we're going to add
|
||||
* 1 for the orphan item deletion
|
||||
* 1 for updating the inode.
|
||||
*/
|
||||
trans = btrfs_start_transaction(root, 4);
|
||||
trans = btrfs_start_transaction(root, 2);
|
||||
if (IS_ERR(trans)) {
|
||||
err = PTR_ERR(trans);
|
||||
goto out;
|
||||
@ -6944,12 +6996,6 @@ static int btrfs_truncate(struct inode *inode)
|
||||
min_size);
|
||||
BUG_ON(ret);
|
||||
|
||||
ret = btrfs_orphan_add(trans, inode);
|
||||
if (ret) {
|
||||
btrfs_end_transaction(trans, root);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* setattr is responsible for setting the ordered_data_close flag,
|
||||
* but that is only tested during the last file release. That
|
||||
@ -7018,12 +7064,6 @@ static int btrfs_truncate(struct inode *inode)
|
||||
ret = btrfs_orphan_del(trans, inode);
|
||||
if (ret)
|
||||
err = ret;
|
||||
} else if (ret && inode->i_nlink > 0) {
|
||||
/*
|
||||
* Failed to do the truncate, remove us from the in memory
|
||||
* orphan list.
|
||||
*/
|
||||
ret = btrfs_orphan_del(NULL, inode);
|
||||
}
|
||||
|
||||
if (trans) {
|
||||
|
@ -1339,6 +1339,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
|
||||
if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running,
|
||||
1)) {
|
||||
pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n");
|
||||
mnt_drop_write_file(file);
|
||||
return -EINPROGRESS;
|
||||
}
|
||||
|
||||
@ -1362,6 +1363,7 @@ static noinline int btrfs_ioctl_resize(struct file *file,
|
||||
printk(KERN_INFO "btrfs: resizing devid %llu\n",
|
||||
(unsigned long long)devid);
|
||||
}
|
||||
|
||||
device = btrfs_find_device(root->fs_info, devid, NULL, NULL);
|
||||
if (!device) {
|
||||
printk(KERN_INFO "btrfs: resizer unable to find device %llu\n",
|
||||
@ -1369,9 +1371,10 @@ static noinline int btrfs_ioctl_resize(struct file *file,
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
}
|
||||
if (device->fs_devices && device->fs_devices->seeding) {
|
||||
|
||||
if (!device->writeable) {
|
||||
printk(KERN_INFO "btrfs: resizer unable to apply on "
|
||||
"seeding device %llu\n",
|
||||
"readonly device %llu\n",
|
||||
(unsigned long long)devid);
|
||||
ret = -EINVAL;
|
||||
goto out_free;
|
||||
@ -2095,13 +2098,13 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file,
|
||||
err = inode_permission(inode, MAY_WRITE | MAY_EXEC);
|
||||
if (err)
|
||||
goto out_dput;
|
||||
|
||||
/* check if subvolume may be deleted by a non-root user */
|
||||
err = btrfs_may_delete(dir, dentry, 1);
|
||||
if (err)
|
||||
goto out_dput;
|
||||
}
|
||||
|
||||
/* check if subvolume may be deleted by a user */
|
||||
err = btrfs_may_delete(dir, dentry, 1);
|
||||
if (err)
|
||||
goto out_dput;
|
||||
|
||||
if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) {
|
||||
err = -EINVAL;
|
||||
goto out_dput;
|
||||
@ -3698,6 +3701,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg)
|
||||
goto drop_write;
|
||||
}
|
||||
|
||||
if (!sa->qgroupid) {
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
trans = btrfs_join_transaction(root);
|
||||
if (IS_ERR(trans)) {
|
||||
ret = PTR_ERR(trans);
|
||||
|
@ -1814,8 +1814,10 @@ static int name_cache_insert(struct send_ctx *sctx,
|
||||
(unsigned long)nce->ino);
|
||||
if (!nce_head) {
|
||||
nce_head = kmalloc(sizeof(*nce_head), GFP_NOFS);
|
||||
if (!nce_head)
|
||||
if (!nce_head) {
|
||||
kfree(nce);
|
||||
return -ENOMEM;
|
||||
}
|
||||
INIT_LIST_HEAD(nce_head);
|
||||
|
||||
ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head);
|
||||
|
@ -1431,7 +1431,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path)
|
||||
}
|
||||
} else {
|
||||
ret = btrfs_get_bdev_and_sb(device_path,
|
||||
FMODE_READ | FMODE_EXCL,
|
||||
FMODE_WRITE | FMODE_EXCL,
|
||||
root->fs_info->bdev_holder, 0,
|
||||
&bdev, &bh);
|
||||
if (ret)
|
||||
|
Loading…
x
Reference in New Issue
Block a user