diff options
Diffstat (limited to 'fs')
33 files changed, 301 insertions, 164 deletions
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 80953528572d..68f322f600a0 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -3163,6 +3163,9 @@ void btrfs_destroy_inode(struct inode *inode); | |||
3163 | int btrfs_drop_inode(struct inode *inode); | 3163 | int btrfs_drop_inode(struct inode *inode); |
3164 | int __init btrfs_init_cachep(void); | 3164 | int __init btrfs_init_cachep(void); |
3165 | void __cold btrfs_destroy_cachep(void); | 3165 | void __cold btrfs_destroy_cachep(void); |
3166 | struct inode *btrfs_iget_path(struct super_block *s, struct btrfs_key *location, | ||
3167 | struct btrfs_root *root, int *new, | ||
3168 | struct btrfs_path *path); | ||
3166 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | 3169 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, |
3167 | struct btrfs_root *root, int *was_new); | 3170 | struct btrfs_root *root, int *was_new); |
3168 | struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, | 3171 | struct extent_map *btrfs_get_extent(struct btrfs_inode *inode, |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index b0ab41da91d1..3f0b6d1936e8 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1664,9 +1664,8 @@ static int cleaner_kthread(void *arg) | |||
1664 | struct btrfs_root *root = arg; | 1664 | struct btrfs_root *root = arg; |
1665 | struct btrfs_fs_info *fs_info = root->fs_info; | 1665 | struct btrfs_fs_info *fs_info = root->fs_info; |
1666 | int again; | 1666 | int again; |
1667 | struct btrfs_trans_handle *trans; | ||
1668 | 1667 | ||
1669 | do { | 1668 | while (1) { |
1670 | again = 0; | 1669 | again = 0; |
1671 | 1670 | ||
1672 | /* Make the cleaner go to sleep early. */ | 1671 | /* Make the cleaner go to sleep early. */ |
@@ -1715,42 +1714,16 @@ static int cleaner_kthread(void *arg) | |||
1715 | */ | 1714 | */ |
1716 | btrfs_delete_unused_bgs(fs_info); | 1715 | btrfs_delete_unused_bgs(fs_info); |
1717 | sleep: | 1716 | sleep: |
1717 | if (kthread_should_park()) | ||
1718 | kthread_parkme(); | ||
1719 | if (kthread_should_stop()) | ||
1720 | return 0; | ||
1718 | if (!again) { | 1721 | if (!again) { |
1719 | set_current_state(TASK_INTERRUPTIBLE); | 1722 | set_current_state(TASK_INTERRUPTIBLE); |
1720 | if (!kthread_should_stop()) | 1723 | schedule(); |
1721 | schedule(); | ||
1722 | __set_current_state(TASK_RUNNING); | 1724 | __set_current_state(TASK_RUNNING); |
1723 | } | 1725 | } |
1724 | } while (!kthread_should_stop()); | ||
1725 | |||
1726 | /* | ||
1727 | * Transaction kthread is stopped before us and wakes us up. | ||
1728 | * However we might have started a new transaction and COWed some | ||
1729 | * tree blocks when deleting unused block groups for example. So | ||
1730 | * make sure we commit the transaction we started to have a clean | ||
1731 | * shutdown when evicting the btree inode - if it has dirty pages | ||
1732 | * when we do the final iput() on it, eviction will trigger a | ||
1733 | * writeback for it which will fail with null pointer dereferences | ||
1734 | * since work queues and other resources were already released and | ||
1735 | * destroyed by the time the iput/eviction/writeback is made. | ||
1736 | */ | ||
1737 | trans = btrfs_attach_transaction(root); | ||
1738 | if (IS_ERR(trans)) { | ||
1739 | if (PTR_ERR(trans) != -ENOENT) | ||
1740 | btrfs_err(fs_info, | ||
1741 | "cleaner transaction attach returned %ld", | ||
1742 | PTR_ERR(trans)); | ||
1743 | } else { | ||
1744 | int ret; | ||
1745 | |||
1746 | ret = btrfs_commit_transaction(trans); | ||
1747 | if (ret) | ||
1748 | btrfs_err(fs_info, | ||
1749 | "cleaner open transaction commit returned %d", | ||
1750 | ret); | ||
1751 | } | 1726 | } |
1752 | |||
1753 | return 0; | ||
1754 | } | 1727 | } |
1755 | 1728 | ||
1756 | static int transaction_kthread(void *arg) | 1729 | static int transaction_kthread(void *arg) |
@@ -3931,6 +3904,13 @@ void close_ctree(struct btrfs_fs_info *fs_info) | |||
3931 | int ret; | 3904 | int ret; |
3932 | 3905 | ||
3933 | set_bit(BTRFS_FS_CLOSING_START, &fs_info->flags); | 3906 | set_bit(BTRFS_FS_CLOSING_START, &fs_info->flags); |
3907 | /* | ||
3908 | * We don't want the cleaner to start new transactions, add more delayed | ||
3909 | * iputs, etc. while we're closing. We can't use kthread_stop() yet | ||
3910 | * because that frees the task_struct, and the transaction kthread might | ||
3911 | * still try to wake up the cleaner. | ||
3912 | */ | ||
3913 | kthread_park(fs_info->cleaner_kthread); | ||
3934 | 3914 | ||
3935 | /* wait for the qgroup rescan worker to stop */ | 3915 | /* wait for the qgroup rescan worker to stop */ |
3936 | btrfs_qgroup_wait_for_completion(fs_info, false); | 3916 | btrfs_qgroup_wait_for_completion(fs_info, false); |
@@ -3958,9 +3938,8 @@ void close_ctree(struct btrfs_fs_info *fs_info) | |||
3958 | 3938 | ||
3959 | if (!sb_rdonly(fs_info->sb)) { | 3939 | if (!sb_rdonly(fs_info->sb)) { |
3960 | /* | 3940 | /* |
3961 | * If the cleaner thread is stopped and there are | 3941 | * The cleaner kthread is stopped, so do one final pass over |
3962 | * block groups queued for removal, the deletion will be | 3942 | * unused block groups. |
3963 | * skipped when we quit the cleaner thread. | ||
3964 | */ | 3943 | */ |
3965 | btrfs_delete_unused_bgs(fs_info); | 3944 | btrfs_delete_unused_bgs(fs_info); |
3966 | 3945 | ||
@@ -4359,13 +4338,23 @@ static int btrfs_destroy_pinned_extent(struct btrfs_fs_info *fs_info, | |||
4359 | unpin = pinned_extents; | 4338 | unpin = pinned_extents; |
4360 | again: | 4339 | again: |
4361 | while (1) { | 4340 | while (1) { |
4341 | /* | ||
4342 | * The btrfs_finish_extent_commit() may get the same range as | ||
4343 | * ours between find_first_extent_bit and clear_extent_dirty. | ||
4344 | * Hence, hold the unused_bg_unpin_mutex to avoid double unpin | ||
4345 | * the same extent range. | ||
4346 | */ | ||
4347 | mutex_lock(&fs_info->unused_bg_unpin_mutex); | ||
4362 | ret = find_first_extent_bit(unpin, 0, &start, &end, | 4348 | ret = find_first_extent_bit(unpin, 0, &start, &end, |
4363 | EXTENT_DIRTY, NULL); | 4349 | EXTENT_DIRTY, NULL); |
4364 | if (ret) | 4350 | if (ret) { |
4351 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); | ||
4365 | break; | 4352 | break; |
4353 | } | ||
4366 | 4354 | ||
4367 | clear_extent_dirty(unpin, start, end); | 4355 | clear_extent_dirty(unpin, start, end); |
4368 | btrfs_error_unpin_extent_range(fs_info, start, end); | 4356 | btrfs_error_unpin_extent_range(fs_info, start, end); |
4357 | mutex_unlock(&fs_info->unused_bg_unpin_mutex); | ||
4369 | cond_resched(); | 4358 | cond_resched(); |
4370 | } | 4359 | } |
4371 | 4360 | ||
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index 4ba0aedc878b..74aa552f4793 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -75,7 +75,8 @@ static struct inode *__lookup_free_space_inode(struct btrfs_root *root, | |||
75 | * sure NOFS is set to keep us from deadlocking. | 75 | * sure NOFS is set to keep us from deadlocking. |
76 | */ | 76 | */ |
77 | nofs_flag = memalloc_nofs_save(); | 77 | nofs_flag = memalloc_nofs_save(); |
78 | inode = btrfs_iget(fs_info->sb, &location, root, NULL); | 78 | inode = btrfs_iget_path(fs_info->sb, &location, root, NULL, path); |
79 | btrfs_release_path(path); | ||
79 | memalloc_nofs_restore(nofs_flag); | 80 | memalloc_nofs_restore(nofs_flag); |
80 | if (IS_ERR(inode)) | 81 | if (IS_ERR(inode)) |
81 | return inode; | 82 | return inode; |
@@ -838,6 +839,25 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, | |||
838 | path->search_commit_root = 1; | 839 | path->search_commit_root = 1; |
839 | path->skip_locking = 1; | 840 | path->skip_locking = 1; |
840 | 841 | ||
842 | /* | ||
843 | * We must pass a path with search_commit_root set to btrfs_iget in | ||
844 | * order to avoid a deadlock when allocating extents for the tree root. | ||
845 | * | ||
846 | * When we are COWing an extent buffer from the tree root, when looking | ||
847 | * for a free extent, at extent-tree.c:find_free_extent(), we can find | ||
848 | * block group without its free space cache loaded. When we find one | ||
849 | * we must load its space cache which requires reading its free space | ||
850 | * cache's inode item from the root tree. If this inode item is located | ||
851 | * in the same leaf that we started COWing before, then we end up in | ||
852 | * deadlock on the extent buffer (trying to read lock it when we | ||
853 | * previously write locked it). | ||
854 | * | ||
855 | * It's safe to read the inode item using the commit root because | ||
856 | * block groups, once loaded, stay in memory forever (until they are | ||
857 | * removed) as well as their space caches once loaded. New block groups | ||
858 | * once created get their ->cached field set to BTRFS_CACHE_FINISHED so | ||
859 | * we will never try to read their inode item while the fs is mounted. | ||
860 | */ | ||
841 | inode = lookup_free_space_inode(fs_info, block_group, path); | 861 | inode = lookup_free_space_inode(fs_info, block_group, path); |
842 | if (IS_ERR(inode)) { | 862 | if (IS_ERR(inode)) { |
843 | btrfs_free_path(path); | 863 | btrfs_free_path(path); |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index d3df5b52278c..9ea4c6f0352f 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1531,12 +1531,11 @@ out_check: | |||
1531 | } | 1531 | } |
1532 | btrfs_release_path(path); | 1532 | btrfs_release_path(path); |
1533 | 1533 | ||
1534 | if (cur_offset <= end && cow_start == (u64)-1) { | 1534 | if (cur_offset <= end && cow_start == (u64)-1) |
1535 | cow_start = cur_offset; | 1535 | cow_start = cur_offset; |
1536 | cur_offset = end; | ||
1537 | } | ||
1538 | 1536 | ||
1539 | if (cow_start != (u64)-1) { | 1537 | if (cow_start != (u64)-1) { |
1538 | cur_offset = end; | ||
1540 | ret = cow_file_range(inode, locked_page, cow_start, end, end, | 1539 | ret = cow_file_range(inode, locked_page, cow_start, end, end, |
1541 | page_started, nr_written, 1, NULL); | 1540 | page_started, nr_written, 1, NULL); |
1542 | if (ret) | 1541 | if (ret) |
@@ -3570,10 +3569,11 @@ static noinline int acls_after_inode_item(struct extent_buffer *leaf, | |||
3570 | /* | 3569 | /* |
3571 | * read an inode from the btree into the in-memory inode | 3570 | * read an inode from the btree into the in-memory inode |
3572 | */ | 3571 | */ |
3573 | static int btrfs_read_locked_inode(struct inode *inode) | 3572 | static int btrfs_read_locked_inode(struct inode *inode, |
3573 | struct btrfs_path *in_path) | ||
3574 | { | 3574 | { |
3575 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); | 3575 | struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb); |
3576 | struct btrfs_path *path; | 3576 | struct btrfs_path *path = in_path; |
3577 | struct extent_buffer *leaf; | 3577 | struct extent_buffer *leaf; |
3578 | struct btrfs_inode_item *inode_item; | 3578 | struct btrfs_inode_item *inode_item; |
3579 | struct btrfs_root *root = BTRFS_I(inode)->root; | 3579 | struct btrfs_root *root = BTRFS_I(inode)->root; |
@@ -3589,15 +3589,18 @@ static int btrfs_read_locked_inode(struct inode *inode) | |||
3589 | if (!ret) | 3589 | if (!ret) |
3590 | filled = true; | 3590 | filled = true; |
3591 | 3591 | ||
3592 | path = btrfs_alloc_path(); | 3592 | if (!path) { |
3593 | if (!path) | 3593 | path = btrfs_alloc_path(); |
3594 | return -ENOMEM; | 3594 | if (!path) |
3595 | return -ENOMEM; | ||
3596 | } | ||
3595 | 3597 | ||
3596 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); | 3598 | memcpy(&location, &BTRFS_I(inode)->location, sizeof(location)); |
3597 | 3599 | ||
3598 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); | 3600 | ret = btrfs_lookup_inode(NULL, root, path, &location, 0); |
3599 | if (ret) { | 3601 | if (ret) { |
3600 | btrfs_free_path(path); | 3602 | if (path != in_path) |
3603 | btrfs_free_path(path); | ||
3601 | return ret; | 3604 | return ret; |
3602 | } | 3605 | } |
3603 | 3606 | ||
@@ -3722,7 +3725,8 @@ cache_acl: | |||
3722 | btrfs_ino(BTRFS_I(inode)), | 3725 | btrfs_ino(BTRFS_I(inode)), |
3723 | root->root_key.objectid, ret); | 3726 | root->root_key.objectid, ret); |
3724 | } | 3727 | } |
3725 | btrfs_free_path(path); | 3728 | if (path != in_path) |
3729 | btrfs_free_path(path); | ||
3726 | 3730 | ||
3727 | if (!maybe_acls) | 3731 | if (!maybe_acls) |
3728 | cache_no_acl(inode); | 3732 | cache_no_acl(inode); |
@@ -5644,8 +5648,9 @@ static struct inode *btrfs_iget_locked(struct super_block *s, | |||
5644 | /* Get an inode object given its location and corresponding root. | 5648 | /* Get an inode object given its location and corresponding root. |
5645 | * Returns in *is_new if the inode was read from disk | 5649 | * Returns in *is_new if the inode was read from disk |
5646 | */ | 5650 | */ |
5647 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | 5651 | struct inode *btrfs_iget_path(struct super_block *s, struct btrfs_key *location, |
5648 | struct btrfs_root *root, int *new) | 5652 | struct btrfs_root *root, int *new, |
5653 | struct btrfs_path *path) | ||
5649 | { | 5654 | { |
5650 | struct inode *inode; | 5655 | struct inode *inode; |
5651 | 5656 | ||
@@ -5656,7 +5661,7 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
5656 | if (inode->i_state & I_NEW) { | 5661 | if (inode->i_state & I_NEW) { |
5657 | int ret; | 5662 | int ret; |
5658 | 5663 | ||
5659 | ret = btrfs_read_locked_inode(inode); | 5664 | ret = btrfs_read_locked_inode(inode, path); |
5660 | if (!ret) { | 5665 | if (!ret) { |
5661 | inode_tree_add(inode); | 5666 | inode_tree_add(inode); |
5662 | unlock_new_inode(inode); | 5667 | unlock_new_inode(inode); |
@@ -5678,6 +5683,12 @@ struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | |||
5678 | return inode; | 5683 | return inode; |
5679 | } | 5684 | } |
5680 | 5685 | ||
5686 | struct inode *btrfs_iget(struct super_block *s, struct btrfs_key *location, | ||
5687 | struct btrfs_root *root, int *new) | ||
5688 | { | ||
5689 | return btrfs_iget_path(s, location, root, new, NULL); | ||
5690 | } | ||
5691 | |||
5681 | static struct inode *new_simple_dir(struct super_block *s, | 5692 | static struct inode *new_simple_dir(struct super_block *s, |
5682 | struct btrfs_key *key, | 5693 | struct btrfs_key *key, |
5683 | struct btrfs_root *root) | 5694 | struct btrfs_root *root) |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 3ca6943827ef..802a628e9f7d 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -3488,6 +3488,8 @@ static int btrfs_extent_same_range(struct inode *src, u64 loff, u64 olen, | |||
3488 | const u64 sz = BTRFS_I(src)->root->fs_info->sectorsize; | 3488 | const u64 sz = BTRFS_I(src)->root->fs_info->sectorsize; |
3489 | 3489 | ||
3490 | len = round_down(i_size_read(src), sz) - loff; | 3490 | len = round_down(i_size_read(src), sz) - loff; |
3491 | if (len == 0) | ||
3492 | return 0; | ||
3491 | olen = len; | 3493 | olen = len; |
3492 | } | 3494 | } |
3493 | } | 3495 | } |
@@ -4257,9 +4259,17 @@ static noinline int btrfs_clone_files(struct file *file, struct file *file_src, | |||
4257 | goto out_unlock; | 4259 | goto out_unlock; |
4258 | if (len == 0) | 4260 | if (len == 0) |
4259 | olen = len = src->i_size - off; | 4261 | olen = len = src->i_size - off; |
4260 | /* if we extend to eof, continue to block boundary */ | 4262 | /* |
4261 | if (off + len == src->i_size) | 4263 | * If we extend to eof, continue to block boundary if and only if the |
4264 | * destination end offset matches the destination file's size, otherwise | ||
4265 | * we would be corrupting data by placing the eof block into the middle | ||
4266 | * of a file. | ||
4267 | */ | ||
4268 | if (off + len == src->i_size) { | ||
4269 | if (!IS_ALIGNED(len, bs) && destoff + len < inode->i_size) | ||
4270 | goto out_unlock; | ||
4262 | len = ALIGN(src->i_size, bs) - off; | 4271 | len = ALIGN(src->i_size, bs) - off; |
4272 | } | ||
4263 | 4273 | ||
4264 | if (len == 0) { | 4274 | if (len == 0) { |
4265 | ret = 0; | 4275 | ret = 0; |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index b362b45dd757..cbc9d0d2c12d 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -1916,7 +1916,7 @@ restore: | |||
1916 | } | 1916 | } |
1917 | 1917 | ||
1918 | /* Used to sort the devices by max_avail(descending sort) */ | 1918 | /* Used to sort the devices by max_avail(descending sort) */ |
1919 | static int btrfs_cmp_device_free_bytes(const void *dev_info1, | 1919 | static inline int btrfs_cmp_device_free_bytes(const void *dev_info1, |
1920 | const void *dev_info2) | 1920 | const void *dev_info2) |
1921 | { | 1921 | { |
1922 | if (((struct btrfs_device_info *)dev_info1)->max_avail > | 1922 | if (((struct btrfs_device_info *)dev_info1)->max_avail > |
@@ -1945,8 +1945,8 @@ static inline void btrfs_descending_sort_devices( | |||
1945 | * The helper to calc the free space on the devices that can be used to store | 1945 | * The helper to calc the free space on the devices that can be used to store |
1946 | * file data. | 1946 | * file data. |
1947 | */ | 1947 | */ |
1948 | static int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info, | 1948 | static inline int btrfs_calc_avail_data_space(struct btrfs_fs_info *fs_info, |
1949 | u64 *free_bytes) | 1949 | u64 *free_bytes) |
1950 | { | 1950 | { |
1951 | struct btrfs_device_info *devices_info; | 1951 | struct btrfs_device_info *devices_info; |
1952 | struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; | 1952 | struct btrfs_fs_devices *fs_devices = fs_info->fs_devices; |
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index cab0b1f1f741..efcf89a8ba44 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c | |||
@@ -440,7 +440,7 @@ static int check_block_group_item(struct btrfs_fs_info *fs_info, | |||
440 | type != (BTRFS_BLOCK_GROUP_METADATA | | 440 | type != (BTRFS_BLOCK_GROUP_METADATA | |
441 | BTRFS_BLOCK_GROUP_DATA)) { | 441 | BTRFS_BLOCK_GROUP_DATA)) { |
442 | block_group_err(fs_info, leaf, slot, | 442 | block_group_err(fs_info, leaf, slot, |
443 | "invalid type, have 0x%llx (%lu bits set) expect either 0x%llx, 0x%llx, 0x%llu or 0x%llx", | 443 | "invalid type, have 0x%llx (%lu bits set) expect either 0x%llx, 0x%llx, 0x%llx or 0x%llx", |
444 | type, hweight64(type), | 444 | type, hweight64(type), |
445 | BTRFS_BLOCK_GROUP_DATA, BTRFS_BLOCK_GROUP_METADATA, | 445 | BTRFS_BLOCK_GROUP_DATA, BTRFS_BLOCK_GROUP_METADATA, |
446 | BTRFS_BLOCK_GROUP_SYSTEM, | 446 | BTRFS_BLOCK_GROUP_SYSTEM, |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index e07f3376b7df..a5ce99a6c936 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -4396,6 +4396,23 @@ static int btrfs_log_changed_extents(struct btrfs_trans_handle *trans, | |||
4396 | logged_end = end; | 4396 | logged_end = end; |
4397 | 4397 | ||
4398 | list_for_each_entry_safe(em, n, &tree->modified_extents, list) { | 4398 | list_for_each_entry_safe(em, n, &tree->modified_extents, list) { |
4399 | /* | ||
4400 | * Skip extents outside our logging range. It's important to do | ||
4401 | * it for correctness because if we don't ignore them, we may | ||
4402 | * log them before their ordered extent completes, and therefore | ||
4403 | * we could log them without logging their respective checksums | ||
4404 | * (the checksum items are added to the csum tree at the very | ||
4405 | * end of btrfs_finish_ordered_io()). Also leave such extents | ||
4406 | * outside of our range in the list, since we may have another | ||
4407 | * ranged fsync in the near future that needs them. If an extent | ||
4408 | * outside our range corresponds to a hole, log it to avoid | ||
4409 | * leaving gaps between extents (fsck will complain when we are | ||
4410 | * not using the NO_HOLES feature). | ||
4411 | */ | ||
4412 | if ((em->start > end || em->start + em->len <= start) && | ||
4413 | em->block_start != EXTENT_MAP_HOLE) | ||
4414 | continue; | ||
4415 | |||
4399 | list_del_init(&em->list); | 4416 | list_del_init(&em->list); |
4400 | /* | 4417 | /* |
4401 | * Just an arbitrary number, this can be really CPU intensive | 4418 | * Just an arbitrary number, this can be really CPU intensive |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 27cad84dab23..189df668b6a0 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -1931,10 +1931,17 @@ static ssize_t ceph_copy_file_range(struct file *src_file, loff_t src_off, | |||
1931 | if (!prealloc_cf) | 1931 | if (!prealloc_cf) |
1932 | return -ENOMEM; | 1932 | return -ENOMEM; |
1933 | 1933 | ||
1934 | /* Start by sync'ing the source file */ | 1934 | /* Start by sync'ing the source and destination files */ |
1935 | ret = file_write_and_wait_range(src_file, src_off, (src_off + len)); | 1935 | ret = file_write_and_wait_range(src_file, src_off, (src_off + len)); |
1936 | if (ret < 0) | 1936 | if (ret < 0) { |
1937 | dout("failed to write src file (%zd)\n", ret); | ||
1938 | goto out; | ||
1939 | } | ||
1940 | ret = file_write_and_wait_range(dst_file, dst_off, (dst_off + len)); | ||
1941 | if (ret < 0) { | ||
1942 | dout("failed to write dst file (%zd)\n", ret); | ||
1937 | goto out; | 1943 | goto out; |
1944 | } | ||
1938 | 1945 | ||
1939 | /* | 1946 | /* |
1940 | * We need FILE_WR caps for dst_ci and FILE_RD for src_ci as other | 1947 | * We need FILE_WR caps for dst_ci and FILE_RD for src_ci as other |
diff --git a/fs/ceph/mds_client.c b/fs/ceph/mds_client.c index 67a9aeb2f4ec..bd13a3267ae0 100644 --- a/fs/ceph/mds_client.c +++ b/fs/ceph/mds_client.c | |||
@@ -80,12 +80,8 @@ static int parse_reply_info_in(void **p, void *end, | |||
80 | info->symlink = *p; | 80 | info->symlink = *p; |
81 | *p += info->symlink_len; | 81 | *p += info->symlink_len; |
82 | 82 | ||
83 | if (features & CEPH_FEATURE_DIRLAYOUTHASH) | 83 | ceph_decode_copy_safe(p, end, &info->dir_layout, |
84 | ceph_decode_copy_safe(p, end, &info->dir_layout, | 84 | sizeof(info->dir_layout), bad); |
85 | sizeof(info->dir_layout), bad); | ||
86 | else | ||
87 | memset(&info->dir_layout, 0, sizeof(info->dir_layout)); | ||
88 | |||
89 | ceph_decode_32_safe(p, end, info->xattr_len, bad); | 85 | ceph_decode_32_safe(p, end, info->xattr_len, bad); |
90 | ceph_decode_need(p, end, info->xattr_len, bad); | 86 | ceph_decode_need(p, end, info->xattr_len, bad); |
91 | info->xattr_data = *p; | 87 | info->xattr_data = *p; |
@@ -3182,10 +3178,8 @@ static void send_mds_reconnect(struct ceph_mds_client *mdsc, | |||
3182 | recon_state.pagelist = pagelist; | 3178 | recon_state.pagelist = pagelist; |
3183 | if (session->s_con.peer_features & CEPH_FEATURE_MDSENC) | 3179 | if (session->s_con.peer_features & CEPH_FEATURE_MDSENC) |
3184 | recon_state.msg_version = 3; | 3180 | recon_state.msg_version = 3; |
3185 | else if (session->s_con.peer_features & CEPH_FEATURE_FLOCK) | ||
3186 | recon_state.msg_version = 2; | ||
3187 | else | 3181 | else |
3188 | recon_state.msg_version = 1; | 3182 | recon_state.msg_version = 2; |
3189 | err = iterate_session_caps(session, encode_caps_cb, &recon_state); | 3183 | err = iterate_session_caps(session, encode_caps_cb, &recon_state); |
3190 | if (err < 0) | 3184 | if (err < 0) |
3191 | goto fail; | 3185 | goto fail; |
diff --git a/fs/ceph/quota.c b/fs/ceph/quota.c index 32d4f13784ba..03f4d24db8fe 100644 --- a/fs/ceph/quota.c +++ b/fs/ceph/quota.c | |||
@@ -237,7 +237,8 @@ static bool check_quota_exceeded(struct inode *inode, enum quota_check_op op, | |||
237 | ceph_put_snap_realm(mdsc, realm); | 237 | ceph_put_snap_realm(mdsc, realm); |
238 | realm = next; | 238 | realm = next; |
239 | } | 239 | } |
240 | ceph_put_snap_realm(mdsc, realm); | 240 | if (realm) |
241 | ceph_put_snap_realm(mdsc, realm); | ||
241 | up_read(&mdsc->snap_rwsem); | 242 | up_read(&mdsc->snap_rwsem); |
242 | 243 | ||
243 | return exceeded; | 244 | return exceeded; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 05f01fbd9c7f..22a9d8159720 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -5835,9 +5835,10 @@ int ext4_mark_iloc_dirty(handle_t *handle, | |||
5835 | { | 5835 | { |
5836 | int err = 0; | 5836 | int err = 0; |
5837 | 5837 | ||
5838 | if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) | 5838 | if (unlikely(ext4_forced_shutdown(EXT4_SB(inode->i_sb)))) { |
5839 | put_bh(iloc->bh); | ||
5839 | return -EIO; | 5840 | return -EIO; |
5840 | 5841 | } | |
5841 | if (IS_I_VERSION(inode)) | 5842 | if (IS_I_VERSION(inode)) |
5842 | inode_inc_iversion(inode); | 5843 | inode_inc_iversion(inode); |
5843 | 5844 | ||
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 17adcb16a9c8..437f71fe83ae 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -126,6 +126,7 @@ static struct buffer_head *__ext4_read_dirblock(struct inode *inode, | |||
126 | if (!is_dx_block && type == INDEX) { | 126 | if (!is_dx_block && type == INDEX) { |
127 | ext4_error_inode(inode, func, line, block, | 127 | ext4_error_inode(inode, func, line, block, |
128 | "directory leaf block found instead of index block"); | 128 | "directory leaf block found instead of index block"); |
129 | brelse(bh); | ||
129 | return ERR_PTR(-EFSCORRUPTED); | 130 | return ERR_PTR(-EFSCORRUPTED); |
130 | } | 131 | } |
131 | if (!ext4_has_metadata_csum(inode->i_sb) || | 132 | if (!ext4_has_metadata_csum(inode->i_sb) || |
@@ -2811,7 +2812,9 @@ int ext4_orphan_add(handle_t *handle, struct inode *inode) | |||
2811 | list_del_init(&EXT4_I(inode)->i_orphan); | 2812 | list_del_init(&EXT4_I(inode)->i_orphan); |
2812 | mutex_unlock(&sbi->s_orphan_lock); | 2813 | mutex_unlock(&sbi->s_orphan_lock); |
2813 | } | 2814 | } |
2814 | } | 2815 | } else |
2816 | brelse(iloc.bh); | ||
2817 | |||
2815 | jbd_debug(4, "superblock will point to %lu\n", inode->i_ino); | 2818 | jbd_debug(4, "superblock will point to %lu\n", inode->i_ino); |
2816 | jbd_debug(4, "orphan inode %lu will point to %d\n", | 2819 | jbd_debug(4, "orphan inode %lu will point to %d\n", |
2817 | inode->i_ino, NEXT_ORPHAN(inode)); | 2820 | inode->i_ino, NEXT_ORPHAN(inode)); |
diff --git a/fs/ext4/resize.c b/fs/ext4/resize.c index ebbc663d0798..a5efee34415f 100644 --- a/fs/ext4/resize.c +++ b/fs/ext4/resize.c | |||
@@ -459,16 +459,18 @@ static int set_flexbg_block_bitmap(struct super_block *sb, handle_t *handle, | |||
459 | 459 | ||
460 | BUFFER_TRACE(bh, "get_write_access"); | 460 | BUFFER_TRACE(bh, "get_write_access"); |
461 | err = ext4_journal_get_write_access(handle, bh); | 461 | err = ext4_journal_get_write_access(handle, bh); |
462 | if (err) | 462 | if (err) { |
463 | brelse(bh); | ||
463 | return err; | 464 | return err; |
465 | } | ||
464 | ext4_debug("mark block bitmap %#04llx (+%llu/%u)\n", | 466 | ext4_debug("mark block bitmap %#04llx (+%llu/%u)\n", |
465 | first_cluster, first_cluster - start, count2); | 467 | first_cluster, first_cluster - start, count2); |
466 | ext4_set_bits(bh->b_data, first_cluster - start, count2); | 468 | ext4_set_bits(bh->b_data, first_cluster - start, count2); |
467 | 469 | ||
468 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | 470 | err = ext4_handle_dirty_metadata(handle, NULL, bh); |
471 | brelse(bh); | ||
469 | if (unlikely(err)) | 472 | if (unlikely(err)) |
470 | return err; | 473 | return err; |
471 | brelse(bh); | ||
472 | } | 474 | } |
473 | 475 | ||
474 | return 0; | 476 | return 0; |
@@ -605,7 +607,6 @@ handle_bb: | |||
605 | bh = bclean(handle, sb, block); | 607 | bh = bclean(handle, sb, block); |
606 | if (IS_ERR(bh)) { | 608 | if (IS_ERR(bh)) { |
607 | err = PTR_ERR(bh); | 609 | err = PTR_ERR(bh); |
608 | bh = NULL; | ||
609 | goto out; | 610 | goto out; |
610 | } | 611 | } |
611 | overhead = ext4_group_overhead_blocks(sb, group); | 612 | overhead = ext4_group_overhead_blocks(sb, group); |
@@ -618,9 +619,9 @@ handle_bb: | |||
618 | ext4_mark_bitmap_end(EXT4_B2C(sbi, group_data[i].blocks_count), | 619 | ext4_mark_bitmap_end(EXT4_B2C(sbi, group_data[i].blocks_count), |
619 | sb->s_blocksize * 8, bh->b_data); | 620 | sb->s_blocksize * 8, bh->b_data); |
620 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | 621 | err = ext4_handle_dirty_metadata(handle, NULL, bh); |
622 | brelse(bh); | ||
621 | if (err) | 623 | if (err) |
622 | goto out; | 624 | goto out; |
623 | brelse(bh); | ||
624 | 625 | ||
625 | handle_ib: | 626 | handle_ib: |
626 | if (bg_flags[i] & EXT4_BG_INODE_UNINIT) | 627 | if (bg_flags[i] & EXT4_BG_INODE_UNINIT) |
@@ -635,18 +636,16 @@ handle_ib: | |||
635 | bh = bclean(handle, sb, block); | 636 | bh = bclean(handle, sb, block); |
636 | if (IS_ERR(bh)) { | 637 | if (IS_ERR(bh)) { |
637 | err = PTR_ERR(bh); | 638 | err = PTR_ERR(bh); |
638 | bh = NULL; | ||
639 | goto out; | 639 | goto out; |
640 | } | 640 | } |
641 | 641 | ||
642 | ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), | 642 | ext4_mark_bitmap_end(EXT4_INODES_PER_GROUP(sb), |
643 | sb->s_blocksize * 8, bh->b_data); | 643 | sb->s_blocksize * 8, bh->b_data); |
644 | err = ext4_handle_dirty_metadata(handle, NULL, bh); | 644 | err = ext4_handle_dirty_metadata(handle, NULL, bh); |
645 | brelse(bh); | ||
645 | if (err) | 646 | if (err) |
646 | goto out; | 647 | goto out; |
647 | brelse(bh); | ||
648 | } | 648 | } |
649 | bh = NULL; | ||
650 | 649 | ||
651 | /* Mark group tables in block bitmap */ | 650 | /* Mark group tables in block bitmap */ |
652 | for (j = 0; j < GROUP_TABLE_COUNT; j++) { | 651 | for (j = 0; j < GROUP_TABLE_COUNT; j++) { |
@@ -685,7 +684,6 @@ handle_ib: | |||
685 | } | 684 | } |
686 | 685 | ||
687 | out: | 686 | out: |
688 | brelse(bh); | ||
689 | err2 = ext4_journal_stop(handle); | 687 | err2 = ext4_journal_stop(handle); |
690 | if (err2 && !err) | 688 | if (err2 && !err) |
691 | err = err2; | 689 | err = err2; |
@@ -873,6 +871,7 @@ static int add_new_gdb(handle_t *handle, struct inode *inode, | |||
873 | err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh); | 871 | err = ext4_handle_dirty_metadata(handle, NULL, gdb_bh); |
874 | if (unlikely(err)) { | 872 | if (unlikely(err)) { |
875 | ext4_std_error(sb, err); | 873 | ext4_std_error(sb, err); |
874 | iloc.bh = NULL; | ||
876 | goto exit_inode; | 875 | goto exit_inode; |
877 | } | 876 | } |
878 | brelse(dind); | 877 | brelse(dind); |
@@ -924,6 +923,7 @@ static int add_new_gdb_meta_bg(struct super_block *sb, | |||
924 | sizeof(struct buffer_head *), | 923 | sizeof(struct buffer_head *), |
925 | GFP_NOFS); | 924 | GFP_NOFS); |
926 | if (!n_group_desc) { | 925 | if (!n_group_desc) { |
926 | brelse(gdb_bh); | ||
927 | err = -ENOMEM; | 927 | err = -ENOMEM; |
928 | ext4_warning(sb, "not enough memory for %lu groups", | 928 | ext4_warning(sb, "not enough memory for %lu groups", |
929 | gdb_num + 1); | 929 | gdb_num + 1); |
@@ -939,8 +939,6 @@ static int add_new_gdb_meta_bg(struct super_block *sb, | |||
939 | kvfree(o_group_desc); | 939 | kvfree(o_group_desc); |
940 | BUFFER_TRACE(gdb_bh, "get_write_access"); | 940 | BUFFER_TRACE(gdb_bh, "get_write_access"); |
941 | err = ext4_journal_get_write_access(handle, gdb_bh); | 941 | err = ext4_journal_get_write_access(handle, gdb_bh); |
942 | if (unlikely(err)) | ||
943 | brelse(gdb_bh); | ||
944 | return err; | 942 | return err; |
945 | } | 943 | } |
946 | 944 | ||
@@ -1124,8 +1122,10 @@ static void update_backups(struct super_block *sb, sector_t blk_off, char *data, | |||
1124 | backup_block, backup_block - | 1122 | backup_block, backup_block - |
1125 | ext4_group_first_block_no(sb, group)); | 1123 | ext4_group_first_block_no(sb, group)); |
1126 | BUFFER_TRACE(bh, "get_write_access"); | 1124 | BUFFER_TRACE(bh, "get_write_access"); |
1127 | if ((err = ext4_journal_get_write_access(handle, bh))) | 1125 | if ((err = ext4_journal_get_write_access(handle, bh))) { |
1126 | brelse(bh); | ||
1128 | break; | 1127 | break; |
1128 | } | ||
1129 | lock_buffer(bh); | 1129 | lock_buffer(bh); |
1130 | memcpy(bh->b_data, data, size); | 1130 | memcpy(bh->b_data, data, size); |
1131 | if (rest) | 1131 | if (rest) |
@@ -2023,7 +2023,7 @@ retry: | |||
2023 | 2023 | ||
2024 | err = ext4_alloc_flex_bg_array(sb, n_group + 1); | 2024 | err = ext4_alloc_flex_bg_array(sb, n_group + 1); |
2025 | if (err) | 2025 | if (err) |
2026 | return err; | 2026 | goto out; |
2027 | 2027 | ||
2028 | err = ext4_mb_alloc_groupinfo(sb, n_group + 1); | 2028 | err = ext4_mb_alloc_groupinfo(sb, n_group + 1); |
2029 | if (err) | 2029 | if (err) |
@@ -2059,6 +2059,10 @@ retry: | |||
2059 | n_blocks_count_retry = 0; | 2059 | n_blocks_count_retry = 0; |
2060 | free_flex_gd(flex_gd); | 2060 | free_flex_gd(flex_gd); |
2061 | flex_gd = NULL; | 2061 | flex_gd = NULL; |
2062 | if (resize_inode) { | ||
2063 | iput(resize_inode); | ||
2064 | resize_inode = NULL; | ||
2065 | } | ||
2062 | goto retry; | 2066 | goto retry; |
2063 | } | 2067 | } |
2064 | 2068 | ||
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index a221f1cdf704..53ff6c2a26ed 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -4075,6 +4075,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
4075 | sbi->s_groups_count = blocks_count; | 4075 | sbi->s_groups_count = blocks_count; |
4076 | sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count, | 4076 | sbi->s_blockfile_groups = min_t(ext4_group_t, sbi->s_groups_count, |
4077 | (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); | 4077 | (EXT4_MAX_BLOCK_FILE_PHYS / EXT4_BLOCKS_PER_GROUP(sb))); |
4078 | if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) != | ||
4079 | le32_to_cpu(es->s_inodes_count)) { | ||
4080 | ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu", | ||
4081 | le32_to_cpu(es->s_inodes_count), | ||
4082 | ((u64)sbi->s_groups_count * sbi->s_inodes_per_group)); | ||
4083 | ret = -EINVAL; | ||
4084 | goto failed_mount; | ||
4085 | } | ||
4078 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / | 4086 | db_count = (sbi->s_groups_count + EXT4_DESC_PER_BLOCK(sb) - 1) / |
4079 | EXT4_DESC_PER_BLOCK(sb); | 4087 | EXT4_DESC_PER_BLOCK(sb); |
4080 | if (ext4_has_feature_meta_bg(sb)) { | 4088 | if (ext4_has_feature_meta_bg(sb)) { |
@@ -4094,14 +4102,6 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
4094 | ret = -ENOMEM; | 4102 | ret = -ENOMEM; |
4095 | goto failed_mount; | 4103 | goto failed_mount; |
4096 | } | 4104 | } |
4097 | if (((u64)sbi->s_groups_count * sbi->s_inodes_per_group) != | ||
4098 | le32_to_cpu(es->s_inodes_count)) { | ||
4099 | ext4_msg(sb, KERN_ERR, "inodes count not valid: %u vs %llu", | ||
4100 | le32_to_cpu(es->s_inodes_count), | ||
4101 | ((u64)sbi->s_groups_count * sbi->s_inodes_per_group)); | ||
4102 | ret = -EINVAL; | ||
4103 | goto failed_mount; | ||
4104 | } | ||
4105 | 4105 | ||
4106 | bgl_lock_init(sbi->s_blockgroup_lock); | 4106 | bgl_lock_init(sbi->s_blockgroup_lock); |
4107 | 4107 | ||
@@ -4510,6 +4510,7 @@ failed_mount6: | |||
4510 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | 4510 | percpu_counter_destroy(&sbi->s_freeinodes_counter); |
4511 | percpu_counter_destroy(&sbi->s_dirs_counter); | 4511 | percpu_counter_destroy(&sbi->s_dirs_counter); |
4512 | percpu_counter_destroy(&sbi->s_dirtyclusters_counter); | 4512 | percpu_counter_destroy(&sbi->s_dirtyclusters_counter); |
4513 | percpu_free_rwsem(&sbi->s_journal_flag_rwsem); | ||
4513 | failed_mount5: | 4514 | failed_mount5: |
4514 | ext4_ext_release(sb); | 4515 | ext4_ext_release(sb); |
4515 | ext4_release_system_zone(sb); | 4516 | ext4_release_system_zone(sb); |
diff --git a/fs/ext4/xattr.c b/fs/ext4/xattr.c index f36fc5d5b257..7643d52c776c 100644 --- a/fs/ext4/xattr.c +++ b/fs/ext4/xattr.c | |||
@@ -1031,10 +1031,8 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, | |||
1031 | inode_lock(ea_inode); | 1031 | inode_lock(ea_inode); |
1032 | 1032 | ||
1033 | ret = ext4_reserve_inode_write(handle, ea_inode, &iloc); | 1033 | ret = ext4_reserve_inode_write(handle, ea_inode, &iloc); |
1034 | if (ret) { | 1034 | if (ret) |
1035 | iloc.bh = NULL; | ||
1036 | goto out; | 1035 | goto out; |
1037 | } | ||
1038 | 1036 | ||
1039 | ref_count = ext4_xattr_inode_get_ref(ea_inode); | 1037 | ref_count = ext4_xattr_inode_get_ref(ea_inode); |
1040 | ref_count += ref_change; | 1038 | ref_count += ref_change; |
@@ -1080,12 +1078,10 @@ static int ext4_xattr_inode_update_ref(handle_t *handle, struct inode *ea_inode, | |||
1080 | } | 1078 | } |
1081 | 1079 | ||
1082 | ret = ext4_mark_iloc_dirty(handle, ea_inode, &iloc); | 1080 | ret = ext4_mark_iloc_dirty(handle, ea_inode, &iloc); |
1083 | iloc.bh = NULL; | ||
1084 | if (ret) | 1081 | if (ret) |
1085 | ext4_warning_inode(ea_inode, | 1082 | ext4_warning_inode(ea_inode, |
1086 | "ext4_mark_iloc_dirty() failed ret=%d", ret); | 1083 | "ext4_mark_iloc_dirty() failed ret=%d", ret); |
1087 | out: | 1084 | out: |
1088 | brelse(iloc.bh); | ||
1089 | inode_unlock(ea_inode); | 1085 | inode_unlock(ea_inode); |
1090 | return ret; | 1086 | return ret; |
1091 | } | 1087 | } |
@@ -1388,6 +1384,12 @@ retry: | |||
1388 | bh = ext4_getblk(handle, ea_inode, block, 0); | 1384 | bh = ext4_getblk(handle, ea_inode, block, 0); |
1389 | if (IS_ERR(bh)) | 1385 | if (IS_ERR(bh)) |
1390 | return PTR_ERR(bh); | 1386 | return PTR_ERR(bh); |
1387 | if (!bh) { | ||
1388 | WARN_ON_ONCE(1); | ||
1389 | EXT4_ERROR_INODE(ea_inode, | ||
1390 | "ext4_getblk() return bh = NULL"); | ||
1391 | return -EFSCORRUPTED; | ||
1392 | } | ||
1391 | ret = ext4_journal_get_write_access(handle, bh); | 1393 | ret = ext4_journal_get_write_access(handle, bh); |
1392 | if (ret) | 1394 | if (ret) |
1393 | goto out; | 1395 | goto out; |
@@ -2276,8 +2278,10 @@ static struct buffer_head *ext4_xattr_get_block(struct inode *inode) | |||
2276 | if (!bh) | 2278 | if (!bh) |
2277 | return ERR_PTR(-EIO); | 2279 | return ERR_PTR(-EIO); |
2278 | error = ext4_xattr_check_block(inode, bh); | 2280 | error = ext4_xattr_check_block(inode, bh); |
2279 | if (error) | 2281 | if (error) { |
2282 | brelse(bh); | ||
2280 | return ERR_PTR(error); | 2283 | return ERR_PTR(error); |
2284 | } | ||
2281 | return bh; | 2285 | return bh; |
2282 | } | 2286 | } |
2283 | 2287 | ||
@@ -2397,6 +2401,8 @@ retry_inode: | |||
2397 | error = ext4_xattr_block_set(handle, inode, &i, &bs); | 2401 | error = ext4_xattr_block_set(handle, inode, &i, &bs); |
2398 | } else if (error == -ENOSPC) { | 2402 | } else if (error == -ENOSPC) { |
2399 | if (EXT4_I(inode)->i_file_acl && !bs.s.base) { | 2403 | if (EXT4_I(inode)->i_file_acl && !bs.s.base) { |
2404 | brelse(bs.bh); | ||
2405 | bs.bh = NULL; | ||
2400 | error = ext4_xattr_block_find(inode, &i, &bs); | 2406 | error = ext4_xattr_block_find(inode, &i, &bs); |
2401 | if (error) | 2407 | if (error) |
2402 | goto cleanup; | 2408 | goto cleanup; |
@@ -2617,6 +2623,8 @@ out: | |||
2617 | kfree(buffer); | 2623 | kfree(buffer); |
2618 | if (is) | 2624 | if (is) |
2619 | brelse(is->iloc.bh); | 2625 | brelse(is->iloc.bh); |
2626 | if (bs) | ||
2627 | brelse(bs->bh); | ||
2620 | kfree(is); | 2628 | kfree(is); |
2621 | kfree(bs); | 2629 | kfree(bs); |
2622 | 2630 | ||
@@ -2696,7 +2704,6 @@ int ext4_expand_extra_isize_ea(struct inode *inode, int new_extra_isize, | |||
2696 | struct ext4_inode *raw_inode, handle_t *handle) | 2704 | struct ext4_inode *raw_inode, handle_t *handle) |
2697 | { | 2705 | { |
2698 | struct ext4_xattr_ibody_header *header; | 2706 | struct ext4_xattr_ibody_header *header; |
2699 | struct buffer_head *bh; | ||
2700 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); | 2707 | struct ext4_sb_info *sbi = EXT4_SB(inode->i_sb); |
2701 | static unsigned int mnt_count; | 2708 | static unsigned int mnt_count; |
2702 | size_t min_offs; | 2709 | size_t min_offs; |
@@ -2737,13 +2744,17 @@ retry: | |||
2737 | * EA block can hold new_extra_isize bytes. | 2744 | * EA block can hold new_extra_isize bytes. |
2738 | */ | 2745 | */ |
2739 | if (EXT4_I(inode)->i_file_acl) { | 2746 | if (EXT4_I(inode)->i_file_acl) { |
2747 | struct buffer_head *bh; | ||
2748 | |||
2740 | bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); | 2749 | bh = sb_bread(inode->i_sb, EXT4_I(inode)->i_file_acl); |
2741 | error = -EIO; | 2750 | error = -EIO; |
2742 | if (!bh) | 2751 | if (!bh) |
2743 | goto cleanup; | 2752 | goto cleanup; |
2744 | error = ext4_xattr_check_block(inode, bh); | 2753 | error = ext4_xattr_check_block(inode, bh); |
2745 | if (error) | 2754 | if (error) { |
2755 | brelse(bh); | ||
2746 | goto cleanup; | 2756 | goto cleanup; |
2757 | } | ||
2747 | base = BHDR(bh); | 2758 | base = BHDR(bh); |
2748 | end = bh->b_data + bh->b_size; | 2759 | end = bh->b_data + bh->b_size; |
2749 | min_offs = end - base; | 2760 | min_offs = end - base; |
diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c index ae813e609932..a5e516a40e7a 100644 --- a/fs/fuse/dev.c +++ b/fs/fuse/dev.c | |||
@@ -165,9 +165,13 @@ static bool fuse_block_alloc(struct fuse_conn *fc, bool for_background) | |||
165 | 165 | ||
166 | static void fuse_drop_waiting(struct fuse_conn *fc) | 166 | static void fuse_drop_waiting(struct fuse_conn *fc) |
167 | { | 167 | { |
168 | if (fc->connected) { | 168 | /* |
169 | atomic_dec(&fc->num_waiting); | 169 | * lockess check of fc->connected is okay, because atomic_dec_and_test() |
170 | } else if (atomic_dec_and_test(&fc->num_waiting)) { | 170 | * provides a memory barrier mached with the one in fuse_wait_aborted() |
171 | * to ensure no wake-up is missed. | ||
172 | */ | ||
173 | if (atomic_dec_and_test(&fc->num_waiting) && | ||
174 | !READ_ONCE(fc->connected)) { | ||
171 | /* wake up aborters */ | 175 | /* wake up aborters */ |
172 | wake_up_all(&fc->blocked_waitq); | 176 | wake_up_all(&fc->blocked_waitq); |
173 | } | 177 | } |
@@ -1768,8 +1772,10 @@ static int fuse_retrieve(struct fuse_conn *fc, struct inode *inode, | |||
1768 | req->in.args[1].size = total_len; | 1772 | req->in.args[1].size = total_len; |
1769 | 1773 | ||
1770 | err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); | 1774 | err = fuse_request_send_notify_reply(fc, req, outarg->notify_unique); |
1771 | if (err) | 1775 | if (err) { |
1772 | fuse_retrieve_end(fc, req); | 1776 | fuse_retrieve_end(fc, req); |
1777 | fuse_put_request(fc, req); | ||
1778 | } | ||
1773 | 1779 | ||
1774 | return err; | 1780 | return err; |
1775 | } | 1781 | } |
@@ -2219,6 +2225,8 @@ EXPORT_SYMBOL_GPL(fuse_abort_conn); | |||
2219 | 2225 | ||
2220 | void fuse_wait_aborted(struct fuse_conn *fc) | 2226 | void fuse_wait_aborted(struct fuse_conn *fc) |
2221 | { | 2227 | { |
2228 | /* matches implicit memory barrier in fuse_drop_waiting() */ | ||
2229 | smp_mb(); | ||
2222 | wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0); | 2230 | wait_event(fc->blocked_waitq, atomic_read(&fc->num_waiting) == 0); |
2223 | } | 2231 | } |
2224 | 2232 | ||
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index cc2121b37bf5..b52f9baaa3e7 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -2924,10 +2924,12 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter) | |||
2924 | } | 2924 | } |
2925 | 2925 | ||
2926 | if (io->async) { | 2926 | if (io->async) { |
2927 | bool blocking = io->blocking; | ||
2928 | |||
2927 | fuse_aio_complete(io, ret < 0 ? ret : 0, -1); | 2929 | fuse_aio_complete(io, ret < 0 ? ret : 0, -1); |
2928 | 2930 | ||
2929 | /* we have a non-extending, async request, so return */ | 2931 | /* we have a non-extending, async request, so return */ |
2930 | if (!io->blocking) | 2932 | if (!blocking) |
2931 | return -EIOCBQUEUED; | 2933 | return -EIOCBQUEUED; |
2932 | 2934 | ||
2933 | wait_for_completion(&wait); | 2935 | wait_for_completion(&wait); |
diff --git a/fs/gfs2/bmap.c b/fs/gfs2/bmap.c index a683d9b27d76..9a4a15d646eb 100644 --- a/fs/gfs2/bmap.c +++ b/fs/gfs2/bmap.c | |||
@@ -826,7 +826,7 @@ static int gfs2_iomap_get(struct inode *inode, loff_t pos, loff_t length, | |||
826 | ret = gfs2_meta_inode_buffer(ip, &dibh); | 826 | ret = gfs2_meta_inode_buffer(ip, &dibh); |
827 | if (ret) | 827 | if (ret) |
828 | goto unlock; | 828 | goto unlock; |
829 | iomap->private = dibh; | 829 | mp->mp_bh[0] = dibh; |
830 | 830 | ||
831 | if (gfs2_is_stuffed(ip)) { | 831 | if (gfs2_is_stuffed(ip)) { |
832 | if (flags & IOMAP_WRITE) { | 832 | if (flags & IOMAP_WRITE) { |
@@ -863,9 +863,6 @@ unstuff: | |||
863 | len = lblock_stop - lblock + 1; | 863 | len = lblock_stop - lblock + 1; |
864 | iomap->length = len << inode->i_blkbits; | 864 | iomap->length = len << inode->i_blkbits; |
865 | 865 | ||
866 | get_bh(dibh); | ||
867 | mp->mp_bh[0] = dibh; | ||
868 | |||
869 | height = ip->i_height; | 866 | height = ip->i_height; |
870 | while ((lblock + 1) * sdp->sd_sb.sb_bsize > sdp->sd_heightsize[height]) | 867 | while ((lblock + 1) * sdp->sd_sb.sb_bsize > sdp->sd_heightsize[height]) |
871 | height++; | 868 | height++; |
@@ -898,8 +895,6 @@ out: | |||
898 | iomap->bdev = inode->i_sb->s_bdev; | 895 | iomap->bdev = inode->i_sb->s_bdev; |
899 | unlock: | 896 | unlock: |
900 | up_read(&ip->i_rw_mutex); | 897 | up_read(&ip->i_rw_mutex); |
901 | if (ret && dibh) | ||
902 | brelse(dibh); | ||
903 | return ret; | 898 | return ret; |
904 | 899 | ||
905 | do_alloc: | 900 | do_alloc: |
@@ -980,9 +975,9 @@ static void gfs2_iomap_journaled_page_done(struct inode *inode, loff_t pos, | |||
980 | 975 | ||
981 | static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, | 976 | static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, |
982 | loff_t length, unsigned flags, | 977 | loff_t length, unsigned flags, |
983 | struct iomap *iomap) | 978 | struct iomap *iomap, |
979 | struct metapath *mp) | ||
984 | { | 980 | { |
985 | struct metapath mp = { .mp_aheight = 1, }; | ||
986 | struct gfs2_inode *ip = GFS2_I(inode); | 981 | struct gfs2_inode *ip = GFS2_I(inode); |
987 | struct gfs2_sbd *sdp = GFS2_SB(inode); | 982 | struct gfs2_sbd *sdp = GFS2_SB(inode); |
988 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; | 983 | unsigned int data_blocks = 0, ind_blocks = 0, rblocks; |
@@ -996,9 +991,9 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, | |||
996 | unstuff = gfs2_is_stuffed(ip) && | 991 | unstuff = gfs2_is_stuffed(ip) && |
997 | pos + length > gfs2_max_stuffed_size(ip); | 992 | pos + length > gfs2_max_stuffed_size(ip); |
998 | 993 | ||
999 | ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp); | 994 | ret = gfs2_iomap_get(inode, pos, length, flags, iomap, mp); |
1000 | if (ret) | 995 | if (ret) |
1001 | goto out_release; | 996 | goto out_unlock; |
1002 | 997 | ||
1003 | alloc_required = unstuff || iomap->type == IOMAP_HOLE; | 998 | alloc_required = unstuff || iomap->type == IOMAP_HOLE; |
1004 | 999 | ||
@@ -1013,7 +1008,7 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, | |||
1013 | 1008 | ||
1014 | ret = gfs2_quota_lock_check(ip, &ap); | 1009 | ret = gfs2_quota_lock_check(ip, &ap); |
1015 | if (ret) | 1010 | if (ret) |
1016 | goto out_release; | 1011 | goto out_unlock; |
1017 | 1012 | ||
1018 | ret = gfs2_inplace_reserve(ip, &ap); | 1013 | ret = gfs2_inplace_reserve(ip, &ap); |
1019 | if (ret) | 1014 | if (ret) |
@@ -1038,17 +1033,15 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, | |||
1038 | ret = gfs2_unstuff_dinode(ip, NULL); | 1033 | ret = gfs2_unstuff_dinode(ip, NULL); |
1039 | if (ret) | 1034 | if (ret) |
1040 | goto out_trans_end; | 1035 | goto out_trans_end; |
1041 | release_metapath(&mp); | 1036 | release_metapath(mp); |
1042 | brelse(iomap->private); | ||
1043 | iomap->private = NULL; | ||
1044 | ret = gfs2_iomap_get(inode, iomap->offset, iomap->length, | 1037 | ret = gfs2_iomap_get(inode, iomap->offset, iomap->length, |
1045 | flags, iomap, &mp); | 1038 | flags, iomap, mp); |
1046 | if (ret) | 1039 | if (ret) |
1047 | goto out_trans_end; | 1040 | goto out_trans_end; |
1048 | } | 1041 | } |
1049 | 1042 | ||
1050 | if (iomap->type == IOMAP_HOLE) { | 1043 | if (iomap->type == IOMAP_HOLE) { |
1051 | ret = gfs2_iomap_alloc(inode, iomap, flags, &mp); | 1044 | ret = gfs2_iomap_alloc(inode, iomap, flags, mp); |
1052 | if (ret) { | 1045 | if (ret) { |
1053 | gfs2_trans_end(sdp); | 1046 | gfs2_trans_end(sdp); |
1054 | gfs2_inplace_release(ip); | 1047 | gfs2_inplace_release(ip); |
@@ -1056,7 +1049,6 @@ static int gfs2_iomap_begin_write(struct inode *inode, loff_t pos, | |||
1056 | goto out_qunlock; | 1049 | goto out_qunlock; |
1057 | } | 1050 | } |
1058 | } | 1051 | } |
1059 | release_metapath(&mp); | ||
1060 | if (!gfs2_is_stuffed(ip) && gfs2_is_jdata(ip)) | 1052 | if (!gfs2_is_stuffed(ip) && gfs2_is_jdata(ip)) |
1061 | iomap->page_done = gfs2_iomap_journaled_page_done; | 1053 | iomap->page_done = gfs2_iomap_journaled_page_done; |
1062 | return 0; | 1054 | return 0; |
@@ -1069,10 +1061,7 @@ out_trans_fail: | |||
1069 | out_qunlock: | 1061 | out_qunlock: |
1070 | if (alloc_required) | 1062 | if (alloc_required) |
1071 | gfs2_quota_unlock(ip); | 1063 | gfs2_quota_unlock(ip); |
1072 | out_release: | 1064 | out_unlock: |
1073 | if (iomap->private) | ||
1074 | brelse(iomap->private); | ||
1075 | release_metapath(&mp); | ||
1076 | gfs2_write_unlock(inode); | 1065 | gfs2_write_unlock(inode); |
1077 | return ret; | 1066 | return ret; |
1078 | } | 1067 | } |
@@ -1088,10 +1077,10 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, | |||
1088 | 1077 | ||
1089 | trace_gfs2_iomap_start(ip, pos, length, flags); | 1078 | trace_gfs2_iomap_start(ip, pos, length, flags); |
1090 | if ((flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT)) { | 1079 | if ((flags & IOMAP_WRITE) && !(flags & IOMAP_DIRECT)) { |
1091 | ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap); | 1080 | ret = gfs2_iomap_begin_write(inode, pos, length, flags, iomap, &mp); |
1092 | } else { | 1081 | } else { |
1093 | ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp); | 1082 | ret = gfs2_iomap_get(inode, pos, length, flags, iomap, &mp); |
1094 | release_metapath(&mp); | 1083 | |
1095 | /* | 1084 | /* |
1096 | * Silently fall back to buffered I/O for stuffed files or if | 1085 | * Silently fall back to buffered I/O for stuffed files or if |
1097 | * we've hot a hole (see gfs2_file_direct_write). | 1086 | * we've hot a hole (see gfs2_file_direct_write). |
@@ -1100,6 +1089,11 @@ static int gfs2_iomap_begin(struct inode *inode, loff_t pos, loff_t length, | |||
1100 | iomap->type != IOMAP_MAPPED) | 1089 | iomap->type != IOMAP_MAPPED) |
1101 | ret = -ENOTBLK; | 1090 | ret = -ENOTBLK; |
1102 | } | 1091 | } |
1092 | if (!ret) { | ||
1093 | get_bh(mp.mp_bh[0]); | ||
1094 | iomap->private = mp.mp_bh[0]; | ||
1095 | } | ||
1096 | release_metapath(&mp); | ||
1103 | trace_gfs2_iomap_end(ip, iomap, ret); | 1097 | trace_gfs2_iomap_end(ip, iomap, ret); |
1104 | return ret; | 1098 | return ret; |
1105 | } | 1099 | } |
@@ -1908,10 +1902,16 @@ static int punch_hole(struct gfs2_inode *ip, u64 offset, u64 length) | |||
1908 | if (ret < 0) | 1902 | if (ret < 0) |
1909 | goto out; | 1903 | goto out; |
1910 | 1904 | ||
1911 | /* issue read-ahead on metadata */ | 1905 | /* On the first pass, issue read-ahead on metadata. */ |
1912 | if (mp.mp_aheight > 1) { | 1906 | if (mp.mp_aheight > 1 && strip_h == ip->i_height - 1) { |
1913 | for (; ret > 1; ret--) { | 1907 | unsigned int height = mp.mp_aheight - 1; |
1914 | metapointer_range(&mp, mp.mp_aheight - ret, | 1908 | |
1909 | /* No read-ahead for data blocks. */ | ||
1910 | if (mp.mp_aheight - 1 == strip_h) | ||
1911 | height--; | ||
1912 | |||
1913 | for (; height >= mp.mp_aheight - ret; height--) { | ||
1914 | metapointer_range(&mp, height, | ||
1915 | start_list, start_aligned, | 1915 | start_list, start_aligned, |
1916 | end_list, end_aligned, | 1916 | end_list, end_aligned, |
1917 | &start, &end); | 1917 | &start, &end); |
diff --git a/fs/gfs2/rgrp.c b/fs/gfs2/rgrp.c index ffe3032b1043..b08a530433ad 100644 --- a/fs/gfs2/rgrp.c +++ b/fs/gfs2/rgrp.c | |||
@@ -733,6 +733,7 @@ void gfs2_clear_rgrpd(struct gfs2_sbd *sdp) | |||
733 | 733 | ||
734 | if (gl) { | 734 | if (gl) { |
735 | glock_clear_object(gl, rgd); | 735 | glock_clear_object(gl, rgd); |
736 | gfs2_rgrp_brelse(rgd); | ||
736 | gfs2_glock_put(gl); | 737 | gfs2_glock_put(gl); |
737 | } | 738 | } |
738 | 739 | ||
@@ -1174,7 +1175,7 @@ static u32 count_unlinked(struct gfs2_rgrpd *rgd) | |||
1174 | * @rgd: the struct gfs2_rgrpd describing the RG to read in | 1175 | * @rgd: the struct gfs2_rgrpd describing the RG to read in |
1175 | * | 1176 | * |
1176 | * Read in all of a Resource Group's header and bitmap blocks. | 1177 | * Read in all of a Resource Group's header and bitmap blocks. |
1177 | * Caller must eventually call gfs2_rgrp_relse() to free the bitmaps. | 1178 | * Caller must eventually call gfs2_rgrp_brelse() to free the bitmaps. |
1178 | * | 1179 | * |
1179 | * Returns: errno | 1180 | * Returns: errno |
1180 | */ | 1181 | */ |
diff --git a/fs/inode.c b/fs/inode.c index 9e198f00b64c..35d2108d567c 100644 --- a/fs/inode.c +++ b/fs/inode.c | |||
@@ -730,8 +730,11 @@ static enum lru_status inode_lru_isolate(struct list_head *item, | |||
730 | return LRU_REMOVED; | 730 | return LRU_REMOVED; |
731 | } | 731 | } |
732 | 732 | ||
733 | /* recently referenced inodes get one more pass */ | 733 | /* |
734 | if (inode->i_state & I_REFERENCED) { | 734 | * Recently referenced inodes and inodes with many attached pages |
735 | * get one more pass. | ||
736 | */ | ||
737 | if (inode->i_state & I_REFERENCED || inode->i_data.nrpages > 1) { | ||
735 | inode->i_state &= ~I_REFERENCED; | 738 | inode->i_state &= ~I_REFERENCED; |
736 | spin_unlock(&inode->i_lock); | 739 | spin_unlock(&inode->i_lock); |
737 | return LRU_ROTATE; | 740 | return LRU_ROTATE; |
diff --git a/fs/namespace.c b/fs/namespace.c index 98d27da43304..a7f91265ea67 100644 --- a/fs/namespace.c +++ b/fs/namespace.c | |||
@@ -695,9 +695,6 @@ static struct mountpoint *lookup_mountpoint(struct dentry *dentry) | |||
695 | 695 | ||
696 | hlist_for_each_entry(mp, chain, m_hash) { | 696 | hlist_for_each_entry(mp, chain, m_hash) { |
697 | if (mp->m_dentry == dentry) { | 697 | if (mp->m_dentry == dentry) { |
698 | /* might be worth a WARN_ON() */ | ||
699 | if (d_unlinked(dentry)) | ||
700 | return ERR_PTR(-ENOENT); | ||
701 | mp->m_count++; | 698 | mp->m_count++; |
702 | return mp; | 699 | return mp; |
703 | } | 700 | } |
@@ -711,6 +708,9 @@ static struct mountpoint *get_mountpoint(struct dentry *dentry) | |||
711 | int ret; | 708 | int ret; |
712 | 709 | ||
713 | if (d_mountpoint(dentry)) { | 710 | if (d_mountpoint(dentry)) { |
711 | /* might be worth a WARN_ON() */ | ||
712 | if (d_unlinked(dentry)) | ||
713 | return ERR_PTR(-ENOENT); | ||
714 | mountpoint: | 714 | mountpoint: |
715 | read_seqlock_excl(&mount_lock); | 715 | read_seqlock_excl(&mount_lock); |
716 | mp = lookup_mountpoint(dentry); | 716 | mp = lookup_mountpoint(dentry); |
@@ -1540,8 +1540,13 @@ static int do_umount(struct mount *mnt, int flags) | |||
1540 | 1540 | ||
1541 | namespace_lock(); | 1541 | namespace_lock(); |
1542 | lock_mount_hash(); | 1542 | lock_mount_hash(); |
1543 | event++; | ||
1544 | 1543 | ||
1544 | /* Recheck MNT_LOCKED with the locks held */ | ||
1545 | retval = -EINVAL; | ||
1546 | if (mnt->mnt.mnt_flags & MNT_LOCKED) | ||
1547 | goto out; | ||
1548 | |||
1549 | event++; | ||
1545 | if (flags & MNT_DETACH) { | 1550 | if (flags & MNT_DETACH) { |
1546 | if (!list_empty(&mnt->mnt_list)) | 1551 | if (!list_empty(&mnt->mnt_list)) |
1547 | umount_tree(mnt, UMOUNT_PROPAGATE); | 1552 | umount_tree(mnt, UMOUNT_PROPAGATE); |
@@ -1555,6 +1560,7 @@ static int do_umount(struct mount *mnt, int flags) | |||
1555 | retval = 0; | 1560 | retval = 0; |
1556 | } | 1561 | } |
1557 | } | 1562 | } |
1563 | out: | ||
1558 | unlock_mount_hash(); | 1564 | unlock_mount_hash(); |
1559 | namespace_unlock(); | 1565 | namespace_unlock(); |
1560 | return retval; | 1566 | return retval; |
@@ -1645,7 +1651,7 @@ int ksys_umount(char __user *name, int flags) | |||
1645 | goto dput_and_out; | 1651 | goto dput_and_out; |
1646 | if (!check_mnt(mnt)) | 1652 | if (!check_mnt(mnt)) |
1647 | goto dput_and_out; | 1653 | goto dput_and_out; |
1648 | if (mnt->mnt.mnt_flags & MNT_LOCKED) | 1654 | if (mnt->mnt.mnt_flags & MNT_LOCKED) /* Check optimistically */ |
1649 | goto dput_and_out; | 1655 | goto dput_and_out; |
1650 | retval = -EPERM; | 1656 | retval = -EPERM; |
1651 | if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) | 1657 | if (flags & MNT_FORCE && !capable(CAP_SYS_ADMIN)) |
@@ -1728,8 +1734,14 @@ struct mount *copy_tree(struct mount *mnt, struct dentry *dentry, | |||
1728 | for (s = r; s; s = next_mnt(s, r)) { | 1734 | for (s = r; s; s = next_mnt(s, r)) { |
1729 | if (!(flag & CL_COPY_UNBINDABLE) && | 1735 | if (!(flag & CL_COPY_UNBINDABLE) && |
1730 | IS_MNT_UNBINDABLE(s)) { | 1736 | IS_MNT_UNBINDABLE(s)) { |
1731 | s = skip_mnt_tree(s); | 1737 | if (s->mnt.mnt_flags & MNT_LOCKED) { |
1732 | continue; | 1738 | /* Both unbindable and locked. */ |
1739 | q = ERR_PTR(-EPERM); | ||
1740 | goto out; | ||
1741 | } else { | ||
1742 | s = skip_mnt_tree(s); | ||
1743 | continue; | ||
1744 | } | ||
1733 | } | 1745 | } |
1734 | if (!(flag & CL_COPY_MNT_NS_FILE) && | 1746 | if (!(flag & CL_COPY_MNT_NS_FILE) && |
1735 | is_mnt_ns_file(s->mnt.mnt_root)) { | 1747 | is_mnt_ns_file(s->mnt.mnt_root)) { |
@@ -1782,7 +1794,7 @@ void drop_collected_mounts(struct vfsmount *mnt) | |||
1782 | { | 1794 | { |
1783 | namespace_lock(); | 1795 | namespace_lock(); |
1784 | lock_mount_hash(); | 1796 | lock_mount_hash(); |
1785 | umount_tree(real_mount(mnt), UMOUNT_SYNC); | 1797 | umount_tree(real_mount(mnt), 0); |
1786 | unlock_mount_hash(); | 1798 | unlock_mount_hash(); |
1787 | namespace_unlock(); | 1799 | namespace_unlock(); |
1788 | } | 1800 | } |
diff --git a/fs/nfs/callback_proc.c b/fs/nfs/callback_proc.c index fa515d5ea5ba..7b861bbc0b43 100644 --- a/fs/nfs/callback_proc.c +++ b/fs/nfs/callback_proc.c | |||
@@ -66,7 +66,7 @@ __be32 nfs4_callback_getattr(void *argp, void *resp, | |||
66 | out_iput: | 66 | out_iput: |
67 | rcu_read_unlock(); | 67 | rcu_read_unlock(); |
68 | trace_nfs4_cb_getattr(cps->clp, &args->fh, inode, -ntohl(res->status)); | 68 | trace_nfs4_cb_getattr(cps->clp, &args->fh, inode, -ntohl(res->status)); |
69 | iput(inode); | 69 | nfs_iput_and_deactive(inode); |
70 | out: | 70 | out: |
71 | dprintk("%s: exit with status = %d\n", __func__, ntohl(res->status)); | 71 | dprintk("%s: exit with status = %d\n", __func__, ntohl(res->status)); |
72 | return res->status; | 72 | return res->status; |
@@ -108,7 +108,7 @@ __be32 nfs4_callback_recall(void *argp, void *resp, | |||
108 | } | 108 | } |
109 | trace_nfs4_cb_recall(cps->clp, &args->fh, inode, | 109 | trace_nfs4_cb_recall(cps->clp, &args->fh, inode, |
110 | &args->stateid, -ntohl(res)); | 110 | &args->stateid, -ntohl(res)); |
111 | iput(inode); | 111 | nfs_iput_and_deactive(inode); |
112 | out: | 112 | out: |
113 | dprintk("%s: exit with status = %d\n", __func__, ntohl(res)); | 113 | dprintk("%s: exit with status = %d\n", __func__, ntohl(res)); |
114 | return res; | 114 | return res; |
diff --git a/fs/nfs/delegation.c b/fs/nfs/delegation.c index 07b839560576..6ec2f78c1e19 100644 --- a/fs/nfs/delegation.c +++ b/fs/nfs/delegation.c | |||
@@ -850,16 +850,23 @@ nfs_delegation_find_inode_server(struct nfs_server *server, | |||
850 | const struct nfs_fh *fhandle) | 850 | const struct nfs_fh *fhandle) |
851 | { | 851 | { |
852 | struct nfs_delegation *delegation; | 852 | struct nfs_delegation *delegation; |
853 | struct inode *res = NULL; | 853 | struct inode *freeme, *res = NULL; |
854 | 854 | ||
855 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { | 855 | list_for_each_entry_rcu(delegation, &server->delegations, super_list) { |
856 | spin_lock(&delegation->lock); | 856 | spin_lock(&delegation->lock); |
857 | if (delegation->inode != NULL && | 857 | if (delegation->inode != NULL && |
858 | nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { | 858 | nfs_compare_fh(fhandle, &NFS_I(delegation->inode)->fh) == 0) { |
859 | res = igrab(delegation->inode); | 859 | freeme = igrab(delegation->inode); |
860 | if (freeme && nfs_sb_active(freeme->i_sb)) | ||
861 | res = freeme; | ||
860 | spin_unlock(&delegation->lock); | 862 | spin_unlock(&delegation->lock); |
861 | if (res != NULL) | 863 | if (res != NULL) |
862 | return res; | 864 | return res; |
865 | if (freeme) { | ||
866 | rcu_read_unlock(); | ||
867 | iput(freeme); | ||
868 | rcu_read_lock(); | ||
869 | } | ||
863 | return ERR_PTR(-EAGAIN); | 870 | return ERR_PTR(-EAGAIN); |
864 | } | 871 | } |
865 | spin_unlock(&delegation->lock); | 872 | spin_unlock(&delegation->lock); |
diff --git a/fs/nfs/nfs4state.c b/fs/nfs/nfs4state.c index 62ae0fd345ad..ffea57885394 100644 --- a/fs/nfs/nfs4state.c +++ b/fs/nfs/nfs4state.c | |||
@@ -2601,11 +2601,12 @@ static void nfs4_state_manager(struct nfs_client *clp) | |||
2601 | nfs4_clear_state_manager_bit(clp); | 2601 | nfs4_clear_state_manager_bit(clp); |
2602 | /* Did we race with an attempt to give us more work? */ | 2602 | /* Did we race with an attempt to give us more work? */ |
2603 | if (clp->cl_state == 0) | 2603 | if (clp->cl_state == 0) |
2604 | break; | 2604 | return; |
2605 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) | 2605 | if (test_and_set_bit(NFS4CLNT_MANAGER_RUNNING, &clp->cl_state) != 0) |
2606 | break; | 2606 | return; |
2607 | } while (refcount_read(&clp->cl_count) > 1); | 2607 | } while (refcount_read(&clp->cl_count) > 1 && !signalled()); |
2608 | return; | 2608 | goto out_drain; |
2609 | |||
2609 | out_error: | 2610 | out_error: |
2610 | if (strlen(section)) | 2611 | if (strlen(section)) |
2611 | section_sep = ": "; | 2612 | section_sep = ": "; |
@@ -2613,6 +2614,7 @@ out_error: | |||
2613 | " with error %d\n", section_sep, section, | 2614 | " with error %d\n", section_sep, section, |
2614 | clp->cl_hostname, -status); | 2615 | clp->cl_hostname, -status); |
2615 | ssleep(1); | 2616 | ssleep(1); |
2617 | out_drain: | ||
2616 | nfs4_end_drain_session(clp); | 2618 | nfs4_end_drain_session(clp); |
2617 | nfs4_clear_state_manager_bit(clp); | 2619 | nfs4_clear_state_manager_bit(clp); |
2618 | } | 2620 | } |
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index edff074d38c7..d505990dac7c 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c | |||
@@ -1038,6 +1038,9 @@ nfsd4_verify_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate, | |||
1038 | { | 1038 | { |
1039 | __be32 status; | 1039 | __be32 status; |
1040 | 1040 | ||
1041 | if (!cstate->save_fh.fh_dentry) | ||
1042 | return nfserr_nofilehandle; | ||
1043 | |||
1041 | status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh, | 1044 | status = nfs4_preprocess_stateid_op(rqstp, cstate, &cstate->save_fh, |
1042 | src_stateid, RD_STATE, src, NULL); | 1045 | src_stateid, RD_STATE, src, NULL); |
1043 | if (status) { | 1046 | if (status) { |
diff --git a/fs/notify/fanotify/fanotify.c b/fs/notify/fanotify/fanotify.c index 5769cf3ff035..e08a6647267b 100644 --- a/fs/notify/fanotify/fanotify.c +++ b/fs/notify/fanotify/fanotify.c | |||
@@ -115,12 +115,12 @@ static bool fanotify_should_send_event(struct fsnotify_iter_info *iter_info, | |||
115 | continue; | 115 | continue; |
116 | mark = iter_info->marks[type]; | 116 | mark = iter_info->marks[type]; |
117 | /* | 117 | /* |
118 | * if the event is for a child and this inode doesn't care about | 118 | * If the event is for a child and this mark doesn't care about |
119 | * events on the child, don't send it! | 119 | * events on a child, don't send it! |
120 | */ | 120 | */ |
121 | if (type == FSNOTIFY_OBJ_TYPE_INODE && | 121 | if (event_mask & FS_EVENT_ON_CHILD && |
122 | (event_mask & FS_EVENT_ON_CHILD) && | 122 | (type != FSNOTIFY_OBJ_TYPE_INODE || |
123 | !(mark->mask & FS_EVENT_ON_CHILD)) | 123 | !(mark->mask & FS_EVENT_ON_CHILD))) |
124 | continue; | 124 | continue; |
125 | 125 | ||
126 | marks_mask |= mark->mask; | 126 | marks_mask |= mark->mask; |
diff --git a/fs/notify/fsnotify.c b/fs/notify/fsnotify.c index 2172ba516c61..d2c34900ae05 100644 --- a/fs/notify/fsnotify.c +++ b/fs/notify/fsnotify.c | |||
@@ -167,9 +167,9 @@ int __fsnotify_parent(const struct path *path, struct dentry *dentry, __u32 mask | |||
167 | parent = dget_parent(dentry); | 167 | parent = dget_parent(dentry); |
168 | p_inode = parent->d_inode; | 168 | p_inode = parent->d_inode; |
169 | 169 | ||
170 | if (unlikely(!fsnotify_inode_watches_children(p_inode))) | 170 | if (unlikely(!fsnotify_inode_watches_children(p_inode))) { |
171 | __fsnotify_update_child_dentry_flags(p_inode); | 171 | __fsnotify_update_child_dentry_flags(p_inode); |
172 | else if (p_inode->i_fsnotify_mask & mask) { | 172 | } else if (p_inode->i_fsnotify_mask & mask & ALL_FSNOTIFY_EVENTS) { |
173 | struct name_snapshot name; | 173 | struct name_snapshot name; |
174 | 174 | ||
175 | /* we are notifying a parent so come up with the new mask which | 175 | /* we are notifying a parent so come up with the new mask which |
@@ -339,6 +339,9 @@ int fsnotify(struct inode *to_tell, __u32 mask, const void *data, int data_is, | |||
339 | sb = mnt->mnt.mnt_sb; | 339 | sb = mnt->mnt.mnt_sb; |
340 | mnt_or_sb_mask = mnt->mnt_fsnotify_mask | sb->s_fsnotify_mask; | 340 | mnt_or_sb_mask = mnt->mnt_fsnotify_mask | sb->s_fsnotify_mask; |
341 | } | 341 | } |
342 | /* An event "on child" is not intended for a mount/sb mark */ | ||
343 | if (mask & FS_EVENT_ON_CHILD) | ||
344 | mnt_or_sb_mask = 0; | ||
342 | 345 | ||
343 | /* | 346 | /* |
344 | * Optimization: srcu_read_lock() has a memory barrier which can | 347 | * Optimization: srcu_read_lock() has a memory barrier which can |
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c index da578ad4c08f..eb1ce30412dc 100644 --- a/fs/ocfs2/aops.c +++ b/fs/ocfs2/aops.c | |||
@@ -2411,8 +2411,16 @@ static int ocfs2_dio_end_io(struct kiocb *iocb, | |||
2411 | /* this io's submitter should not have unlocked this before we could */ | 2411 | /* this io's submitter should not have unlocked this before we could */ |
2412 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); | 2412 | BUG_ON(!ocfs2_iocb_is_rw_locked(iocb)); |
2413 | 2413 | ||
2414 | if (bytes > 0 && private) | 2414 | if (bytes <= 0) |
2415 | ret = ocfs2_dio_end_io_write(inode, private, offset, bytes); | 2415 | mlog_ratelimited(ML_ERROR, "Direct IO failed, bytes = %lld", |
2416 | (long long)bytes); | ||
2417 | if (private) { | ||
2418 | if (bytes > 0) | ||
2419 | ret = ocfs2_dio_end_io_write(inode, private, offset, | ||
2420 | bytes); | ||
2421 | else | ||
2422 | ocfs2_dio_free_write_ctx(inode, private); | ||
2423 | } | ||
2416 | 2424 | ||
2417 | ocfs2_iocb_clear_rw_locked(iocb); | 2425 | ocfs2_iocb_clear_rw_locked(iocb); |
2418 | 2426 | ||
diff --git a/fs/ocfs2/cluster/masklog.h b/fs/ocfs2/cluster/masklog.h index 308ea0eb35fd..a396096a5099 100644 --- a/fs/ocfs2/cluster/masklog.h +++ b/fs/ocfs2/cluster/masklog.h | |||
@@ -178,6 +178,15 @@ do { \ | |||
178 | ##__VA_ARGS__); \ | 178 | ##__VA_ARGS__); \ |
179 | } while (0) | 179 | } while (0) |
180 | 180 | ||
181 | #define mlog_ratelimited(mask, fmt, ...) \ | ||
182 | do { \ | ||
183 | static DEFINE_RATELIMIT_STATE(_rs, \ | ||
184 | DEFAULT_RATELIMIT_INTERVAL, \ | ||
185 | DEFAULT_RATELIMIT_BURST); \ | ||
186 | if (__ratelimit(&_rs)) \ | ||
187 | mlog(mask, fmt, ##__VA_ARGS__); \ | ||
188 | } while (0) | ||
189 | |||
181 | #define mlog_errno(st) ({ \ | 190 | #define mlog_errno(st) ({ \ |
182 | int _st = (st); \ | 191 | int _st = (st); \ |
183 | if (_st != -ERESTARTSYS && _st != -EINTR && \ | 192 | if (_st != -ERESTARTSYS && _st != -EINTR && \ |
diff --git a/fs/xfs/libxfs/xfs_attr_leaf.c b/fs/xfs/libxfs/xfs_attr_leaf.c index 6fc5425b1474..2652d00842d6 100644 --- a/fs/xfs/libxfs/xfs_attr_leaf.c +++ b/fs/xfs/libxfs/xfs_attr_leaf.c | |||
@@ -243,7 +243,7 @@ xfs_attr3_leaf_verify( | |||
243 | struct xfs_mount *mp = bp->b_target->bt_mount; | 243 | struct xfs_mount *mp = bp->b_target->bt_mount; |
244 | struct xfs_attr_leafblock *leaf = bp->b_addr; | 244 | struct xfs_attr_leafblock *leaf = bp->b_addr; |
245 | struct xfs_attr_leaf_entry *entries; | 245 | struct xfs_attr_leaf_entry *entries; |
246 | uint16_t end; | 246 | uint32_t end; /* must be 32bit - see below */ |
247 | int i; | 247 | int i; |
248 | 248 | ||
249 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); | 249 | xfs_attr3_leaf_hdr_from_disk(mp->m_attr_geo, &ichdr, leaf); |
@@ -293,6 +293,11 @@ xfs_attr3_leaf_verify( | |||
293 | /* | 293 | /* |
294 | * Quickly check the freemap information. Attribute data has to be | 294 | * Quickly check the freemap information. Attribute data has to be |
295 | * aligned to 4-byte boundaries, and likewise for the free space. | 295 | * aligned to 4-byte boundaries, and likewise for the free space. |
296 | * | ||
297 | * Note that for 64k block size filesystems, the freemap entries cannot | ||
298 | * overflow as they are only be16 fields. However, when checking end | ||
299 | * pointer of the freemap, we have to be careful to detect overflows and | ||
300 | * so use uint32_t for those checks. | ||
296 | */ | 301 | */ |
297 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { | 302 | for (i = 0; i < XFS_ATTR_LEAF_MAPSIZE; i++) { |
298 | if (ichdr.freemap[i].base > mp->m_attr_geo->blksize) | 303 | if (ichdr.freemap[i].base > mp->m_attr_geo->blksize) |
@@ -303,7 +308,9 @@ xfs_attr3_leaf_verify( | |||
303 | return __this_address; | 308 | return __this_address; |
304 | if (ichdr.freemap[i].size & 0x3) | 309 | if (ichdr.freemap[i].size & 0x3) |
305 | return __this_address; | 310 | return __this_address; |
306 | end = ichdr.freemap[i].base + ichdr.freemap[i].size; | 311 | |
312 | /* be care of 16 bit overflows here */ | ||
313 | end = (uint32_t)ichdr.freemap[i].base + ichdr.freemap[i].size; | ||
307 | if (end < ichdr.freemap[i].base) | 314 | if (end < ichdr.freemap[i].base) |
308 | return __this_address; | 315 | return __this_address; |
309 | if (end > mp->m_attr_geo->blksize) | 316 | if (end > mp->m_attr_geo->blksize) |
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c index 6e2c08f30f60..6ecdbb3af7de 100644 --- a/fs/xfs/xfs_ioctl.c +++ b/fs/xfs/xfs_ioctl.c | |||
@@ -1608,7 +1608,7 @@ xfs_ioc_getbmap( | |||
1608 | error = 0; | 1608 | error = 0; |
1609 | out_free_buf: | 1609 | out_free_buf: |
1610 | kmem_free(buf); | 1610 | kmem_free(buf); |
1611 | return 0; | 1611 | return error; |
1612 | } | 1612 | } |
1613 | 1613 | ||
1614 | struct getfsmap_info { | 1614 | struct getfsmap_info { |
diff --git a/fs/xfs/xfs_message.c b/fs/xfs/xfs_message.c index 576c375ce12a..6b736ea58d35 100644 --- a/fs/xfs/xfs_message.c +++ b/fs/xfs/xfs_message.c | |||
@@ -107,5 +107,5 @@ assfail(char *expr, char *file, int line) | |||
107 | void | 107 | void |
108 | xfs_hex_dump(void *p, int length) | 108 | xfs_hex_dump(void *p, int length) |
109 | { | 109 | { |
110 | print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_ADDRESS, 16, 1, p, length, 1); | 110 | print_hex_dump(KERN_ALERT, "", DUMP_PREFIX_OFFSET, 16, 1, p, length, 1); |
111 | } | 111 | } |