diff options
author | Chris Mason <chris.mason@fusionio.com> | 2013-01-21 20:26:55 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@fusionio.com> | 2013-01-21 20:26:55 -0500 |
commit | daf2c08911522d1739c55baf35f03531a29c87ef (patch) | |
tree | 380d89b955baebd90ca5ac1cf6527f963cf7dae7 /fs | |
parent | 2cf687039676c2b6e1ee96b0b89090aca94babcd (diff) | |
parent | 3972f2603d8570effaf633cea52b12c7c2773c11 (diff) |
Merge branch 'for-chris' of git://git.kernel.org/pub/scm/linux/kernel/git/josef/btrfs-next into linus
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/extent-tree.c | 6 | ||||
-rw-r--r-- | fs/btrfs/file.c | 10 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 82 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 22 | ||||
-rw-r--r-- | fs/btrfs/send.c | 4 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 2 |
6 files changed, 91 insertions, 35 deletions
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index d133edfcd449..85b8454d9608 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3997,7 +3997,7 @@ again: | |||
3997 | * We make the other tasks wait for the flush only when we can flush | 3997 | * We make the other tasks wait for the flush only when we can flush |
3998 | * all things. | 3998 | * all things. |
3999 | */ | 3999 | */ |
4000 | if (ret && flush == BTRFS_RESERVE_FLUSH_ALL) { | 4000 | if (ret && flush != BTRFS_RESERVE_NO_FLUSH) { |
4001 | flushing = true; | 4001 | flushing = true; |
4002 | space_info->flush = 1; | 4002 | space_info->flush = 1; |
4003 | } | 4003 | } |
@@ -5560,7 +5560,7 @@ static noinline int find_free_extent(struct btrfs_trans_handle *trans, | |||
5560 | int empty_cluster = 2 * 1024 * 1024; | 5560 | int empty_cluster = 2 * 1024 * 1024; |
5561 | struct btrfs_space_info *space_info; | 5561 | struct btrfs_space_info *space_info; |
5562 | int loop = 0; | 5562 | int loop = 0; |
5563 | int index = 0; | 5563 | int index = __get_raid_index(data); |
5564 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? | 5564 | int alloc_type = (data & BTRFS_BLOCK_GROUP_DATA) ? |
5565 | RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; | 5565 | RESERVE_ALLOC_NO_ACCOUNT : RESERVE_ALLOC; |
5566 | bool found_uncached_bg = false; | 5566 | bool found_uncached_bg = false; |
@@ -6788,11 +6788,13 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, | |||
6788 | &wc->flags[level]); | 6788 | &wc->flags[level]); |
6789 | if (ret < 0) { | 6789 | if (ret < 0) { |
6790 | btrfs_tree_unlock_rw(eb, path->locks[level]); | 6790 | btrfs_tree_unlock_rw(eb, path->locks[level]); |
6791 | path->locks[level] = 0; | ||
6791 | return ret; | 6792 | return ret; |
6792 | } | 6793 | } |
6793 | BUG_ON(wc->refs[level] == 0); | 6794 | BUG_ON(wc->refs[level] == 0); |
6794 | if (wc->refs[level] == 1) { | 6795 | if (wc->refs[level] == 1) { |
6795 | btrfs_tree_unlock_rw(eb, path->locks[level]); | 6796 | btrfs_tree_unlock_rw(eb, path->locks[level]); |
6797 | path->locks[level] = 0; | ||
6796 | return 1; | 6798 | return 1; |
6797 | } | 6799 | } |
6798 | } | 6800 | } |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 20452c110d7d..841cfe3be0e0 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -2242,6 +2242,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) | |||
2242 | if (lockend <= lockstart) | 2242 | if (lockend <= lockstart) |
2243 | lockend = lockstart + root->sectorsize; | 2243 | lockend = lockstart + root->sectorsize; |
2244 | 2244 | ||
2245 | lockend--; | ||
2245 | len = lockend - lockstart + 1; | 2246 | len = lockend - lockstart + 1; |
2246 | 2247 | ||
2247 | len = max_t(u64, len, root->sectorsize); | 2248 | len = max_t(u64, len, root->sectorsize); |
@@ -2308,9 +2309,12 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) | |||
2308 | } | 2309 | } |
2309 | } | 2310 | } |
2310 | 2311 | ||
2311 | *offset = start; | 2312 | if (!test_bit(EXTENT_FLAG_PREALLOC, |
2312 | free_extent_map(em); | 2313 | &em->flags)) { |
2313 | break; | 2314 | *offset = start; |
2315 | free_extent_map(em); | ||
2316 | break; | ||
2317 | } | ||
2314 | } | 2318 | } |
2315 | } | 2319 | } |
2316 | 2320 | ||
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 67ed24ae86bb..9bc6c40b182d 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -88,7 +88,7 @@ static unsigned char btrfs_type_by_mode[S_IFMT >> S_SHIFT] = { | |||
88 | [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK, | 88 | [S_IFLNK >> S_SHIFT] = BTRFS_FT_SYMLINK, |
89 | }; | 89 | }; |
90 | 90 | ||
91 | static int btrfs_setsize(struct inode *inode, loff_t newsize); | 91 | static int btrfs_setsize(struct inode *inode, struct iattr *attr); |
92 | static int btrfs_truncate(struct inode *inode); | 92 | static int btrfs_truncate(struct inode *inode); |
93 | static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent); | 93 | static int btrfs_finish_ordered_io(struct btrfs_ordered_extent *ordered_extent); |
94 | static noinline int cow_file_range(struct inode *inode, | 94 | static noinline int cow_file_range(struct inode *inode, |
@@ -2478,6 +2478,18 @@ int btrfs_orphan_cleanup(struct btrfs_root *root) | |||
2478 | continue; | 2478 | continue; |
2479 | } | 2479 | } |
2480 | nr_truncate++; | 2480 | nr_truncate++; |
2481 | |||
2482 | /* 1 for the orphan item deletion. */ | ||
2483 | trans = btrfs_start_transaction(root, 1); | ||
2484 | if (IS_ERR(trans)) { | ||
2485 | ret = PTR_ERR(trans); | ||
2486 | goto out; | ||
2487 | } | ||
2488 | ret = btrfs_orphan_add(trans, inode); | ||
2489 | btrfs_end_transaction(trans, root); | ||
2490 | if (ret) | ||
2491 | goto out; | ||
2492 | |||
2481 | ret = btrfs_truncate(inode); | 2493 | ret = btrfs_truncate(inode); |
2482 | } else { | 2494 | } else { |
2483 | nr_unlink++; | 2495 | nr_unlink++; |
@@ -3665,6 +3677,7 @@ int btrfs_cont_expand(struct inode *inode, loff_t oldsize, loff_t size) | |||
3665 | block_end - cur_offset, 0); | 3677 | block_end - cur_offset, 0); |
3666 | if (IS_ERR(em)) { | 3678 | if (IS_ERR(em)) { |
3667 | err = PTR_ERR(em); | 3679 | err = PTR_ERR(em); |
3680 | em = NULL; | ||
3668 | break; | 3681 | break; |
3669 | } | 3682 | } |
3670 | last_byte = min(extent_map_end(em), block_end); | 3683 | last_byte = min(extent_map_end(em), block_end); |
@@ -3748,16 +3761,27 @@ next: | |||
3748 | return err; | 3761 | return err; |
3749 | } | 3762 | } |
3750 | 3763 | ||
3751 | static int btrfs_setsize(struct inode *inode, loff_t newsize) | 3764 | static int btrfs_setsize(struct inode *inode, struct iattr *attr) |
3752 | { | 3765 | { |
3753 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3766 | struct btrfs_root *root = BTRFS_I(inode)->root; |
3754 | struct btrfs_trans_handle *trans; | 3767 | struct btrfs_trans_handle *trans; |
3755 | loff_t oldsize = i_size_read(inode); | 3768 | loff_t oldsize = i_size_read(inode); |
3769 | loff_t newsize = attr->ia_size; | ||
3770 | int mask = attr->ia_valid; | ||
3756 | int ret; | 3771 | int ret; |
3757 | 3772 | ||
3758 | if (newsize == oldsize) | 3773 | if (newsize == oldsize) |
3759 | return 0; | 3774 | return 0; |
3760 | 3775 | ||
3776 | /* | ||
3777 | * The regular truncate() case without ATTR_CTIME and ATTR_MTIME is a | ||
3778 | * special case where we need to update the times despite not having | ||
3779 | * these flags set. For all other operations the VFS set these flags | ||
3780 | * explicitly if it wants a timestamp update. | ||
3781 | */ | ||
3782 | if (newsize != oldsize && (!(mask & (ATTR_CTIME | ATTR_MTIME)))) | ||
3783 | inode->i_ctime = inode->i_mtime = current_fs_time(inode->i_sb); | ||
3784 | |||
3761 | if (newsize > oldsize) { | 3785 | if (newsize > oldsize) { |
3762 | truncate_pagecache(inode, oldsize, newsize); | 3786 | truncate_pagecache(inode, oldsize, newsize); |
3763 | ret = btrfs_cont_expand(inode, oldsize, newsize); | 3787 | ret = btrfs_cont_expand(inode, oldsize, newsize); |
@@ -3783,9 +3807,34 @@ static int btrfs_setsize(struct inode *inode, loff_t newsize) | |||
3783 | set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, | 3807 | set_bit(BTRFS_INODE_ORDERED_DATA_CLOSE, |
3784 | &BTRFS_I(inode)->runtime_flags); | 3808 | &BTRFS_I(inode)->runtime_flags); |
3785 | 3809 | ||
3810 | /* | ||
3811 | * 1 for the orphan item we're going to add | ||
3812 | * 1 for the orphan item deletion. | ||
3813 | */ | ||
3814 | trans = btrfs_start_transaction(root, 2); | ||
3815 | if (IS_ERR(trans)) | ||
3816 | return PTR_ERR(trans); | ||
3817 | |||
3818 | /* | ||
3819 | * We need to do this in case we fail at _any_ point during the | ||
3820 | * actual truncate. Once we do the truncate_setsize we could | ||
3821 | * invalidate pages which forces any outstanding ordered io to | ||
3822 | * be instantly completed which will give us extents that need | ||
3823 | * to be truncated. If we fail to get an orphan inode down we | ||
3824 | * could have left over extents that were never meant to live, | ||
3825 | * so we need to garuntee from this point on that everything | ||
3826 | * will be consistent. | ||
3827 | */ | ||
3828 | ret = btrfs_orphan_add(trans, inode); | ||
3829 | btrfs_end_transaction(trans, root); | ||
3830 | if (ret) | ||
3831 | return ret; | ||
3832 | |||
3786 | /* we don't support swapfiles, so vmtruncate shouldn't fail */ | 3833 | /* we don't support swapfiles, so vmtruncate shouldn't fail */ |
3787 | truncate_setsize(inode, newsize); | 3834 | truncate_setsize(inode, newsize); |
3788 | ret = btrfs_truncate(inode); | 3835 | ret = btrfs_truncate(inode); |
3836 | if (ret && inode->i_nlink) | ||
3837 | btrfs_orphan_del(NULL, inode); | ||
3789 | } | 3838 | } |
3790 | 3839 | ||
3791 | return ret; | 3840 | return ret; |
@@ -3805,7 +3854,7 @@ static int btrfs_setattr(struct dentry *dentry, struct iattr *attr) | |||
3805 | return err; | 3854 | return err; |
3806 | 3855 | ||
3807 | if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { | 3856 | if (S_ISREG(inode->i_mode) && (attr->ia_valid & ATTR_SIZE)) { |
3808 | err = btrfs_setsize(inode, attr->ia_size); | 3857 | err = btrfs_setsize(inode, attr); |
3809 | if (err) | 3858 | if (err) |
3810 | return err; | 3859 | return err; |
3811 | } | 3860 | } |
@@ -5586,10 +5635,13 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag | |||
5586 | return em; | 5635 | return em; |
5587 | if (em) { | 5636 | if (em) { |
5588 | /* | 5637 | /* |
5589 | * if our em maps to a hole, there might | 5638 | * if our em maps to |
5590 | * actually be delalloc bytes behind it | 5639 | * - a hole or |
5640 | * - a pre-alloc extent, | ||
5641 | * there might actually be delalloc bytes behind it. | ||
5591 | */ | 5642 | */ |
5592 | if (em->block_start != EXTENT_MAP_HOLE) | 5643 | if (em->block_start != EXTENT_MAP_HOLE && |
5644 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags)) | ||
5593 | return em; | 5645 | return em; |
5594 | else | 5646 | else |
5595 | hole_em = em; | 5647 | hole_em = em; |
@@ -5671,6 +5723,8 @@ struct extent_map *btrfs_get_extent_fiemap(struct inode *inode, struct page *pag | |||
5671 | */ | 5723 | */ |
5672 | em->block_start = hole_em->block_start; | 5724 | em->block_start = hole_em->block_start; |
5673 | em->block_len = hole_len; | 5725 | em->block_len = hole_len; |
5726 | if (test_bit(EXTENT_FLAG_PREALLOC, &hole_em->flags)) | ||
5727 | set_bit(EXTENT_FLAG_PREALLOC, &em->flags); | ||
5674 | } else { | 5728 | } else { |
5675 | em->start = range_start; | 5729 | em->start = range_start; |
5676 | em->len = found; | 5730 | em->len = found; |
@@ -6929,11 +6983,9 @@ static int btrfs_truncate(struct inode *inode) | |||
6929 | 6983 | ||
6930 | /* | 6984 | /* |
6931 | * 1 for the truncate slack space | 6985 | * 1 for the truncate slack space |
6932 | * 1 for the orphan item we're going to add | ||
6933 | * 1 for the orphan item deletion | ||
6934 | * 1 for updating the inode. | 6986 | * 1 for updating the inode. |
6935 | */ | 6987 | */ |
6936 | trans = btrfs_start_transaction(root, 4); | 6988 | trans = btrfs_start_transaction(root, 2); |
6937 | if (IS_ERR(trans)) { | 6989 | if (IS_ERR(trans)) { |
6938 | err = PTR_ERR(trans); | 6990 | err = PTR_ERR(trans); |
6939 | goto out; | 6991 | goto out; |
@@ -6944,12 +6996,6 @@ static int btrfs_truncate(struct inode *inode) | |||
6944 | min_size); | 6996 | min_size); |
6945 | BUG_ON(ret); | 6997 | BUG_ON(ret); |
6946 | 6998 | ||
6947 | ret = btrfs_orphan_add(trans, inode); | ||
6948 | if (ret) { | ||
6949 | btrfs_end_transaction(trans, root); | ||
6950 | goto out; | ||
6951 | } | ||
6952 | |||
6953 | /* | 6999 | /* |
6954 | * setattr is responsible for setting the ordered_data_close flag, | 7000 | * setattr is responsible for setting the ordered_data_close flag, |
6955 | * but that is only tested during the last file release. That | 7001 | * but that is only tested during the last file release. That |
@@ -7018,12 +7064,6 @@ static int btrfs_truncate(struct inode *inode) | |||
7018 | ret = btrfs_orphan_del(trans, inode); | 7064 | ret = btrfs_orphan_del(trans, inode); |
7019 | if (ret) | 7065 | if (ret) |
7020 | err = ret; | 7066 | err = ret; |
7021 | } else if (ret && inode->i_nlink > 0) { | ||
7022 | /* | ||
7023 | * Failed to do the truncate, remove us from the in memory | ||
7024 | * orphan list. | ||
7025 | */ | ||
7026 | ret = btrfs_orphan_del(NULL, inode); | ||
7027 | } | 7067 | } |
7028 | 7068 | ||
7029 | if (trans) { | 7069 | if (trans) { |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 7624212ae926..982c0b9ceea5 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -1339,6 +1339,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, | |||
1339 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, | 1339 | if (atomic_xchg(&root->fs_info->mutually_exclusive_operation_running, |
1340 | 1)) { | 1340 | 1)) { |
1341 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); | 1341 | pr_info("btrfs: dev add/delete/balance/replace/resize operation in progress\n"); |
1342 | mnt_drop_write_file(file); | ||
1342 | return -EINPROGRESS; | 1343 | return -EINPROGRESS; |
1343 | } | 1344 | } |
1344 | 1345 | ||
@@ -1362,6 +1363,7 @@ static noinline int btrfs_ioctl_resize(struct file *file, | |||
1362 | printk(KERN_INFO "btrfs: resizing devid %llu\n", | 1363 | printk(KERN_INFO "btrfs: resizing devid %llu\n", |
1363 | (unsigned long long)devid); | 1364 | (unsigned long long)devid); |
1364 | } | 1365 | } |
1366 | |||
1365 | device = btrfs_find_device(root->fs_info, devid, NULL, NULL); | 1367 | device = btrfs_find_device(root->fs_info, devid, NULL, NULL); |
1366 | if (!device) { | 1368 | if (!device) { |
1367 | printk(KERN_INFO "btrfs: resizer unable to find device %llu\n", | 1369 | printk(KERN_INFO "btrfs: resizer unable to find device %llu\n", |
@@ -1369,9 +1371,10 @@ static noinline int btrfs_ioctl_resize(struct file *file, | |||
1369 | ret = -EINVAL; | 1371 | ret = -EINVAL; |
1370 | goto out_free; | 1372 | goto out_free; |
1371 | } | 1373 | } |
1372 | if (device->fs_devices && device->fs_devices->seeding) { | 1374 | |
1375 | if (!device->writeable) { | ||
1373 | printk(KERN_INFO "btrfs: resizer unable to apply on " | 1376 | printk(KERN_INFO "btrfs: resizer unable to apply on " |
1374 | "seeding device %llu\n", | 1377 | "readonly device %llu\n", |
1375 | (unsigned long long)devid); | 1378 | (unsigned long long)devid); |
1376 | ret = -EINVAL; | 1379 | ret = -EINVAL; |
1377 | goto out_free; | 1380 | goto out_free; |
@@ -2095,13 +2098,13 @@ static noinline int btrfs_ioctl_snap_destroy(struct file *file, | |||
2095 | err = inode_permission(inode, MAY_WRITE | MAY_EXEC); | 2098 | err = inode_permission(inode, MAY_WRITE | MAY_EXEC); |
2096 | if (err) | 2099 | if (err) |
2097 | goto out_dput; | 2100 | goto out_dput; |
2098 | |||
2099 | /* check if subvolume may be deleted by a non-root user */ | ||
2100 | err = btrfs_may_delete(dir, dentry, 1); | ||
2101 | if (err) | ||
2102 | goto out_dput; | ||
2103 | } | 2101 | } |
2104 | 2102 | ||
2103 | /* check if subvolume may be deleted by a user */ | ||
2104 | err = btrfs_may_delete(dir, dentry, 1); | ||
2105 | if (err) | ||
2106 | goto out_dput; | ||
2107 | |||
2105 | if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { | 2108 | if (btrfs_ino(inode) != BTRFS_FIRST_FREE_OBJECTID) { |
2106 | err = -EINVAL; | 2109 | err = -EINVAL; |
2107 | goto out_dput; | 2110 | goto out_dput; |
@@ -3698,6 +3701,11 @@ static long btrfs_ioctl_qgroup_create(struct file *file, void __user *arg) | |||
3698 | goto drop_write; | 3701 | goto drop_write; |
3699 | } | 3702 | } |
3700 | 3703 | ||
3704 | if (!sa->qgroupid) { | ||
3705 | ret = -EINVAL; | ||
3706 | goto out; | ||
3707 | } | ||
3708 | |||
3701 | trans = btrfs_join_transaction(root); | 3709 | trans = btrfs_join_transaction(root); |
3702 | if (IS_ERR(trans)) { | 3710 | if (IS_ERR(trans)) { |
3703 | ret = PTR_ERR(trans); | 3711 | ret = PTR_ERR(trans); |
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c index 54454542ad40..321b7fb4e441 100644 --- a/fs/btrfs/send.c +++ b/fs/btrfs/send.c | |||
@@ -1814,8 +1814,10 @@ static int name_cache_insert(struct send_ctx *sctx, | |||
1814 | (unsigned long)nce->ino); | 1814 | (unsigned long)nce->ino); |
1815 | if (!nce_head) { | 1815 | if (!nce_head) { |
1816 | nce_head = kmalloc(sizeof(*nce_head), GFP_NOFS); | 1816 | nce_head = kmalloc(sizeof(*nce_head), GFP_NOFS); |
1817 | if (!nce_head) | 1817 | if (!nce_head) { |
1818 | kfree(nce); | ||
1818 | return -ENOMEM; | 1819 | return -ENOMEM; |
1820 | } | ||
1819 | INIT_LIST_HEAD(nce_head); | 1821 | INIT_LIST_HEAD(nce_head); |
1820 | 1822 | ||
1821 | ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head); | 1823 | ret = radix_tree_insert(&sctx->name_cache, nce->ino, nce_head); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 5cce6aa74012..86279c37de64 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1431,7 +1431,7 @@ int btrfs_rm_device(struct btrfs_root *root, char *device_path) | |||
1431 | } | 1431 | } |
1432 | } else { | 1432 | } else { |
1433 | ret = btrfs_get_bdev_and_sb(device_path, | 1433 | ret = btrfs_get_bdev_and_sb(device_path, |
1434 | FMODE_READ | FMODE_EXCL, | 1434 | FMODE_WRITE | FMODE_EXCL, |
1435 | root->fs_info->bdev_holder, 0, | 1435 | root->fs_info->bdev_holder, 0, |
1436 | &bdev, &bh); | 1436 | &bdev, &bh); |
1437 | if (ret) | 1437 | if (ret) |