diff options
author | Anton Altaparmakov <anton@tuxera.com> | 2012-02-27 04:01:22 -0500 |
---|---|---|
committer | Anton Altaparmakov <anton@tuxera.com> | 2012-02-27 04:01:22 -0500 |
commit | f621c5334396fd153cd882ea92466823b7e7b821 (patch) | |
tree | 7b829cad44dc0e5003d7cacac3a7a1b128637083 /fs | |
parent | 0afa1b62e33250d4777c5803a98ae69fbe872061 (diff) | |
parent | 500dd2370e77c9551ba298bdeeb91b02d8402199 (diff) |
Merge branch 'master' of /Volumes/CaseSensitiveDisk/linux
Diffstat (limited to 'fs')
-rw-r--r-- | fs/autofs4/autofs_i.h | 1 | ||||
-rw-r--r-- | fs/autofs4/dev-ioctl.c | 1 | ||||
-rw-r--r-- | fs/autofs4/inode.c | 2 | ||||
-rw-r--r-- | fs/autofs4/waitq.c | 22 | ||||
-rw-r--r-- | fs/btrfs/backref.c | 2 | ||||
-rw-r--r-- | fs/btrfs/check-integrity.c | 2 | ||||
-rw-r--r-- | fs/btrfs/compression.c | 2 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 2 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 12 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 51 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 113 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 1 | ||||
-rw-r--r-- | fs/btrfs/extent_map.h | 4 | ||||
-rw-r--r-- | fs/btrfs/file.c | 29 | ||||
-rw-r--r-- | fs/btrfs/free-space-cache.c | 1 | ||||
-rw-r--r-- | fs/btrfs/inode-map.c | 6 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 40 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 59 | ||||
-rw-r--r-- | fs/btrfs/scrub.c | 8 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 16 | ||||
-rw-r--r-- | fs/btrfs/volumes.c | 33 | ||||
-rw-r--r-- | fs/direct-io.c | 4 | ||||
-rw-r--r-- | fs/eventpoll.c | 30 | ||||
-rw-r--r-- | fs/signalfd.c | 15 |
24 files changed, 319 insertions, 137 deletions
diff --git a/fs/autofs4/autofs_i.h b/fs/autofs4/autofs_i.h index d8d8e7ba6a1e..eb1cc92cd67d 100644 --- a/fs/autofs4/autofs_i.h +++ b/fs/autofs4/autofs_i.h | |||
@@ -110,6 +110,7 @@ struct autofs_sb_info { | |||
110 | int sub_version; | 110 | int sub_version; |
111 | int min_proto; | 111 | int min_proto; |
112 | int max_proto; | 112 | int max_proto; |
113 | int compat_daemon; | ||
113 | unsigned long exp_timeout; | 114 | unsigned long exp_timeout; |
114 | unsigned int type; | 115 | unsigned int type; |
115 | int reghost_enabled; | 116 | int reghost_enabled; |
diff --git a/fs/autofs4/dev-ioctl.c b/fs/autofs4/dev-ioctl.c index 76741d8d7786..85f1fcdb30e7 100644 --- a/fs/autofs4/dev-ioctl.c +++ b/fs/autofs4/dev-ioctl.c | |||
@@ -385,6 +385,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp, | |||
385 | sbi->pipefd = pipefd; | 385 | sbi->pipefd = pipefd; |
386 | sbi->pipe = pipe; | 386 | sbi->pipe = pipe; |
387 | sbi->catatonic = 0; | 387 | sbi->catatonic = 0; |
388 | sbi->compat_daemon = is_compat_task(); | ||
388 | } | 389 | } |
389 | out: | 390 | out: |
390 | mutex_unlock(&sbi->wq_mutex); | 391 | mutex_unlock(&sbi->wq_mutex); |
diff --git a/fs/autofs4/inode.c b/fs/autofs4/inode.c index e16980b00b8d..06858d955120 100644 --- a/fs/autofs4/inode.c +++ b/fs/autofs4/inode.c | |||
@@ -19,6 +19,7 @@ | |||
19 | #include <linux/parser.h> | 19 | #include <linux/parser.h> |
20 | #include <linux/bitops.h> | 20 | #include <linux/bitops.h> |
21 | #include <linux/magic.h> | 21 | #include <linux/magic.h> |
22 | #include <linux/compat.h> | ||
22 | #include "autofs_i.h" | 23 | #include "autofs_i.h" |
23 | #include <linux/module.h> | 24 | #include <linux/module.h> |
24 | 25 | ||
@@ -224,6 +225,7 @@ int autofs4_fill_super(struct super_block *s, void *data, int silent) | |||
224 | set_autofs_type_indirect(&sbi->type); | 225 | set_autofs_type_indirect(&sbi->type); |
225 | sbi->min_proto = 0; | 226 | sbi->min_proto = 0; |
226 | sbi->max_proto = 0; | 227 | sbi->max_proto = 0; |
228 | sbi->compat_daemon = is_compat_task(); | ||
227 | mutex_init(&sbi->wq_mutex); | 229 | mutex_init(&sbi->wq_mutex); |
228 | mutex_init(&sbi->pipe_mutex); | 230 | mutex_init(&sbi->pipe_mutex); |
229 | spin_lock_init(&sbi->fs_lock); | 231 | spin_lock_init(&sbi->fs_lock); |
diff --git a/fs/autofs4/waitq.c b/fs/autofs4/waitq.c index da8876d38a7b..9c098db43344 100644 --- a/fs/autofs4/waitq.c +++ b/fs/autofs4/waitq.c | |||
@@ -91,7 +91,24 @@ static int autofs4_write(struct autofs_sb_info *sbi, | |||
91 | 91 | ||
92 | return (bytes > 0); | 92 | return (bytes > 0); |
93 | } | 93 | } |
94 | 94 | ||
95 | /* | ||
96 | * The autofs_v5 packet was misdesigned. | ||
97 | * | ||
98 | * The packets are identical on x86-32 and x86-64, but have different | ||
99 | * alignment. Which means that 'sizeof()' will give different results. | ||
100 | * Fix it up for the case of running 32-bit user mode on a 64-bit kernel. | ||
101 | */ | ||
102 | static noinline size_t autofs_v5_packet_size(struct autofs_sb_info *sbi) | ||
103 | { | ||
104 | size_t pktsz = sizeof(struct autofs_v5_packet); | ||
105 | #if defined(CONFIG_X86_64) && defined(CONFIG_COMPAT) | ||
106 | if (sbi->compat_daemon > 0) | ||
107 | pktsz -= 4; | ||
108 | #endif | ||
109 | return pktsz; | ||
110 | } | ||
111 | |||
95 | static void autofs4_notify_daemon(struct autofs_sb_info *sbi, | 112 | static void autofs4_notify_daemon(struct autofs_sb_info *sbi, |
96 | struct autofs_wait_queue *wq, | 113 | struct autofs_wait_queue *wq, |
97 | int type) | 114 | int type) |
@@ -155,8 +172,7 @@ static void autofs4_notify_daemon(struct autofs_sb_info *sbi, | |||
155 | { | 172 | { |
156 | struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; | 173 | struct autofs_v5_packet *packet = &pkt.v5_pkt.v5_packet; |
157 | 174 | ||
158 | pktsz = sizeof(*packet); | 175 | pktsz = autofs_v5_packet_size(sbi); |
159 | |||
160 | packet->wait_queue_token = wq->wait_queue_token; | 176 | packet->wait_queue_token = wq->wait_queue_token; |
161 | packet->len = wq->name.len; | 177 | packet->len = wq->name.len; |
162 | memcpy(packet->name, wq->name.name, wq->name.len); | 178 | memcpy(packet->name, wq->name.name, wq->name.len); |
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 633c701a287d..98f6bf10bbd4 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -892,6 +892,8 @@ static char *iref_to_path(struct btrfs_root *fs_root, struct btrfs_path *path, | |||
892 | if (eb != eb_in) | 892 | if (eb != eb_in) |
893 | free_extent_buffer(eb); | 893 | free_extent_buffer(eb); |
894 | ret = inode_ref_info(parent, 0, fs_root, path, &found_key); | 894 | ret = inode_ref_info(parent, 0, fs_root, path, &found_key); |
895 | if (ret > 0) | ||
896 | ret = -ENOENT; | ||
895 | if (ret) | 897 | if (ret) |
896 | break; | 898 | break; |
897 | next_inum = found_key.offset; | 899 | next_inum = found_key.offset; |
diff --git a/fs/btrfs/check-integrity.c b/fs/btrfs/check-integrity.c index b669a7d8e499..d986824bb2b4 100644 --- a/fs/btrfs/check-integrity.c +++ b/fs/btrfs/check-integrity.c | |||
@@ -644,7 +644,7 @@ static struct btrfsic_dev_state *btrfsic_dev_state_hashtable_lookup( | |||
644 | static int btrfsic_process_superblock(struct btrfsic_state *state, | 644 | static int btrfsic_process_superblock(struct btrfsic_state *state, |
645 | struct btrfs_fs_devices *fs_devices) | 645 | struct btrfs_fs_devices *fs_devices) |
646 | { | 646 | { |
647 | int ret; | 647 | int ret = 0; |
648 | struct btrfs_super_block *selected_super; | 648 | struct btrfs_super_block *selected_super; |
649 | struct list_head *dev_head = &fs_devices->devices; | 649 | struct list_head *dev_head = &fs_devices->devices; |
650 | struct btrfs_device *device; | 650 | struct btrfs_device *device; |
diff --git a/fs/btrfs/compression.c b/fs/btrfs/compression.c index 14f1c5a0b2d2..d02c27cd14c7 100644 --- a/fs/btrfs/compression.c +++ b/fs/btrfs/compression.c | |||
@@ -588,6 +588,8 @@ int btrfs_submit_compressed_read(struct inode *inode, struct bio *bio, | |||
588 | page_offset(bio->bi_io_vec->bv_page), | 588 | page_offset(bio->bi_io_vec->bv_page), |
589 | PAGE_CACHE_SIZE); | 589 | PAGE_CACHE_SIZE); |
590 | read_unlock(&em_tree->lock); | 590 | read_unlock(&em_tree->lock); |
591 | if (!em) | ||
592 | return -EIO; | ||
591 | 593 | ||
592 | compressed_len = em->block_len; | 594 | compressed_len = em->block_len; |
593 | cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); | 595 | cb = kmalloc(compressed_bio_size(root, compressed_len), GFP_NOFS); |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 27ebe61d3ccc..80b6486fd5e6 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -886,7 +886,7 @@ struct btrfs_block_rsv { | |||
886 | u64 reserved; | 886 | u64 reserved; |
887 | struct btrfs_space_info *space_info; | 887 | struct btrfs_space_info *space_info; |
888 | spinlock_t lock; | 888 | spinlock_t lock; |
889 | unsigned int full:1; | 889 | unsigned int full; |
890 | }; | 890 | }; |
891 | 891 | ||
892 | /* | 892 | /* |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index 811d9f918b1c..534266fe505f 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -2260,6 +2260,12 @@ int open_ctree(struct super_block *sb, | |||
2260 | goto fail_sb_buffer; | 2260 | goto fail_sb_buffer; |
2261 | } | 2261 | } |
2262 | 2262 | ||
2263 | if (sectorsize < PAGE_SIZE) { | ||
2264 | printk(KERN_WARNING "btrfs: Incompatible sector size " | ||
2265 | "found on %s\n", sb->s_id); | ||
2266 | goto fail_sb_buffer; | ||
2267 | } | ||
2268 | |||
2263 | mutex_lock(&fs_info->chunk_mutex); | 2269 | mutex_lock(&fs_info->chunk_mutex); |
2264 | ret = btrfs_read_sys_array(tree_root); | 2270 | ret = btrfs_read_sys_array(tree_root); |
2265 | mutex_unlock(&fs_info->chunk_mutex); | 2271 | mutex_unlock(&fs_info->chunk_mutex); |
@@ -2301,6 +2307,12 @@ int open_ctree(struct super_block *sb, | |||
2301 | 2307 | ||
2302 | btrfs_close_extra_devices(fs_devices); | 2308 | btrfs_close_extra_devices(fs_devices); |
2303 | 2309 | ||
2310 | if (!fs_devices->latest_bdev) { | ||
2311 | printk(KERN_CRIT "btrfs: failed to read devices on %s\n", | ||
2312 | sb->s_id); | ||
2313 | goto fail_tree_roots; | ||
2314 | } | ||
2315 | |||
2304 | retry_root_backup: | 2316 | retry_root_backup: |
2305 | blocksize = btrfs_level_size(tree_root, | 2317 | blocksize = btrfs_level_size(tree_root, |
2306 | btrfs_super_root_level(disk_super)); | 2318 | btrfs_super_root_level(disk_super)); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 283af7a676a3..37e0a800d34e 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -3312,7 +3312,8 @@ commit_trans: | |||
3312 | } | 3312 | } |
3313 | data_sinfo->bytes_may_use += bytes; | 3313 | data_sinfo->bytes_may_use += bytes; |
3314 | trace_btrfs_space_reservation(root->fs_info, "space_info", | 3314 | trace_btrfs_space_reservation(root->fs_info, "space_info", |
3315 | (u64)data_sinfo, bytes, 1); | 3315 | (u64)(unsigned long)data_sinfo, |
3316 | bytes, 1); | ||
3316 | spin_unlock(&data_sinfo->lock); | 3317 | spin_unlock(&data_sinfo->lock); |
3317 | 3318 | ||
3318 | return 0; | 3319 | return 0; |
@@ -3333,7 +3334,8 @@ void btrfs_free_reserved_data_space(struct inode *inode, u64 bytes) | |||
3333 | spin_lock(&data_sinfo->lock); | 3334 | spin_lock(&data_sinfo->lock); |
3334 | data_sinfo->bytes_may_use -= bytes; | 3335 | data_sinfo->bytes_may_use -= bytes; |
3335 | trace_btrfs_space_reservation(root->fs_info, "space_info", | 3336 | trace_btrfs_space_reservation(root->fs_info, "space_info", |
3336 | (u64)data_sinfo, bytes, 0); | 3337 | (u64)(unsigned long)data_sinfo, |
3338 | bytes, 0); | ||
3337 | spin_unlock(&data_sinfo->lock); | 3339 | spin_unlock(&data_sinfo->lock); |
3338 | } | 3340 | } |
3339 | 3341 | ||
@@ -3611,12 +3613,15 @@ static int may_commit_transaction(struct btrfs_root *root, | |||
3611 | if (space_info != delayed_rsv->space_info) | 3613 | if (space_info != delayed_rsv->space_info) |
3612 | return -ENOSPC; | 3614 | return -ENOSPC; |
3613 | 3615 | ||
3616 | spin_lock(&space_info->lock); | ||
3614 | spin_lock(&delayed_rsv->lock); | 3617 | spin_lock(&delayed_rsv->lock); |
3615 | if (delayed_rsv->size < bytes) { | 3618 | if (space_info->bytes_pinned + delayed_rsv->size < bytes) { |
3616 | spin_unlock(&delayed_rsv->lock); | 3619 | spin_unlock(&delayed_rsv->lock); |
3620 | spin_unlock(&space_info->lock); | ||
3617 | return -ENOSPC; | 3621 | return -ENOSPC; |
3618 | } | 3622 | } |
3619 | spin_unlock(&delayed_rsv->lock); | 3623 | spin_unlock(&delayed_rsv->lock); |
3624 | spin_unlock(&space_info->lock); | ||
3620 | 3625 | ||
3621 | commit: | 3626 | commit: |
3622 | trans = btrfs_join_transaction(root); | 3627 | trans = btrfs_join_transaction(root); |
@@ -3695,9 +3700,9 @@ again: | |||
3695 | if (used + orig_bytes <= space_info->total_bytes) { | 3700 | if (used + orig_bytes <= space_info->total_bytes) { |
3696 | space_info->bytes_may_use += orig_bytes; | 3701 | space_info->bytes_may_use += orig_bytes; |
3697 | trace_btrfs_space_reservation(root->fs_info, | 3702 | trace_btrfs_space_reservation(root->fs_info, |
3698 | "space_info", | 3703 | "space_info", |
3699 | (u64)space_info, | 3704 | (u64)(unsigned long)space_info, |
3700 | orig_bytes, 1); | 3705 | orig_bytes, 1); |
3701 | ret = 0; | 3706 | ret = 0; |
3702 | } else { | 3707 | } else { |
3703 | /* | 3708 | /* |
@@ -3766,9 +3771,9 @@ again: | |||
3766 | if (used + num_bytes < space_info->total_bytes + avail) { | 3771 | if (used + num_bytes < space_info->total_bytes + avail) { |
3767 | space_info->bytes_may_use += orig_bytes; | 3772 | space_info->bytes_may_use += orig_bytes; |
3768 | trace_btrfs_space_reservation(root->fs_info, | 3773 | trace_btrfs_space_reservation(root->fs_info, |
3769 | "space_info", | 3774 | "space_info", |
3770 | (u64)space_info, | 3775 | (u64)(unsigned long)space_info, |
3771 | orig_bytes, 1); | 3776 | orig_bytes, 1); |
3772 | ret = 0; | 3777 | ret = 0; |
3773 | } else { | 3778 | } else { |
3774 | wait_ordered = true; | 3779 | wait_ordered = true; |
@@ -3913,8 +3918,8 @@ static void block_rsv_release_bytes(struct btrfs_fs_info *fs_info, | |||
3913 | spin_lock(&space_info->lock); | 3918 | spin_lock(&space_info->lock); |
3914 | space_info->bytes_may_use -= num_bytes; | 3919 | space_info->bytes_may_use -= num_bytes; |
3915 | trace_btrfs_space_reservation(fs_info, "space_info", | 3920 | trace_btrfs_space_reservation(fs_info, "space_info", |
3916 | (u64)space_info, | 3921 | (u64)(unsigned long)space_info, |
3917 | num_bytes, 0); | 3922 | num_bytes, 0); |
3918 | space_info->reservation_progress++; | 3923 | space_info->reservation_progress++; |
3919 | spin_unlock(&space_info->lock); | 3924 | spin_unlock(&space_info->lock); |
3920 | } | 3925 | } |
@@ -4105,7 +4110,7 @@ static u64 calc_global_metadata_size(struct btrfs_fs_info *fs_info) | |||
4105 | num_bytes += div64_u64(data_used + meta_used, 50); | 4110 | num_bytes += div64_u64(data_used + meta_used, 50); |
4106 | 4111 | ||
4107 | if (num_bytes * 3 > meta_used) | 4112 | if (num_bytes * 3 > meta_used) |
4108 | num_bytes = div64_u64(meta_used, 3); | 4113 | num_bytes = div64_u64(meta_used, 3) * 2; |
4109 | 4114 | ||
4110 | return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10); | 4115 | return ALIGN(num_bytes, fs_info->extent_root->leafsize << 10); |
4111 | } | 4116 | } |
@@ -4132,14 +4137,14 @@ static void update_global_block_rsv(struct btrfs_fs_info *fs_info) | |||
4132 | block_rsv->reserved += num_bytes; | 4137 | block_rsv->reserved += num_bytes; |
4133 | sinfo->bytes_may_use += num_bytes; | 4138 | sinfo->bytes_may_use += num_bytes; |
4134 | trace_btrfs_space_reservation(fs_info, "space_info", | 4139 | trace_btrfs_space_reservation(fs_info, "space_info", |
4135 | (u64)sinfo, num_bytes, 1); | 4140 | (u64)(unsigned long)sinfo, num_bytes, 1); |
4136 | } | 4141 | } |
4137 | 4142 | ||
4138 | if (block_rsv->reserved >= block_rsv->size) { | 4143 | if (block_rsv->reserved >= block_rsv->size) { |
4139 | num_bytes = block_rsv->reserved - block_rsv->size; | 4144 | num_bytes = block_rsv->reserved - block_rsv->size; |
4140 | sinfo->bytes_may_use -= num_bytes; | 4145 | sinfo->bytes_may_use -= num_bytes; |
4141 | trace_btrfs_space_reservation(fs_info, "space_info", | 4146 | trace_btrfs_space_reservation(fs_info, "space_info", |
4142 | (u64)sinfo, num_bytes, 0); | 4147 | (u64)(unsigned long)sinfo, num_bytes, 0); |
4143 | sinfo->reservation_progress++; | 4148 | sinfo->reservation_progress++; |
4144 | block_rsv->reserved = block_rsv->size; | 4149 | block_rsv->reserved = block_rsv->size; |
4145 | block_rsv->full = 1; | 4150 | block_rsv->full = 1; |
@@ -4192,7 +4197,8 @@ void btrfs_trans_release_metadata(struct btrfs_trans_handle *trans, | |||
4192 | if (!trans->bytes_reserved) | 4197 | if (!trans->bytes_reserved) |
4193 | return; | 4198 | return; |
4194 | 4199 | ||
4195 | trace_btrfs_space_reservation(root->fs_info, "transaction", (u64)trans, | 4200 | trace_btrfs_space_reservation(root->fs_info, "transaction", |
4201 | (u64)(unsigned long)trans, | ||
4196 | trans->bytes_reserved, 0); | 4202 | trans->bytes_reserved, 0); |
4197 | btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); | 4203 | btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); |
4198 | trans->bytes_reserved = 0; | 4204 | trans->bytes_reserved = 0; |
@@ -4710,9 +4716,9 @@ static int btrfs_update_reserved_bytes(struct btrfs_block_group_cache *cache, | |||
4710 | space_info->bytes_reserved += num_bytes; | 4716 | space_info->bytes_reserved += num_bytes; |
4711 | if (reserve == RESERVE_ALLOC) { | 4717 | if (reserve == RESERVE_ALLOC) { |
4712 | trace_btrfs_space_reservation(cache->fs_info, | 4718 | trace_btrfs_space_reservation(cache->fs_info, |
4713 | "space_info", | 4719 | "space_info", |
4714 | (u64)space_info, | 4720 | (u64)(unsigned long)space_info, |
4715 | num_bytes, 0); | 4721 | num_bytes, 0); |
4716 | space_info->bytes_may_use -= num_bytes; | 4722 | space_info->bytes_may_use -= num_bytes; |
4717 | } | 4723 | } |
4718 | } | 4724 | } |
@@ -7886,9 +7892,16 @@ int btrfs_trim_fs(struct btrfs_root *root, struct fstrim_range *range) | |||
7886 | u64 start; | 7892 | u64 start; |
7887 | u64 end; | 7893 | u64 end; |
7888 | u64 trimmed = 0; | 7894 | u64 trimmed = 0; |
7895 | u64 total_bytes = btrfs_super_total_bytes(fs_info->super_copy); | ||
7889 | int ret = 0; | 7896 | int ret = 0; |
7890 | 7897 | ||
7891 | cache = btrfs_lookup_block_group(fs_info, range->start); | 7898 | /* |
7899 | * try to trim all FS space, our block group may start from non-zero. | ||
7900 | */ | ||
7901 | if (range->len == total_bytes) | ||
7902 | cache = btrfs_lookup_first_block_group(fs_info, range->start); | ||
7903 | else | ||
7904 | cache = btrfs_lookup_block_group(fs_info, range->start); | ||
7892 | 7905 | ||
7893 | while (cache) { | 7906 | while (cache) { |
7894 | if (cache->key.objectid >= (range->start + range->len)) { | 7907 | if (cache->key.objectid >= (range->start + range->len)) { |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index fcf77e1ded40..a55fbe6252de 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -513,6 +513,15 @@ hit_next: | |||
513 | WARN_ON(state->end < start); | 513 | WARN_ON(state->end < start); |
514 | last_end = state->end; | 514 | last_end = state->end; |
515 | 515 | ||
516 | if (state->end < end && !need_resched()) | ||
517 | next_node = rb_next(&state->rb_node); | ||
518 | else | ||
519 | next_node = NULL; | ||
520 | |||
521 | /* the state doesn't have the wanted bits, go ahead */ | ||
522 | if (!(state->state & bits)) | ||
523 | goto next; | ||
524 | |||
516 | /* | 525 | /* |
517 | * | ---- desired range ---- | | 526 | * | ---- desired range ---- | |
518 | * | state | or | 527 | * | state | or |
@@ -565,20 +574,15 @@ hit_next: | |||
565 | goto out; | 574 | goto out; |
566 | } | 575 | } |
567 | 576 | ||
568 | if (state->end < end && prealloc && !need_resched()) | ||
569 | next_node = rb_next(&state->rb_node); | ||
570 | else | ||
571 | next_node = NULL; | ||
572 | |||
573 | set |= clear_state_bit(tree, state, &bits, wake); | 577 | set |= clear_state_bit(tree, state, &bits, wake); |
578 | next: | ||
574 | if (last_end == (u64)-1) | 579 | if (last_end == (u64)-1) |
575 | goto out; | 580 | goto out; |
576 | start = last_end + 1; | 581 | start = last_end + 1; |
577 | if (start <= end && next_node) { | 582 | if (start <= end && next_node) { |
578 | state = rb_entry(next_node, struct extent_state, | 583 | state = rb_entry(next_node, struct extent_state, |
579 | rb_node); | 584 | rb_node); |
580 | if (state->start == start) | 585 | goto hit_next; |
581 | goto hit_next; | ||
582 | } | 586 | } |
583 | goto search_again; | 587 | goto search_again; |
584 | 588 | ||
@@ -961,8 +965,6 @@ hit_next: | |||
961 | 965 | ||
962 | set_state_bits(tree, state, &bits); | 966 | set_state_bits(tree, state, &bits); |
963 | clear_state_bit(tree, state, &clear_bits, 0); | 967 | clear_state_bit(tree, state, &clear_bits, 0); |
964 | |||
965 | merge_state(tree, state); | ||
966 | if (last_end == (u64)-1) | 968 | if (last_end == (u64)-1) |
967 | goto out; | 969 | goto out; |
968 | 970 | ||
@@ -1007,7 +1009,6 @@ hit_next: | |||
1007 | if (state->end <= end) { | 1009 | if (state->end <= end) { |
1008 | set_state_bits(tree, state, &bits); | 1010 | set_state_bits(tree, state, &bits); |
1009 | clear_state_bit(tree, state, &clear_bits, 0); | 1011 | clear_state_bit(tree, state, &clear_bits, 0); |
1010 | merge_state(tree, state); | ||
1011 | if (last_end == (u64)-1) | 1012 | if (last_end == (u64)-1) |
1012 | goto out; | 1013 | goto out; |
1013 | start = last_end + 1; | 1014 | start = last_end + 1; |
@@ -1068,8 +1069,6 @@ hit_next: | |||
1068 | 1069 | ||
1069 | set_state_bits(tree, prealloc, &bits); | 1070 | set_state_bits(tree, prealloc, &bits); |
1070 | clear_state_bit(tree, prealloc, &clear_bits, 0); | 1071 | clear_state_bit(tree, prealloc, &clear_bits, 0); |
1071 | |||
1072 | merge_state(tree, prealloc); | ||
1073 | prealloc = NULL; | 1072 | prealloc = NULL; |
1074 | goto out; | 1073 | goto out; |
1075 | } | 1074 | } |
@@ -2154,13 +2153,46 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page, | |||
2154 | "this_mirror=%d, num_copies=%d, in_validation=%d\n", read_mode, | 2153 | "this_mirror=%d, num_copies=%d, in_validation=%d\n", read_mode, |
2155 | failrec->this_mirror, num_copies, failrec->in_validation); | 2154 | failrec->this_mirror, num_copies, failrec->in_validation); |
2156 | 2155 | ||
2157 | tree->ops->submit_bio_hook(inode, read_mode, bio, failrec->this_mirror, | 2156 | ret = tree->ops->submit_bio_hook(inode, read_mode, bio, |
2158 | failrec->bio_flags, 0); | 2157 | failrec->this_mirror, |
2159 | return 0; | 2158 | failrec->bio_flags, 0); |
2159 | return ret; | ||
2160 | } | 2160 | } |
2161 | 2161 | ||
2162 | /* lots and lots of room for performance fixes in the end_bio funcs */ | 2162 | /* lots and lots of room for performance fixes in the end_bio funcs */ |
2163 | 2163 | ||
2164 | int end_extent_writepage(struct page *page, int err, u64 start, u64 end) | ||
2165 | { | ||
2166 | int uptodate = (err == 0); | ||
2167 | struct extent_io_tree *tree; | ||
2168 | int ret; | ||
2169 | |||
2170 | tree = &BTRFS_I(page->mapping->host)->io_tree; | ||
2171 | |||
2172 | if (tree->ops && tree->ops->writepage_end_io_hook) { | ||
2173 | ret = tree->ops->writepage_end_io_hook(page, start, | ||
2174 | end, NULL, uptodate); | ||
2175 | if (ret) | ||
2176 | uptodate = 0; | ||
2177 | } | ||
2178 | |||
2179 | if (!uptodate && tree->ops && | ||
2180 | tree->ops->writepage_io_failed_hook) { | ||
2181 | ret = tree->ops->writepage_io_failed_hook(NULL, page, | ||
2182 | start, end, NULL); | ||
2183 | /* Writeback already completed */ | ||
2184 | if (ret == 0) | ||
2185 | return 1; | ||
2186 | } | ||
2187 | |||
2188 | if (!uptodate) { | ||
2189 | clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS); | ||
2190 | ClearPageUptodate(page); | ||
2191 | SetPageError(page); | ||
2192 | } | ||
2193 | return 0; | ||
2194 | } | ||
2195 | |||
2164 | /* | 2196 | /* |
2165 | * after a writepage IO is done, we need to: | 2197 | * after a writepage IO is done, we need to: |
2166 | * clear the uptodate bits on error | 2198 | * clear the uptodate bits on error |
@@ -2172,13 +2204,11 @@ static int bio_readpage_error(struct bio *failed_bio, struct page *page, | |||
2172 | */ | 2204 | */ |
2173 | static void end_bio_extent_writepage(struct bio *bio, int err) | 2205 | static void end_bio_extent_writepage(struct bio *bio, int err) |
2174 | { | 2206 | { |
2175 | int uptodate = err == 0; | ||
2176 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; | 2207 | struct bio_vec *bvec = bio->bi_io_vec + bio->bi_vcnt - 1; |
2177 | struct extent_io_tree *tree; | 2208 | struct extent_io_tree *tree; |
2178 | u64 start; | 2209 | u64 start; |
2179 | u64 end; | 2210 | u64 end; |
2180 | int whole_page; | 2211 | int whole_page; |
2181 | int ret; | ||
2182 | 2212 | ||
2183 | do { | 2213 | do { |
2184 | struct page *page = bvec->bv_page; | 2214 | struct page *page = bvec->bv_page; |
@@ -2195,28 +2225,9 @@ static void end_bio_extent_writepage(struct bio *bio, int err) | |||
2195 | 2225 | ||
2196 | if (--bvec >= bio->bi_io_vec) | 2226 | if (--bvec >= bio->bi_io_vec) |
2197 | prefetchw(&bvec->bv_page->flags); | 2227 | prefetchw(&bvec->bv_page->flags); |
2198 | if (tree->ops && tree->ops->writepage_end_io_hook) { | ||
2199 | ret = tree->ops->writepage_end_io_hook(page, start, | ||
2200 | end, NULL, uptodate); | ||
2201 | if (ret) | ||
2202 | uptodate = 0; | ||
2203 | } | ||
2204 | |||
2205 | if (!uptodate && tree->ops && | ||
2206 | tree->ops->writepage_io_failed_hook) { | ||
2207 | ret = tree->ops->writepage_io_failed_hook(bio, page, | ||
2208 | start, end, NULL); | ||
2209 | if (ret == 0) { | ||
2210 | uptodate = (err == 0); | ||
2211 | continue; | ||
2212 | } | ||
2213 | } | ||
2214 | 2228 | ||
2215 | if (!uptodate) { | 2229 | if (end_extent_writepage(page, err, start, end)) |
2216 | clear_extent_uptodate(tree, start, end, NULL, GFP_NOFS); | 2230 | continue; |
2217 | ClearPageUptodate(page); | ||
2218 | SetPageError(page); | ||
2219 | } | ||
2220 | 2231 | ||
2221 | if (whole_page) | 2232 | if (whole_page) |
2222 | end_page_writeback(page); | 2233 | end_page_writeback(page); |
@@ -2779,9 +2790,12 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, | |||
2779 | delalloc_start = delalloc_end + 1; | 2790 | delalloc_start = delalloc_end + 1; |
2780 | continue; | 2791 | continue; |
2781 | } | 2792 | } |
2782 | tree->ops->fill_delalloc(inode, page, delalloc_start, | 2793 | ret = tree->ops->fill_delalloc(inode, page, |
2783 | delalloc_end, &page_started, | 2794 | delalloc_start, |
2784 | &nr_written); | 2795 | delalloc_end, |
2796 | &page_started, | ||
2797 | &nr_written); | ||
2798 | BUG_ON(ret); | ||
2785 | /* | 2799 | /* |
2786 | * delalloc_end is already one less than the total | 2800 | * delalloc_end is already one less than the total |
2787 | * length, so we don't subtract one from | 2801 | * length, so we don't subtract one from |
@@ -2818,8 +2832,12 @@ static int __extent_writepage(struct page *page, struct writeback_control *wbc, | |||
2818 | if (tree->ops && tree->ops->writepage_start_hook) { | 2832 | if (tree->ops && tree->ops->writepage_start_hook) { |
2819 | ret = tree->ops->writepage_start_hook(page, start, | 2833 | ret = tree->ops->writepage_start_hook(page, start, |
2820 | page_end); | 2834 | page_end); |
2821 | if (ret == -EAGAIN) { | 2835 | if (ret) { |
2822 | redirty_page_for_writepage(wbc, page); | 2836 | /* Fixup worker will requeue */ |
2837 | if (ret == -EBUSY) | ||
2838 | wbc->pages_skipped++; | ||
2839 | else | ||
2840 | redirty_page_for_writepage(wbc, page); | ||
2823 | update_nr_written(page, wbc, nr_written); | 2841 | update_nr_written(page, wbc, nr_written); |
2824 | unlock_page(page); | 2842 | unlock_page(page); |
2825 | ret = 0; | 2843 | ret = 0; |
@@ -3289,7 +3307,7 @@ int try_release_extent_mapping(struct extent_map_tree *map, | |||
3289 | len = end - start + 1; | 3307 | len = end - start + 1; |
3290 | write_lock(&map->lock); | 3308 | write_lock(&map->lock); |
3291 | em = lookup_extent_mapping(map, start, len); | 3309 | em = lookup_extent_mapping(map, start, len); |
3292 | if (IS_ERR_OR_NULL(em)) { | 3310 | if (!em) { |
3293 | write_unlock(&map->lock); | 3311 | write_unlock(&map->lock); |
3294 | break; | 3312 | break; |
3295 | } | 3313 | } |
@@ -3853,10 +3871,9 @@ int clear_extent_buffer_uptodate(struct extent_io_tree *tree, | |||
3853 | num_pages = num_extent_pages(eb->start, eb->len); | 3871 | num_pages = num_extent_pages(eb->start, eb->len); |
3854 | clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); | 3872 | clear_bit(EXTENT_BUFFER_UPTODATE, &eb->bflags); |
3855 | 3873 | ||
3856 | if (eb_straddles_pages(eb)) { | 3874 | clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, |
3857 | clear_extent_uptodate(tree, eb->start, eb->start + eb->len - 1, | 3875 | cached_state, GFP_NOFS); |
3858 | cached_state, GFP_NOFS); | 3876 | |
3859 | } | ||
3860 | for (i = 0; i < num_pages; i++) { | 3877 | for (i = 0; i < num_pages; i++) { |
3861 | page = extent_buffer_page(eb, i); | 3878 | page = extent_buffer_page(eb, i); |
3862 | if (page) | 3879 | if (page) |
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index bc6a042cb6fc..cecc3518c121 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -319,4 +319,5 @@ struct btrfs_mapping_tree; | |||
319 | int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start, | 319 | int repair_io_failure(struct btrfs_mapping_tree *map_tree, u64 start, |
320 | u64 length, u64 logical, struct page *page, | 320 | u64 length, u64 logical, struct page *page, |
321 | int mirror_num); | 321 | int mirror_num); |
322 | int end_extent_writepage(struct page *page, int err, u64 start, u64 end); | ||
322 | #endif | 323 | #endif |
diff --git a/fs/btrfs/extent_map.h b/fs/btrfs/extent_map.h index 33a7890b1f40..1195f09761fe 100644 --- a/fs/btrfs/extent_map.h +++ b/fs/btrfs/extent_map.h | |||
@@ -26,8 +26,8 @@ struct extent_map { | |||
26 | unsigned long flags; | 26 | unsigned long flags; |
27 | struct block_device *bdev; | 27 | struct block_device *bdev; |
28 | atomic_t refs; | 28 | atomic_t refs; |
29 | unsigned int in_tree:1; | 29 | unsigned int in_tree; |
30 | unsigned int compress_type:4; | 30 | unsigned int compress_type; |
31 | }; | 31 | }; |
32 | 32 | ||
33 | struct extent_map_tree { | 33 | struct extent_map_tree { |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 859ba2dd8890..e8d06b6b9194 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -1605,6 +1605,14 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1605 | return -EOPNOTSUPP; | 1605 | return -EOPNOTSUPP; |
1606 | 1606 | ||
1607 | /* | 1607 | /* |
1608 | * Make sure we have enough space before we do the | ||
1609 | * allocation. | ||
1610 | */ | ||
1611 | ret = btrfs_check_data_free_space(inode, len); | ||
1612 | if (ret) | ||
1613 | return ret; | ||
1614 | |||
1615 | /* | ||
1608 | * wait for ordered IO before we have any locks. We'll loop again | 1616 | * wait for ordered IO before we have any locks. We'll loop again |
1609 | * below with the locks held. | 1617 | * below with the locks held. |
1610 | */ | 1618 | */ |
@@ -1667,27 +1675,12 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1667 | if (em->block_start == EXTENT_MAP_HOLE || | 1675 | if (em->block_start == EXTENT_MAP_HOLE || |
1668 | (cur_offset >= inode->i_size && | 1676 | (cur_offset >= inode->i_size && |
1669 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { | 1677 | !test_bit(EXTENT_FLAG_PREALLOC, &em->flags))) { |
1670 | |||
1671 | /* | ||
1672 | * Make sure we have enough space before we do the | ||
1673 | * allocation. | ||
1674 | */ | ||
1675 | ret = btrfs_check_data_free_space(inode, last_byte - | ||
1676 | cur_offset); | ||
1677 | if (ret) { | ||
1678 | free_extent_map(em); | ||
1679 | break; | ||
1680 | } | ||
1681 | |||
1682 | ret = btrfs_prealloc_file_range(inode, mode, cur_offset, | 1678 | ret = btrfs_prealloc_file_range(inode, mode, cur_offset, |
1683 | last_byte - cur_offset, | 1679 | last_byte - cur_offset, |
1684 | 1 << inode->i_blkbits, | 1680 | 1 << inode->i_blkbits, |
1685 | offset + len, | 1681 | offset + len, |
1686 | &alloc_hint); | 1682 | &alloc_hint); |
1687 | 1683 | ||
1688 | /* Let go of our reservation. */ | ||
1689 | btrfs_free_reserved_data_space(inode, last_byte - | ||
1690 | cur_offset); | ||
1691 | if (ret < 0) { | 1684 | if (ret < 0) { |
1692 | free_extent_map(em); | 1685 | free_extent_map(em); |
1693 | break; | 1686 | break; |
@@ -1715,6 +1708,8 @@ static long btrfs_fallocate(struct file *file, int mode, | |||
1715 | &cached_state, GFP_NOFS); | 1708 | &cached_state, GFP_NOFS); |
1716 | out: | 1709 | out: |
1717 | mutex_unlock(&inode->i_mutex); | 1710 | mutex_unlock(&inode->i_mutex); |
1711 | /* Let go of our reservation. */ | ||
1712 | btrfs_free_reserved_data_space(inode, len); | ||
1718 | return ret; | 1713 | return ret; |
1719 | } | 1714 | } |
1720 | 1715 | ||
@@ -1761,7 +1756,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) | |||
1761 | start - root->sectorsize, | 1756 | start - root->sectorsize, |
1762 | root->sectorsize, 0); | 1757 | root->sectorsize, 0); |
1763 | if (IS_ERR(em)) { | 1758 | if (IS_ERR(em)) { |
1764 | ret = -ENXIO; | 1759 | ret = PTR_ERR(em); |
1765 | goto out; | 1760 | goto out; |
1766 | } | 1761 | } |
1767 | last_end = em->start + em->len; | 1762 | last_end = em->start + em->len; |
@@ -1773,7 +1768,7 @@ static int find_desired_extent(struct inode *inode, loff_t *offset, int origin) | |||
1773 | while (1) { | 1768 | while (1) { |
1774 | em = btrfs_get_extent_fiemap(inode, NULL, 0, start, len, 0); | 1769 | em = btrfs_get_extent_fiemap(inode, NULL, 0, start, len, 0); |
1775 | if (IS_ERR(em)) { | 1770 | if (IS_ERR(em)) { |
1776 | ret = -ENXIO; | 1771 | ret = PTR_ERR(em); |
1777 | break; | 1772 | break; |
1778 | } | 1773 | } |
1779 | 1774 | ||
diff --git a/fs/btrfs/free-space-cache.c b/fs/btrfs/free-space-cache.c index c2f20594c9f7..710ea380c7ed 100644 --- a/fs/btrfs/free-space-cache.c +++ b/fs/btrfs/free-space-cache.c | |||
@@ -777,6 +777,7 @@ int load_free_space_cache(struct btrfs_fs_info *fs_info, | |||
777 | spin_lock(&block_group->lock); | 777 | spin_lock(&block_group->lock); |
778 | if (block_group->disk_cache_state != BTRFS_DC_WRITTEN) { | 778 | if (block_group->disk_cache_state != BTRFS_DC_WRITTEN) { |
779 | spin_unlock(&block_group->lock); | 779 | spin_unlock(&block_group->lock); |
780 | btrfs_free_path(path); | ||
780 | goto out; | 781 | goto out; |
781 | } | 782 | } |
782 | spin_unlock(&block_group->lock); | 783 | spin_unlock(&block_group->lock); |
diff --git a/fs/btrfs/inode-map.c b/fs/btrfs/inode-map.c index 213ffa86ce1b..ee15d88b33d2 100644 --- a/fs/btrfs/inode-map.c +++ b/fs/btrfs/inode-map.c | |||
@@ -438,7 +438,8 @@ int btrfs_save_ino_cache(struct btrfs_root *root, | |||
438 | trans->bytes_reserved); | 438 | trans->bytes_reserved); |
439 | if (ret) | 439 | if (ret) |
440 | goto out; | 440 | goto out; |
441 | trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans, | 441 | trace_btrfs_space_reservation(root->fs_info, "ino_cache", |
442 | (u64)(unsigned long)trans, | ||
442 | trans->bytes_reserved, 1); | 443 | trans->bytes_reserved, 1); |
443 | again: | 444 | again: |
444 | inode = lookup_free_ino_inode(root, path); | 445 | inode = lookup_free_ino_inode(root, path); |
@@ -500,7 +501,8 @@ again: | |||
500 | out_put: | 501 | out_put: |
501 | iput(inode); | 502 | iput(inode); |
502 | out_release: | 503 | out_release: |
503 | trace_btrfs_space_reservation(root->fs_info, "ino_cache", (u64)trans, | 504 | trace_btrfs_space_reservation(root->fs_info, "ino_cache", |
505 | (u64)(unsigned long)trans, | ||
504 | trans->bytes_reserved, 0); | 506 | trans->bytes_reserved, 0); |
505 | btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); | 507 | btrfs_block_rsv_release(root, trans->block_rsv, trans->bytes_reserved); |
506 | out: | 508 | out: |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 32214fe0f7e3..892b34785ccc 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -1555,6 +1555,7 @@ static void btrfs_writepage_fixup_worker(struct btrfs_work *work) | |||
1555 | struct inode *inode; | 1555 | struct inode *inode; |
1556 | u64 page_start; | 1556 | u64 page_start; |
1557 | u64 page_end; | 1557 | u64 page_end; |
1558 | int ret; | ||
1558 | 1559 | ||
1559 | fixup = container_of(work, struct btrfs_writepage_fixup, work); | 1560 | fixup = container_of(work, struct btrfs_writepage_fixup, work); |
1560 | page = fixup->page; | 1561 | page = fixup->page; |
@@ -1582,12 +1583,21 @@ again: | |||
1582 | page_end, &cached_state, GFP_NOFS); | 1583 | page_end, &cached_state, GFP_NOFS); |
1583 | unlock_page(page); | 1584 | unlock_page(page); |
1584 | btrfs_start_ordered_extent(inode, ordered, 1); | 1585 | btrfs_start_ordered_extent(inode, ordered, 1); |
1586 | btrfs_put_ordered_extent(ordered); | ||
1585 | goto again; | 1587 | goto again; |
1586 | } | 1588 | } |
1587 | 1589 | ||
1588 | BUG(); | 1590 | ret = btrfs_delalloc_reserve_space(inode, PAGE_CACHE_SIZE); |
1591 | if (ret) { | ||
1592 | mapping_set_error(page->mapping, ret); | ||
1593 | end_extent_writepage(page, ret, page_start, page_end); | ||
1594 | ClearPageChecked(page); | ||
1595 | goto out; | ||
1596 | } | ||
1597 | |||
1589 | btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state); | 1598 | btrfs_set_extent_delalloc(inode, page_start, page_end, &cached_state); |
1590 | ClearPageChecked(page); | 1599 | ClearPageChecked(page); |
1600 | set_page_dirty(page); | ||
1591 | out: | 1601 | out: |
1592 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end, | 1602 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, page_start, page_end, |
1593 | &cached_state, GFP_NOFS); | 1603 | &cached_state, GFP_NOFS); |
@@ -1630,7 +1640,7 @@ static int btrfs_writepage_start_hook(struct page *page, u64 start, u64 end) | |||
1630 | fixup->work.func = btrfs_writepage_fixup_worker; | 1640 | fixup->work.func = btrfs_writepage_fixup_worker; |
1631 | fixup->page = page; | 1641 | fixup->page = page; |
1632 | btrfs_queue_worker(&root->fs_info->fixup_workers, &fixup->work); | 1642 | btrfs_queue_worker(&root->fs_info->fixup_workers, &fixup->work); |
1633 | return -EAGAIN; | 1643 | return -EBUSY; |
1634 | } | 1644 | } |
1635 | 1645 | ||
1636 | static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, | 1646 | static int insert_reserved_file_extent(struct btrfs_trans_handle *trans, |
@@ -4575,7 +4585,8 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, | |||
4575 | ret = btrfs_insert_dir_item(trans, root, name, name_len, | 4585 | ret = btrfs_insert_dir_item(trans, root, name, name_len, |
4576 | parent_inode, &key, | 4586 | parent_inode, &key, |
4577 | btrfs_inode_type(inode), index); | 4587 | btrfs_inode_type(inode), index); |
4578 | BUG_ON(ret); | 4588 | if (ret) |
4589 | goto fail_dir_item; | ||
4579 | 4590 | ||
4580 | btrfs_i_size_write(parent_inode, parent_inode->i_size + | 4591 | btrfs_i_size_write(parent_inode, parent_inode->i_size + |
4581 | name_len * 2); | 4592 | name_len * 2); |
@@ -4583,6 +4594,23 @@ int btrfs_add_link(struct btrfs_trans_handle *trans, | |||
4583 | ret = btrfs_update_inode(trans, root, parent_inode); | 4594 | ret = btrfs_update_inode(trans, root, parent_inode); |
4584 | } | 4595 | } |
4585 | return ret; | 4596 | return ret; |
4597 | |||
4598 | fail_dir_item: | ||
4599 | if (unlikely(ino == BTRFS_FIRST_FREE_OBJECTID)) { | ||
4600 | u64 local_index; | ||
4601 | int err; | ||
4602 | err = btrfs_del_root_ref(trans, root->fs_info->tree_root, | ||
4603 | key.objectid, root->root_key.objectid, | ||
4604 | parent_ino, &local_index, name, name_len); | ||
4605 | |||
4606 | } else if (add_backref) { | ||
4607 | u64 local_index; | ||
4608 | int err; | ||
4609 | |||
4610 | err = btrfs_del_inode_ref(trans, root, name, name_len, | ||
4611 | ino, parent_ino, &local_index); | ||
4612 | } | ||
4613 | return ret; | ||
4586 | } | 4614 | } |
4587 | 4615 | ||
4588 | static int btrfs_add_nondir(struct btrfs_trans_handle *trans, | 4616 | static int btrfs_add_nondir(struct btrfs_trans_handle *trans, |
@@ -6696,8 +6724,10 @@ int btrfs_create_subvol_root(struct btrfs_trans_handle *trans, | |||
6696 | int err; | 6724 | int err; |
6697 | u64 index = 0; | 6725 | u64 index = 0; |
6698 | 6726 | ||
6699 | inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, new_dirid, | 6727 | inode = btrfs_new_inode(trans, new_root, NULL, "..", 2, |
6700 | new_dirid, S_IFDIR | 0700, &index); | 6728 | new_dirid, new_dirid, |
6729 | S_IFDIR | (~current_umask() & S_IRWXUGO), | ||
6730 | &index); | ||
6701 | if (IS_ERR(inode)) | 6731 | if (IS_ERR(inode)) |
6702 | return PTR_ERR(inode); | 6732 | return PTR_ERR(inode); |
6703 | inode->i_op = &btrfs_dir_inode_operations; | 6733 | inode->i_op = &btrfs_dir_inode_operations; |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index 03bb62a9ee24..d8b54715c2de 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -861,6 +861,7 @@ static int cluster_pages_for_defrag(struct inode *inode, | |||
861 | int i_done; | 861 | int i_done; |
862 | struct btrfs_ordered_extent *ordered; | 862 | struct btrfs_ordered_extent *ordered; |
863 | struct extent_state *cached_state = NULL; | 863 | struct extent_state *cached_state = NULL; |
864 | struct extent_io_tree *tree; | ||
864 | gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping); | 865 | gfp_t mask = btrfs_alloc_write_mask(inode->i_mapping); |
865 | 866 | ||
866 | if (isize == 0) | 867 | if (isize == 0) |
@@ -871,18 +872,34 @@ static int cluster_pages_for_defrag(struct inode *inode, | |||
871 | num_pages << PAGE_CACHE_SHIFT); | 872 | num_pages << PAGE_CACHE_SHIFT); |
872 | if (ret) | 873 | if (ret) |
873 | return ret; | 874 | return ret; |
874 | again: | ||
875 | ret = 0; | ||
876 | i_done = 0; | 875 | i_done = 0; |
876 | tree = &BTRFS_I(inode)->io_tree; | ||
877 | 877 | ||
878 | /* step one, lock all the pages */ | 878 | /* step one, lock all the pages */ |
879 | for (i = 0; i < num_pages; i++) { | 879 | for (i = 0; i < num_pages; i++) { |
880 | struct page *page; | 880 | struct page *page; |
881 | again: | ||
881 | page = find_or_create_page(inode->i_mapping, | 882 | page = find_or_create_page(inode->i_mapping, |
882 | start_index + i, mask); | 883 | start_index + i, mask); |
883 | if (!page) | 884 | if (!page) |
884 | break; | 885 | break; |
885 | 886 | ||
887 | page_start = page_offset(page); | ||
888 | page_end = page_start + PAGE_CACHE_SIZE - 1; | ||
889 | while (1) { | ||
890 | lock_extent(tree, page_start, page_end, GFP_NOFS); | ||
891 | ordered = btrfs_lookup_ordered_extent(inode, | ||
892 | page_start); | ||
893 | unlock_extent(tree, page_start, page_end, GFP_NOFS); | ||
894 | if (!ordered) | ||
895 | break; | ||
896 | |||
897 | unlock_page(page); | ||
898 | btrfs_start_ordered_extent(inode, ordered, 1); | ||
899 | btrfs_put_ordered_extent(ordered); | ||
900 | lock_page(page); | ||
901 | } | ||
902 | |||
886 | if (!PageUptodate(page)) { | 903 | if (!PageUptodate(page)) { |
887 | btrfs_readpage(NULL, page); | 904 | btrfs_readpage(NULL, page); |
888 | lock_page(page); | 905 | lock_page(page); |
@@ -893,15 +910,22 @@ again: | |||
893 | break; | 910 | break; |
894 | } | 911 | } |
895 | } | 912 | } |
913 | |||
896 | isize = i_size_read(inode); | 914 | isize = i_size_read(inode); |
897 | file_end = (isize - 1) >> PAGE_CACHE_SHIFT; | 915 | file_end = (isize - 1) >> PAGE_CACHE_SHIFT; |
898 | if (!isize || page->index > file_end || | 916 | if (!isize || page->index > file_end) { |
899 | page->mapping != inode->i_mapping) { | ||
900 | /* whoops, we blew past eof, skip this page */ | 917 | /* whoops, we blew past eof, skip this page */ |
901 | unlock_page(page); | 918 | unlock_page(page); |
902 | page_cache_release(page); | 919 | page_cache_release(page); |
903 | break; | 920 | break; |
904 | } | 921 | } |
922 | |||
923 | if (page->mapping != inode->i_mapping) { | ||
924 | unlock_page(page); | ||
925 | page_cache_release(page); | ||
926 | goto again; | ||
927 | } | ||
928 | |||
905 | pages[i] = page; | 929 | pages[i] = page; |
906 | i_done++; | 930 | i_done++; |
907 | } | 931 | } |
@@ -924,25 +948,6 @@ again: | |||
924 | lock_extent_bits(&BTRFS_I(inode)->io_tree, | 948 | lock_extent_bits(&BTRFS_I(inode)->io_tree, |
925 | page_start, page_end - 1, 0, &cached_state, | 949 | page_start, page_end - 1, 0, &cached_state, |
926 | GFP_NOFS); | 950 | GFP_NOFS); |
927 | ordered = btrfs_lookup_first_ordered_extent(inode, page_end - 1); | ||
928 | if (ordered && | ||
929 | ordered->file_offset + ordered->len > page_start && | ||
930 | ordered->file_offset < page_end) { | ||
931 | btrfs_put_ordered_extent(ordered); | ||
932 | unlock_extent_cached(&BTRFS_I(inode)->io_tree, | ||
933 | page_start, page_end - 1, | ||
934 | &cached_state, GFP_NOFS); | ||
935 | for (i = 0; i < i_done; i++) { | ||
936 | unlock_page(pages[i]); | ||
937 | page_cache_release(pages[i]); | ||
938 | } | ||
939 | btrfs_wait_ordered_range(inode, page_start, | ||
940 | page_end - page_start); | ||
941 | goto again; | ||
942 | } | ||
943 | if (ordered) | ||
944 | btrfs_put_ordered_extent(ordered); | ||
945 | |||
946 | clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, | 951 | clear_extent_bit(&BTRFS_I(inode)->io_tree, page_start, |
947 | page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC | | 952 | page_end - 1, EXTENT_DIRTY | EXTENT_DELALLOC | |
948 | EXTENT_DO_ACCOUNTING, 0, 0, &cached_state, | 953 | EXTENT_DO_ACCOUNTING, 0, 0, &cached_state, |
@@ -1327,6 +1332,12 @@ static noinline int btrfs_ioctl_snap_create_transid(struct file *file, | |||
1327 | goto out; | 1332 | goto out; |
1328 | } | 1333 | } |
1329 | 1334 | ||
1335 | if (name[0] == '.' && | ||
1336 | (namelen == 1 || (name[1] == '.' && namelen == 2))) { | ||
1337 | ret = -EEXIST; | ||
1338 | goto out; | ||
1339 | } | ||
1340 | |||
1330 | if (subvol) { | 1341 | if (subvol) { |
1331 | ret = btrfs_mksubvol(&file->f_path, name, namelen, | 1342 | ret = btrfs_mksubvol(&file->f_path, name, namelen, |
1332 | NULL, transid, readonly); | 1343 | NULL, transid, readonly); |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index 9770cc5bfb76..abc0fbffa510 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -1367,7 +1367,8 @@ out: | |||
1367 | } | 1367 | } |
1368 | 1368 | ||
1369 | static noinline_for_stack int scrub_chunk(struct scrub_dev *sdev, | 1369 | static noinline_for_stack int scrub_chunk(struct scrub_dev *sdev, |
1370 | u64 chunk_tree, u64 chunk_objectid, u64 chunk_offset, u64 length) | 1370 | u64 chunk_tree, u64 chunk_objectid, u64 chunk_offset, u64 length, |
1371 | u64 dev_offset) | ||
1371 | { | 1372 | { |
1372 | struct btrfs_mapping_tree *map_tree = | 1373 | struct btrfs_mapping_tree *map_tree = |
1373 | &sdev->dev->dev_root->fs_info->mapping_tree; | 1374 | &sdev->dev->dev_root->fs_info->mapping_tree; |
@@ -1391,7 +1392,8 @@ static noinline_for_stack int scrub_chunk(struct scrub_dev *sdev, | |||
1391 | goto out; | 1392 | goto out; |
1392 | 1393 | ||
1393 | for (i = 0; i < map->num_stripes; ++i) { | 1394 | for (i = 0; i < map->num_stripes; ++i) { |
1394 | if (map->stripes[i].dev == sdev->dev) { | 1395 | if (map->stripes[i].dev == sdev->dev && |
1396 | map->stripes[i].physical == dev_offset) { | ||
1395 | ret = scrub_stripe(sdev, map, i, chunk_offset, length); | 1397 | ret = scrub_stripe(sdev, map, i, chunk_offset, length); |
1396 | if (ret) | 1398 | if (ret) |
1397 | goto out; | 1399 | goto out; |
@@ -1487,7 +1489,7 @@ int scrub_enumerate_chunks(struct scrub_dev *sdev, u64 start, u64 end) | |||
1487 | break; | 1489 | break; |
1488 | } | 1490 | } |
1489 | ret = scrub_chunk(sdev, chunk_tree, chunk_objectid, | 1491 | ret = scrub_chunk(sdev, chunk_tree, chunk_objectid, |
1490 | chunk_offset, length); | 1492 | chunk_offset, length, found_key.offset); |
1491 | btrfs_put_block_group(cache); | 1493 | btrfs_put_block_group(cache); |
1492 | if (ret) | 1494 | if (ret) |
1493 | break; | 1495 | break; |
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 287a6728b1ad..04b77e3ceb7a 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -327,7 +327,8 @@ again: | |||
327 | 327 | ||
328 | if (num_bytes) { | 328 | if (num_bytes) { |
329 | trace_btrfs_space_reservation(root->fs_info, "transaction", | 329 | trace_btrfs_space_reservation(root->fs_info, "transaction", |
330 | (u64)h, num_bytes, 1); | 330 | (u64)(unsigned long)h, |
331 | num_bytes, 1); | ||
331 | h->block_rsv = &root->fs_info->trans_block_rsv; | 332 | h->block_rsv = &root->fs_info->trans_block_rsv; |
332 | h->bytes_reserved = num_bytes; | 333 | h->bytes_reserved = num_bytes; |
333 | } | 334 | } |
@@ -915,7 +916,11 @@ static noinline int create_pending_snapshot(struct btrfs_trans_handle *trans, | |||
915 | dentry->d_name.name, dentry->d_name.len, | 916 | dentry->d_name.name, dentry->d_name.len, |
916 | parent_inode, &key, | 917 | parent_inode, &key, |
917 | BTRFS_FT_DIR, index); | 918 | BTRFS_FT_DIR, index); |
918 | BUG_ON(ret); | 919 | if (ret) { |
920 | pending->error = -EEXIST; | ||
921 | dput(parent); | ||
922 | goto fail; | ||
923 | } | ||
919 | 924 | ||
920 | btrfs_i_size_write(parent_inode, parent_inode->i_size + | 925 | btrfs_i_size_write(parent_inode, parent_inode->i_size + |
921 | dentry->d_name.len * 2); | 926 | dentry->d_name.len * 2); |
@@ -993,12 +998,9 @@ static noinline int create_pending_snapshots(struct btrfs_trans_handle *trans, | |||
993 | { | 998 | { |
994 | struct btrfs_pending_snapshot *pending; | 999 | struct btrfs_pending_snapshot *pending; |
995 | struct list_head *head = &trans->transaction->pending_snapshots; | 1000 | struct list_head *head = &trans->transaction->pending_snapshots; |
996 | int ret; | ||
997 | 1001 | ||
998 | list_for_each_entry(pending, head, list) { | 1002 | list_for_each_entry(pending, head, list) |
999 | ret = create_pending_snapshot(trans, fs_info, pending); | 1003 | create_pending_snapshot(trans, fs_info, pending); |
1000 | BUG_ON(ret); | ||
1001 | } | ||
1002 | return 0; | 1004 | return 0; |
1003 | } | 1005 | } |
1004 | 1006 | ||
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index 0b4e2af7954d..ef41f285a475 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -459,12 +459,23 @@ int btrfs_close_extra_devices(struct btrfs_fs_devices *fs_devices) | |||
459 | { | 459 | { |
460 | struct btrfs_device *device, *next; | 460 | struct btrfs_device *device, *next; |
461 | 461 | ||
462 | struct block_device *latest_bdev = NULL; | ||
463 | u64 latest_devid = 0; | ||
464 | u64 latest_transid = 0; | ||
465 | |||
462 | mutex_lock(&uuid_mutex); | 466 | mutex_lock(&uuid_mutex); |
463 | again: | 467 | again: |
464 | /* This is the initialized path, it is safe to release the devices. */ | 468 | /* This is the initialized path, it is safe to release the devices. */ |
465 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { | 469 | list_for_each_entry_safe(device, next, &fs_devices->devices, dev_list) { |
466 | if (device->in_fs_metadata) | 470 | if (device->in_fs_metadata) { |
471 | if (!latest_transid || | ||
472 | device->generation > latest_transid) { | ||
473 | latest_devid = device->devid; | ||
474 | latest_transid = device->generation; | ||
475 | latest_bdev = device->bdev; | ||
476 | } | ||
467 | continue; | 477 | continue; |
478 | } | ||
468 | 479 | ||
469 | if (device->bdev) { | 480 | if (device->bdev) { |
470 | blkdev_put(device->bdev, device->mode); | 481 | blkdev_put(device->bdev, device->mode); |
@@ -487,6 +498,10 @@ again: | |||
487 | goto again; | 498 | goto again; |
488 | } | 499 | } |
489 | 500 | ||
501 | fs_devices->latest_bdev = latest_bdev; | ||
502 | fs_devices->latest_devid = latest_devid; | ||
503 | fs_devices->latest_trans = latest_transid; | ||
504 | |||
490 | mutex_unlock(&uuid_mutex); | 505 | mutex_unlock(&uuid_mutex); |
491 | return 0; | 506 | return 0; |
492 | } | 507 | } |
@@ -1953,7 +1968,7 @@ static int btrfs_relocate_chunk(struct btrfs_root *root, | |||
1953 | em = lookup_extent_mapping(em_tree, chunk_offset, 1); | 1968 | em = lookup_extent_mapping(em_tree, chunk_offset, 1); |
1954 | read_unlock(&em_tree->lock); | 1969 | read_unlock(&em_tree->lock); |
1955 | 1970 | ||
1956 | BUG_ON(em->start > chunk_offset || | 1971 | BUG_ON(!em || em->start > chunk_offset || |
1957 | em->start + em->len < chunk_offset); | 1972 | em->start + em->len < chunk_offset); |
1958 | map = (struct map_lookup *)em->bdev; | 1973 | map = (struct map_lookup *)em->bdev; |
1959 | 1974 | ||
@@ -4356,6 +4371,20 @@ int btrfs_read_sys_array(struct btrfs_root *root) | |||
4356 | return -ENOMEM; | 4371 | return -ENOMEM; |
4357 | btrfs_set_buffer_uptodate(sb); | 4372 | btrfs_set_buffer_uptodate(sb); |
4358 | btrfs_set_buffer_lockdep_class(root->root_key.objectid, sb, 0); | 4373 | btrfs_set_buffer_lockdep_class(root->root_key.objectid, sb, 0); |
4374 | /* | ||
4375 | * The sb extent buffer is artifical and just used to read the system array. | ||
4376 | * btrfs_set_buffer_uptodate() call does not properly mark all it's | ||
4377 | * pages up-to-date when the page is larger: extent does not cover the | ||
4378 | * whole page and consequently check_page_uptodate does not find all | ||
4379 | * the page's extents up-to-date (the hole beyond sb), | ||
4380 | * write_extent_buffer then triggers a WARN_ON. | ||
4381 | * | ||
4382 | * Regular short extents go through mark_extent_buffer_dirty/writeback cycle, | ||
4383 | * but sb spans only this function. Add an explicit SetPageUptodate call | ||
4384 | * to silence the warning eg. on PowerPC 64. | ||
4385 | */ | ||
4386 | if (PAGE_CACHE_SIZE > BTRFS_SUPER_INFO_SIZE) | ||
4387 | SetPageUptodate(sb->first_page); | ||
4359 | 4388 | ||
4360 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); | 4389 | write_extent_buffer(sb, super_copy, 0, BTRFS_SUPER_INFO_SIZE); |
4361 | array_size = btrfs_super_sys_array_size(super_copy); | 4390 | array_size = btrfs_super_sys_array_size(super_copy); |
diff --git a/fs/direct-io.c b/fs/direct-io.c index 4a588dbd11bf..f4aadd15b613 100644 --- a/fs/direct-io.c +++ b/fs/direct-io.c | |||
@@ -173,7 +173,7 @@ void inode_dio_wait(struct inode *inode) | |||
173 | if (atomic_read(&inode->i_dio_count)) | 173 | if (atomic_read(&inode->i_dio_count)) |
174 | __inode_dio_wait(inode); | 174 | __inode_dio_wait(inode); |
175 | } | 175 | } |
176 | EXPORT_SYMBOL_GPL(inode_dio_wait); | 176 | EXPORT_SYMBOL(inode_dio_wait); |
177 | 177 | ||
178 | /* | 178 | /* |
179 | * inode_dio_done - signal finish of a direct I/O requests | 179 | * inode_dio_done - signal finish of a direct I/O requests |
@@ -187,7 +187,7 @@ void inode_dio_done(struct inode *inode) | |||
187 | if (atomic_dec_and_test(&inode->i_dio_count)) | 187 | if (atomic_dec_and_test(&inode->i_dio_count)) |
188 | wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); | 188 | wake_up_bit(&inode->i_state, __I_DIO_WAKEUP); |
189 | } | 189 | } |
190 | EXPORT_SYMBOL_GPL(inode_dio_done); | 190 | EXPORT_SYMBOL(inode_dio_done); |
191 | 191 | ||
192 | /* | 192 | /* |
193 | * How many pages are in the queue? | 193 | * How many pages are in the queue? |
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index aabdfc38cf24..ea54cdef04dd 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -320,6 +320,11 @@ static inline int ep_is_linked(struct list_head *p) | |||
320 | return !list_empty(p); | 320 | return !list_empty(p); |
321 | } | 321 | } |
322 | 322 | ||
323 | static inline struct eppoll_entry *ep_pwq_from_wait(wait_queue_t *p) | ||
324 | { | ||
325 | return container_of(p, struct eppoll_entry, wait); | ||
326 | } | ||
327 | |||
323 | /* Get the "struct epitem" from a wait queue pointer */ | 328 | /* Get the "struct epitem" from a wait queue pointer */ |
324 | static inline struct epitem *ep_item_from_wait(wait_queue_t *p) | 329 | static inline struct epitem *ep_item_from_wait(wait_queue_t *p) |
325 | { | 330 | { |
@@ -467,6 +472,18 @@ static void ep_poll_safewake(wait_queue_head_t *wq) | |||
467 | put_cpu(); | 472 | put_cpu(); |
468 | } | 473 | } |
469 | 474 | ||
475 | static void ep_remove_wait_queue(struct eppoll_entry *pwq) | ||
476 | { | ||
477 | wait_queue_head_t *whead; | ||
478 | |||
479 | rcu_read_lock(); | ||
480 | /* If it is cleared by POLLFREE, it should be rcu-safe */ | ||
481 | whead = rcu_dereference(pwq->whead); | ||
482 | if (whead) | ||
483 | remove_wait_queue(whead, &pwq->wait); | ||
484 | rcu_read_unlock(); | ||
485 | } | ||
486 | |||
470 | /* | 487 | /* |
471 | * This function unregisters poll callbacks from the associated file | 488 | * This function unregisters poll callbacks from the associated file |
472 | * descriptor. Must be called with "mtx" held (or "epmutex" if called from | 489 | * descriptor. Must be called with "mtx" held (or "epmutex" if called from |
@@ -481,7 +498,7 @@ static void ep_unregister_pollwait(struct eventpoll *ep, struct epitem *epi) | |||
481 | pwq = list_first_entry(lsthead, struct eppoll_entry, llink); | 498 | pwq = list_first_entry(lsthead, struct eppoll_entry, llink); |
482 | 499 | ||
483 | list_del(&pwq->llink); | 500 | list_del(&pwq->llink); |
484 | remove_wait_queue(pwq->whead, &pwq->wait); | 501 | ep_remove_wait_queue(pwq); |
485 | kmem_cache_free(pwq_cache, pwq); | 502 | kmem_cache_free(pwq_cache, pwq); |
486 | } | 503 | } |
487 | } | 504 | } |
@@ -842,6 +859,17 @@ static int ep_poll_callback(wait_queue_t *wait, unsigned mode, int sync, void *k | |||
842 | struct epitem *epi = ep_item_from_wait(wait); | 859 | struct epitem *epi = ep_item_from_wait(wait); |
843 | struct eventpoll *ep = epi->ep; | 860 | struct eventpoll *ep = epi->ep; |
844 | 861 | ||
862 | if ((unsigned long)key & POLLFREE) { | ||
863 | ep_pwq_from_wait(wait)->whead = NULL; | ||
864 | /* | ||
865 | * whead = NULL above can race with ep_remove_wait_queue() | ||
866 | * which can do another remove_wait_queue() after us, so we | ||
867 | * can't use __remove_wait_queue(). whead->lock is held by | ||
868 | * the caller. | ||
869 | */ | ||
870 | list_del_init(&wait->task_list); | ||
871 | } | ||
872 | |||
845 | spin_lock_irqsave(&ep->lock, flags); | 873 | spin_lock_irqsave(&ep->lock, flags); |
846 | 874 | ||
847 | /* | 875 | /* |
diff --git a/fs/signalfd.c b/fs/signalfd.c index 492465b451dd..7ae2a574cb25 100644 --- a/fs/signalfd.c +++ b/fs/signalfd.c | |||
@@ -30,6 +30,21 @@ | |||
30 | #include <linux/signalfd.h> | 30 | #include <linux/signalfd.h> |
31 | #include <linux/syscalls.h> | 31 | #include <linux/syscalls.h> |
32 | 32 | ||
33 | void signalfd_cleanup(struct sighand_struct *sighand) | ||
34 | { | ||
35 | wait_queue_head_t *wqh = &sighand->signalfd_wqh; | ||
36 | /* | ||
37 | * The lockless check can race with remove_wait_queue() in progress, | ||
38 | * but in this case its caller should run under rcu_read_lock() and | ||
39 | * sighand_cachep is SLAB_DESTROY_BY_RCU, we can safely return. | ||
40 | */ | ||
41 | if (likely(!waitqueue_active(wqh))) | ||
42 | return; | ||
43 | |||
44 | /* wait_queue_t->func(POLLFREE) should do remove_wait_queue() */ | ||
45 | wake_up_poll(wqh, POLLHUP | POLLFREE); | ||
46 | } | ||
47 | |||
33 | struct signalfd_ctx { | 48 | struct signalfd_ctx { |
34 | sigset_t sigmask; | 49 | sigset_t sigmask; |
35 | }; | 50 | }; |