Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs
Pull btrfs update from Chris Mason: "This is a large pull, with the bulk of the updates coming from: - Hole punching - send/receive fixes - fsync performance - Disk format extension allowing more hardlinks inside a single directory (btrfs-progs patch required to enable the compat bit for this one) I'm cooking more unrelated RAID code, but I wanted to make sure this original batch makes it in. The largest updates here are relatively old and have been in testing for some time." * 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/linux-btrfs: (121 commits) btrfs: init ref_index to zero in add_inode_ref Btrfs: remove repeated eb->pages check in, disk-io.c/csum_dirty_buffer Btrfs: fix page leakage Btrfs: do not warn_on when we cannot alloc a page for an extent buffer Btrfs: don't bug on enomem in readpage Btrfs: cleanup pages properly when ENOMEM in compression Btrfs: make filesystem read-only when submitting barrier fails Btrfs: detect corrupted filesystem after write I/O errors Btrfs: make compress and nodatacow mount options mutually exclusive btrfs: fix message printing Btrfs: don't bother committing delayed inode updates when fsyncing btrfs: move inline function code to header file Btrfs: remove unnecessary IS_ERR in bio_readpage_error() btrfs: remove unused function btrfs_insert_some_items() Btrfs: don't commit instead of overcommitting Btrfs: confirmation of value is added before trace_btrfs_get_extent() is called Btrfs: be smarter about dropping things from the tree log Btrfs: don't lookup csums for prealloc extents Btrfs: cache extent state when writing out dirty metadata pages Btrfs: do not hold the file extent leaf locked when adding extent item ...
This commit is contained in:
100
fs/btrfs/ioctl.c
100
fs/btrfs/ioctl.c
@@ -181,6 +181,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
|
||||
int ret;
|
||||
u64 ip_oldflags;
|
||||
unsigned int i_oldflags;
|
||||
umode_t mode;
|
||||
|
||||
if (btrfs_root_readonly(root))
|
||||
return -EROFS;
|
||||
@@ -203,6 +204,7 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
|
||||
|
||||
ip_oldflags = ip->flags;
|
||||
i_oldflags = inode->i_flags;
|
||||
mode = inode->i_mode;
|
||||
|
||||
flags = btrfs_mask_flags(inode->i_mode, flags);
|
||||
oldflags = btrfs_flags_to_ioctl(ip->flags);
|
||||
@@ -237,10 +239,31 @@ static int btrfs_ioctl_setflags(struct file *file, void __user *arg)
|
||||
ip->flags |= BTRFS_INODE_DIRSYNC;
|
||||
else
|
||||
ip->flags &= ~BTRFS_INODE_DIRSYNC;
|
||||
if (flags & FS_NOCOW_FL)
|
||||
ip->flags |= BTRFS_INODE_NODATACOW;
|
||||
else
|
||||
ip->flags &= ~BTRFS_INODE_NODATACOW;
|
||||
if (flags & FS_NOCOW_FL) {
|
||||
if (S_ISREG(mode)) {
|
||||
/*
|
||||
* It's safe to turn csums off here, no extents exist.
|
||||
* Otherwise we want the flag to reflect the real COW
|
||||
* status of the file and will not set it.
|
||||
*/
|
||||
if (inode->i_size == 0)
|
||||
ip->flags |= BTRFS_INODE_NODATACOW
|
||||
| BTRFS_INODE_NODATASUM;
|
||||
} else {
|
||||
ip->flags |= BTRFS_INODE_NODATACOW;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Revert back under same assuptions as above
|
||||
*/
|
||||
if (S_ISREG(mode)) {
|
||||
if (inode->i_size == 0)
|
||||
ip->flags &= ~(BTRFS_INODE_NODATACOW
|
||||
| BTRFS_INODE_NODATASUM);
|
||||
} else {
|
||||
ip->flags &= ~BTRFS_INODE_NODATACOW;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* The COMPRESS flag can only be changed by users, while the NOCOMPRESS
|
||||
@@ -516,7 +539,8 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
|
||||
if (!pending_snapshot)
|
||||
return -ENOMEM;
|
||||
|
||||
btrfs_init_block_rsv(&pending_snapshot->block_rsv);
|
||||
btrfs_init_block_rsv(&pending_snapshot->block_rsv,
|
||||
BTRFS_BLOCK_RSV_TEMP);
|
||||
pending_snapshot->dentry = dentry;
|
||||
pending_snapshot->root = root;
|
||||
pending_snapshot->readonly = readonly;
|
||||
@@ -525,7 +549,7 @@ static int create_snapshot(struct btrfs_root *root, struct dentry *dentry,
|
||||
*inherit = NULL; /* take responsibility to free it */
|
||||
}
|
||||
|
||||
trans = btrfs_start_transaction(root->fs_info->extent_root, 5);
|
||||
trans = btrfs_start_transaction(root->fs_info->extent_root, 6);
|
||||
if (IS_ERR(trans)) {
|
||||
ret = PTR_ERR(trans);
|
||||
goto fail;
|
||||
@@ -1022,8 +1046,8 @@ again:
|
||||
page_start, page_end - 1, 0, &cached_state);
|
||||
clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start,
|
||||
page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC |
|
||||
EXTENT_DO_ACCOUNTING, 0, 0, &cached_state,
|
||||
GFP_NOFS);
|
||||
EXTENT_DO_ACCOUNTING | EXTENT_DEFRAG, 0, 0,
|
||||
&cached_state, GFP_NOFS);
|
||||
|
||||
if (i_done != page_cnt) {
|
||||
spin_lock(&BTRFS_I(inode)->lock);
|
||||
@@ -1034,8 +1058,8 @@ again:
|
||||
}
|
||||
|
||||
|
||||
btrfs_set_extent_delalloc(inode, page_start, page_end - 1,
|
||||
&cached_state);
|
||||
set_extent_defrag(&BTRFS_I(inode)->io_tree, page_start, page_end - 1,
|
||||
&cached_state, GFP_NOFS);
|
||||
|
||||
unlock_extent_cached(&BTRFS_I(inode)->io_tree,
|
||||
page_start, page_end - 1, &cached_state,
|
||||
@@ -2351,7 +2375,6 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
||||
int ret;
|
||||
u64 len = olen;
|
||||
u64 bs = root->fs_info->sb->s_blocksize;
|
||||
u64 hint_byte;
|
||||
|
||||
/*
|
||||
* TODO:
|
||||
@@ -2456,13 +2479,13 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
||||
another, and lock file content */
|
||||
while (1) {
|
||||
struct btrfs_ordered_extent *ordered;
|
||||
lock_extent(&BTRFS_I(src)->io_tree, off, off+len);
|
||||
ordered = btrfs_lookup_first_ordered_extent(src, off+len);
|
||||
lock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
|
||||
ordered = btrfs_lookup_first_ordered_extent(src, off + len - 1);
|
||||
if (!ordered &&
|
||||
!test_range_bit(&BTRFS_I(src)->io_tree, off, off+len,
|
||||
EXTENT_DELALLOC, 0, NULL))
|
||||
!test_range_bit(&BTRFS_I(src)->io_tree, off, off + len - 1,
|
||||
EXTENT_DELALLOC, 0, NULL))
|
||||
break;
|
||||
unlock_extent(&BTRFS_I(src)->io_tree, off, off+len);
|
||||
unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
|
||||
if (ordered)
|
||||
btrfs_put_ordered_extent(ordered);
|
||||
btrfs_wait_ordered_range(src, off, len);
|
||||
@@ -2536,7 +2559,7 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
||||
btrfs_release_path(path);
|
||||
|
||||
if (key.offset + datal <= off ||
|
||||
key.offset >= off+len)
|
||||
key.offset >= off + len - 1)
|
||||
goto next;
|
||||
|
||||
memcpy(&new_key, &key, sizeof(new_key));
|
||||
@@ -2574,10 +2597,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
||||
datal -= off - key.offset;
|
||||
}
|
||||
|
||||
ret = btrfs_drop_extents(trans, inode,
|
||||
ret = btrfs_drop_extents(trans, root, inode,
|
||||
new_key.offset,
|
||||
new_key.offset + datal,
|
||||
&hint_byte, 1);
|
||||
1);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, root,
|
||||
ret);
|
||||
@@ -2637,8 +2660,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
||||
new_key.offset += skip;
|
||||
}
|
||||
|
||||
if (key.offset + datal > off+len)
|
||||
trim = key.offset + datal - (off+len);
|
||||
if (key.offset + datal > off + len)
|
||||
trim = key.offset + datal - (off + len);
|
||||
|
||||
if (comp && (skip || trim)) {
|
||||
ret = -EINVAL;
|
||||
@@ -2648,10 +2671,10 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
|
||||
size -= skip + trim;
|
||||
datal -= skip + trim;
|
||||
|
||||
ret = btrfs_drop_extents(trans, inode,
|
||||
ret = btrfs_drop_extents(trans, root, inode,
|
||||
new_key.offset,
|
||||
new_key.offset + datal,
|
||||
&hint_byte, 1);
|
||||
1);
|
||||
if (ret) {
|
||||
btrfs_abort_transaction(trans, root,
|
||||
ret);
|
||||
@@ -2715,7 +2738,7 @@ next:
|
||||
ret = 0;
|
||||
out:
|
||||
btrfs_release_path(path);
|
||||
unlock_extent(&BTRFS_I(src)->io_tree, off, off+len);
|
||||
unlock_extent(&BTRFS_I(src)->io_tree, off, off + len - 1);
|
||||
out_unlock:
|
||||
mutex_unlock(&src->i_mutex);
|
||||
mutex_unlock(&inode->i_mutex);
|
||||
@@ -2850,8 +2873,8 @@ static long btrfs_ioctl_default_subvol(struct file *file, void __user *argp)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_block_group_info(struct list_head *groups_list,
|
||||
struct btrfs_ioctl_space_info *space)
|
||||
void btrfs_get_block_group_info(struct list_head *groups_list,
|
||||
struct btrfs_ioctl_space_info *space)
|
||||
{
|
||||
struct btrfs_block_group_cache *block_group;
|
||||
|
||||
@@ -2959,8 +2982,8 @@ long btrfs_ioctl_space_info(struct btrfs_root *root, void __user *arg)
|
||||
down_read(&info->groups_sem);
|
||||
for (c = 0; c < BTRFS_NR_RAID_TYPES; c++) {
|
||||
if (!list_empty(&info->block_groups[c])) {
|
||||
get_block_group_info(&info->block_groups[c],
|
||||
&space);
|
||||
btrfs_get_block_group_info(
|
||||
&info->block_groups[c], &space);
|
||||
memcpy(dest, &space, sizeof(space));
|
||||
dest++;
|
||||
space_args.total_spaces++;
|
||||
@@ -3208,11 +3231,9 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
|
||||
{
|
||||
int ret = 0;
|
||||
int size;
|
||||
u64 extent_item_pos;
|
||||
struct btrfs_ioctl_logical_ino_args *loi;
|
||||
struct btrfs_data_container *inodes = NULL;
|
||||
struct btrfs_path *path = NULL;
|
||||
struct btrfs_key key;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
@@ -3230,7 +3251,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
|
||||
goto out;
|
||||
}
|
||||
|
||||
size = min_t(u32, loi->size, 4096);
|
||||
size = min_t(u32, loi->size, 64 * 1024);
|
||||
inodes = init_data_container(size);
|
||||
if (IS_ERR(inodes)) {
|
||||
ret = PTR_ERR(inodes);
|
||||
@@ -3238,22 +3259,13 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = extent_from_logical(root->fs_info, loi->logical, path, &key);
|
||||
btrfs_release_path(path);
|
||||
|
||||
if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK)
|
||||
ret = iterate_inodes_from_logical(loi->logical, root->fs_info, path,
|
||||
build_ino_list, inodes);
|
||||
if (ret == -EINVAL)
|
||||
ret = -ENOENT;
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
extent_item_pos = loi->logical - key.objectid;
|
||||
ret = iterate_extent_inodes(root->fs_info, key.objectid,
|
||||
extent_item_pos, 0, build_ino_list,
|
||||
inodes);
|
||||
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
ret = copy_to_user((void *)(unsigned long)loi->inodes,
|
||||
(void *)(unsigned long)inodes, size);
|
||||
if (ret)
|
||||
@@ -3261,7 +3273,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root,
|
||||
|
||||
out:
|
||||
btrfs_free_path(path);
|
||||
kfree(inodes);
|
||||
vfree(inodes);
|
||||
kfree(loi);
|
||||
|
||||
return ret;
|
||||
|
Reference in New Issue
Block a user