diff options
author | Jiri Kosina <jkosina@suse.cz> | 2010-12-22 12:57:02 -0500 |
---|---|---|
committer | Jiri Kosina <jkosina@suse.cz> | 2010-12-22 12:57:02 -0500 |
commit | 4b7bd364700d9ac8372eff48832062b936d0793b (patch) | |
tree | 0dbf78c95456a0b02d07fcd473281f04a87e266d /fs/ext4 | |
parent | c0d8768af260e2cbb4bf659ae6094a262c86b085 (diff) | |
parent | 90a8a73c06cc32b609a880d48449d7083327e11a (diff) |
Merge branch 'master' into for-next
Conflicts:
MAINTAINERS
arch/arm/mach-omap2/pm24xx.c
drivers/scsi/bfa/bfa_fcpim.c
Needed to update to apply fixes for which the old branch was too
outdated.
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/ext4.h | 5 | ||||
-rw-r--r-- | fs/ext4/inode.c | 10 | ||||
-rw-r--r-- | fs/ext4/ioctl.c | 24 | ||||
-rw-r--r-- | fs/ext4/mballoc.c | 2 | ||||
-rw-r--r-- | fs/ext4/namei.c | 2 | ||||
-rw-r--r-- | fs/ext4/page-io.c | 99 | ||||
-rw-r--r-- | fs/ext4/super.c | 125 |
7 files changed, 163 insertions, 104 deletions
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 47162de0b957..1f253a9a141d 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h | |||
@@ -177,7 +177,7 @@ struct mpage_da_data { | |||
177 | 177 | ||
178 | struct ext4_io_page { | 178 | struct ext4_io_page { |
179 | struct page *p_page; | 179 | struct page *p_page; |
180 | int p_count; | 180 | atomic_t p_count; |
181 | }; | 181 | }; |
182 | 182 | ||
183 | #define MAX_IO_PAGES 128 | 183 | #define MAX_IO_PAGES 128 |
@@ -858,6 +858,7 @@ struct ext4_inode_info { | |||
858 | spinlock_t i_completed_io_lock; | 858 | spinlock_t i_completed_io_lock; |
859 | /* current io_end structure for async DIO write*/ | 859 | /* current io_end structure for async DIO write*/ |
860 | ext4_io_end_t *cur_aio_dio; | 860 | ext4_io_end_t *cur_aio_dio; |
861 | atomic_t i_ioend_count; /* Number of outstanding io_end structs */ | ||
861 | 862 | ||
862 | /* | 863 | /* |
863 | * Transactions that contain inode's metadata needed to complete | 864 | * Transactions that contain inode's metadata needed to complete |
@@ -909,6 +910,7 @@ struct ext4_inode_info { | |||
909 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ | 910 | #define EXT4_MOUNT_JOURNAL_CHECKSUM 0x800000 /* Journal checksums */ |
910 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ | 911 | #define EXT4_MOUNT_JOURNAL_ASYNC_COMMIT 0x1000000 /* Journal Async Commit */ |
911 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ | 912 | #define EXT4_MOUNT_I_VERSION 0x2000000 /* i_version support */ |
913 | #define EXT4_MOUNT_MBLK_IO_SUBMIT 0x4000000 /* multi-block io submits */ | ||
912 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ | 914 | #define EXT4_MOUNT_DELALLOC 0x8000000 /* Delalloc support */ |
913 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ | 915 | #define EXT4_MOUNT_DATA_ERR_ABORT 0x10000000 /* Abort on file data write */ |
914 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ | 916 | #define EXT4_MOUNT_BLOCK_VALIDITY 0x20000000 /* Block validity checking */ |
@@ -2060,6 +2062,7 @@ extern int ext4_move_extents(struct file *o_filp, struct file *d_filp, | |||
2060 | /* page-io.c */ | 2062 | /* page-io.c */ |
2061 | extern int __init ext4_init_pageio(void); | 2063 | extern int __init ext4_init_pageio(void); |
2062 | extern void ext4_exit_pageio(void); | 2064 | extern void ext4_exit_pageio(void); |
2065 | extern void ext4_ioend_wait(struct inode *); | ||
2063 | extern void ext4_free_io_end(ext4_io_end_t *io); | 2066 | extern void ext4_free_io_end(ext4_io_end_t *io); |
2064 | extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags); | 2067 | extern ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags); |
2065 | extern int ext4_end_io_nolock(ext4_io_end_t *io); | 2068 | extern int ext4_end_io_nolock(ext4_io_end_t *io); |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b6a4b41d7e14..ef9d5be0b2a8 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -53,6 +53,7 @@ | |||
53 | static inline int ext4_begin_ordered_truncate(struct inode *inode, | 53 | static inline int ext4_begin_ordered_truncate(struct inode *inode, |
54 | loff_t new_size) | 54 | loff_t new_size) |
55 | { | 55 | { |
56 | trace_ext4_begin_ordered_truncate(inode, new_size); | ||
56 | return jbd2_journal_begin_ordered_truncate( | 57 | return jbd2_journal_begin_ordered_truncate( |
57 | EXT4_SB(inode->i_sb)->s_journal, | 58 | EXT4_SB(inode->i_sb)->s_journal, |
58 | &EXT4_I(inode)->jinode, | 59 | &EXT4_I(inode)->jinode, |
@@ -178,6 +179,7 @@ void ext4_evict_inode(struct inode *inode) | |||
178 | handle_t *handle; | 179 | handle_t *handle; |
179 | int err; | 180 | int err; |
180 | 181 | ||
182 | trace_ext4_evict_inode(inode); | ||
181 | if (inode->i_nlink) { | 183 | if (inode->i_nlink) { |
182 | truncate_inode_pages(&inode->i_data, 0); | 184 | truncate_inode_pages(&inode->i_data, 0); |
183 | goto no_delete; | 185 | goto no_delete; |
@@ -2123,9 +2125,12 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, | |||
2123 | */ | 2125 | */ |
2124 | if (unlikely(journal_data && PageChecked(page))) | 2126 | if (unlikely(journal_data && PageChecked(page))) |
2125 | err = __ext4_journalled_writepage(page, len); | 2127 | err = __ext4_journalled_writepage(page, len); |
2126 | else | 2128 | else if (test_opt(inode->i_sb, MBLK_IO_SUBMIT)) |
2127 | err = ext4_bio_write_page(&io_submit, page, | 2129 | err = ext4_bio_write_page(&io_submit, page, |
2128 | len, mpd->wbc); | 2130 | len, mpd->wbc); |
2131 | else | ||
2132 | err = block_write_full_page(page, | ||
2133 | noalloc_get_block_write, mpd->wbc); | ||
2129 | 2134 | ||
2130 | if (!err) | 2135 | if (!err) |
2131 | mpd->pages_written++; | 2136 | mpd->pages_written++; |
@@ -5410,9 +5415,7 @@ int ext4_getattr(struct vfsmount *mnt, struct dentry *dentry, | |||
5410 | * will return the blocks that include the delayed allocation | 5415 | * will return the blocks that include the delayed allocation |
5411 | * blocks for this file. | 5416 | * blocks for this file. |
5412 | */ | 5417 | */ |
5413 | spin_lock(&EXT4_I(inode)->i_block_reservation_lock); | ||
5414 | delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; | 5418 | delalloc_blocks = EXT4_I(inode)->i_reserved_data_blocks; |
5415 | spin_unlock(&EXT4_I(inode)->i_block_reservation_lock); | ||
5416 | 5419 | ||
5417 | stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; | 5420 | stat->blocks += (delalloc_blocks << inode->i_sb->s_blocksize_bits)>>9; |
5418 | return 0; | 5421 | return 0; |
@@ -5649,6 +5652,7 @@ int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | |||
5649 | int err, ret; | 5652 | int err, ret; |
5650 | 5653 | ||
5651 | might_sleep(); | 5654 | might_sleep(); |
5655 | trace_ext4_mark_inode_dirty(inode, _RET_IP_); | ||
5652 | err = ext4_reserve_inode_write(handle, inode, &iloc); | 5656 | err = ext4_reserve_inode_write(handle, inode, &iloc); |
5653 | if (ext4_handle_valid(handle) && | 5657 | if (ext4_handle_valid(handle) && |
5654 | EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && | 5658 | EXT4_I(inode)->i_extra_isize < sbi->s_want_extra_isize && |
diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c index bf5ae883b1bd..eb3bc2fe647e 100644 --- a/fs/ext4/ioctl.c +++ b/fs/ext4/ioctl.c | |||
@@ -331,6 +331,30 @@ mext_out: | |||
331 | return err; | 331 | return err; |
332 | } | 332 | } |
333 | 333 | ||
334 | case FITRIM: | ||
335 | { | ||
336 | struct super_block *sb = inode->i_sb; | ||
337 | struct fstrim_range range; | ||
338 | int ret = 0; | ||
339 | |||
340 | if (!capable(CAP_SYS_ADMIN)) | ||
341 | return -EPERM; | ||
342 | |||
343 | if (copy_from_user(&range, (struct fstrim_range *)arg, | ||
344 | sizeof(range))) | ||
345 | return -EFAULT; | ||
346 | |||
347 | ret = ext4_trim_fs(sb, &range); | ||
348 | if (ret < 0) | ||
349 | return ret; | ||
350 | |||
351 | if (copy_to_user((struct fstrim_range *)arg, &range, | ||
352 | sizeof(range))) | ||
353 | return -EFAULT; | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
334 | default: | 358 | default: |
335 | return -ENOTTY; | 359 | return -ENOTTY; |
336 | } | 360 | } |
diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c index c58eba34724a..5b4d4e3a4d58 100644 --- a/fs/ext4/mballoc.c +++ b/fs/ext4/mballoc.c | |||
@@ -4640,8 +4640,6 @@ do_more: | |||
4640 | * with group lock held. generate_buddy look at | 4640 | * with group lock held. generate_buddy look at |
4641 | * them with group lock_held | 4641 | * them with group lock_held |
4642 | */ | 4642 | */ |
4643 | if (test_opt(sb, DISCARD)) | ||
4644 | ext4_issue_discard(sb, block_group, bit, count); | ||
4645 | ext4_lock_group(sb, block_group); | 4643 | ext4_lock_group(sb, block_group); |
4646 | mb_clear_bits(bitmap_bh->b_data, bit, count); | 4644 | mb_clear_bits(bitmap_bh->b_data, bit, count); |
4647 | mb_free_blocks(inode, &e4b, bit, count); | 4645 | mb_free_blocks(inode, &e4b, bit, count); |
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 92203b8a099f..dc40e75cba88 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c | |||
@@ -872,7 +872,7 @@ static struct buffer_head * ext4_find_entry (struct inode *dir, | |||
872 | if (namelen > EXT4_NAME_LEN) | 872 | if (namelen > EXT4_NAME_LEN) |
873 | return NULL; | 873 | return NULL; |
874 | if ((namelen <= 2) && (name[0] == '.') && | 874 | if ((namelen <= 2) && (name[0] == '.') && |
875 | (name[1] == '.' || name[1] == '0')) { | 875 | (name[1] == '.' || name[1] == '\0')) { |
876 | /* | 876 | /* |
877 | * "." or ".." will only be in the first block | 877 | * "." or ".." will only be in the first block |
878 | * NFS may look up ".."; "." should be handled by the VFS | 878 | * NFS may look up ".."; "." should be handled by the VFS |
diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 46a7d6a9d976..beacce11ac50 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c | |||
@@ -32,8 +32,14 @@ | |||
32 | 32 | ||
33 | static struct kmem_cache *io_page_cachep, *io_end_cachep; | 33 | static struct kmem_cache *io_page_cachep, *io_end_cachep; |
34 | 34 | ||
35 | #define WQ_HASH_SZ 37 | ||
36 | #define to_ioend_wq(v) (&ioend_wq[((unsigned long)v) % WQ_HASH_SZ]) | ||
37 | static wait_queue_head_t ioend_wq[WQ_HASH_SZ]; | ||
38 | |||
35 | int __init ext4_init_pageio(void) | 39 | int __init ext4_init_pageio(void) |
36 | { | 40 | { |
41 | int i; | ||
42 | |||
37 | io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT); | 43 | io_page_cachep = KMEM_CACHE(ext4_io_page, SLAB_RECLAIM_ACCOUNT); |
38 | if (io_page_cachep == NULL) | 44 | if (io_page_cachep == NULL) |
39 | return -ENOMEM; | 45 | return -ENOMEM; |
@@ -42,6 +48,8 @@ int __init ext4_init_pageio(void) | |||
42 | kmem_cache_destroy(io_page_cachep); | 48 | kmem_cache_destroy(io_page_cachep); |
43 | return -ENOMEM; | 49 | return -ENOMEM; |
44 | } | 50 | } |
51 | for (i = 0; i < WQ_HASH_SZ; i++) | ||
52 | init_waitqueue_head(&ioend_wq[i]); | ||
45 | 53 | ||
46 | return 0; | 54 | return 0; |
47 | } | 55 | } |
@@ -52,24 +60,37 @@ void ext4_exit_pageio(void) | |||
52 | kmem_cache_destroy(io_page_cachep); | 60 | kmem_cache_destroy(io_page_cachep); |
53 | } | 61 | } |
54 | 62 | ||
63 | void ext4_ioend_wait(struct inode *inode) | ||
64 | { | ||
65 | wait_queue_head_t *wq = to_ioend_wq(inode); | ||
66 | |||
67 | wait_event(*wq, (atomic_read(&EXT4_I(inode)->i_ioend_count) == 0)); | ||
68 | } | ||
69 | |||
70 | static void put_io_page(struct ext4_io_page *io_page) | ||
71 | { | ||
72 | if (atomic_dec_and_test(&io_page->p_count)) { | ||
73 | end_page_writeback(io_page->p_page); | ||
74 | put_page(io_page->p_page); | ||
75 | kmem_cache_free(io_page_cachep, io_page); | ||
76 | } | ||
77 | } | ||
78 | |||
55 | void ext4_free_io_end(ext4_io_end_t *io) | 79 | void ext4_free_io_end(ext4_io_end_t *io) |
56 | { | 80 | { |
57 | int i; | 81 | int i; |
82 | wait_queue_head_t *wq; | ||
58 | 83 | ||
59 | BUG_ON(!io); | 84 | BUG_ON(!io); |
60 | if (io->page) | 85 | if (io->page) |
61 | put_page(io->page); | 86 | put_page(io->page); |
62 | for (i = 0; i < io->num_io_pages; i++) { | 87 | for (i = 0; i < io->num_io_pages; i++) |
63 | if (--io->pages[i]->p_count == 0) { | 88 | put_io_page(io->pages[i]); |
64 | struct page *page = io->pages[i]->p_page; | ||
65 | |||
66 | end_page_writeback(page); | ||
67 | put_page(page); | ||
68 | kmem_cache_free(io_page_cachep, io->pages[i]); | ||
69 | } | ||
70 | } | ||
71 | io->num_io_pages = 0; | 89 | io->num_io_pages = 0; |
72 | iput(io->inode); | 90 | wq = to_ioend_wq(io->inode); |
91 | if (atomic_dec_and_test(&EXT4_I(io->inode)->i_ioend_count) && | ||
92 | waitqueue_active(wq)) | ||
93 | wake_up_all(wq); | ||
73 | kmem_cache_free(io_end_cachep, io); | 94 | kmem_cache_free(io_end_cachep, io); |
74 | } | 95 | } |
75 | 96 | ||
@@ -142,8 +163,8 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags) | |||
142 | io = kmem_cache_alloc(io_end_cachep, flags); | 163 | io = kmem_cache_alloc(io_end_cachep, flags); |
143 | if (io) { | 164 | if (io) { |
144 | memset(io, 0, sizeof(*io)); | 165 | memset(io, 0, sizeof(*io)); |
145 | io->inode = igrab(inode); | 166 | atomic_inc(&EXT4_I(inode)->i_ioend_count); |
146 | BUG_ON(!io->inode); | 167 | io->inode = inode; |
147 | INIT_WORK(&io->work, ext4_end_io_work); | 168 | INIT_WORK(&io->work, ext4_end_io_work); |
148 | INIT_LIST_HEAD(&io->list); | 169 | INIT_LIST_HEAD(&io->list); |
149 | } | 170 | } |
@@ -171,35 +192,15 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
171 | struct workqueue_struct *wq; | 192 | struct workqueue_struct *wq; |
172 | struct inode *inode; | 193 | struct inode *inode; |
173 | unsigned long flags; | 194 | unsigned long flags; |
174 | ext4_fsblk_t err_block; | ||
175 | int i; | 195 | int i; |
176 | 196 | ||
177 | BUG_ON(!io_end); | 197 | BUG_ON(!io_end); |
178 | inode = io_end->inode; | ||
179 | bio->bi_private = NULL; | 198 | bio->bi_private = NULL; |
180 | bio->bi_end_io = NULL; | 199 | bio->bi_end_io = NULL; |
181 | if (test_bit(BIO_UPTODATE, &bio->bi_flags)) | 200 | if (test_bit(BIO_UPTODATE, &bio->bi_flags)) |
182 | error = 0; | 201 | error = 0; |
183 | err_block = bio->bi_sector >> (inode->i_blkbits - 9); | ||
184 | bio_put(bio); | 202 | bio_put(bio); |
185 | 203 | ||
186 | if (!(inode->i_sb->s_flags & MS_ACTIVE)) { | ||
187 | pr_err("sb umounted, discard end_io request for inode %lu\n", | ||
188 | io_end->inode->i_ino); | ||
189 | ext4_free_io_end(io_end); | ||
190 | return; | ||
191 | } | ||
192 | |||
193 | if (error) { | ||
194 | io_end->flag |= EXT4_IO_END_ERROR; | ||
195 | ext4_warning(inode->i_sb, "I/O error writing to inode %lu " | ||
196 | "(offset %llu size %ld starting block %llu)", | ||
197 | inode->i_ino, | ||
198 | (unsigned long long) io_end->offset, | ||
199 | (long) io_end->size, | ||
200 | (unsigned long long) err_block); | ||
201 | } | ||
202 | |||
203 | for (i = 0; i < io_end->num_io_pages; i++) { | 204 | for (i = 0; i < io_end->num_io_pages; i++) { |
204 | struct page *page = io_end->pages[i]->p_page; | 205 | struct page *page = io_end->pages[i]->p_page; |
205 | struct buffer_head *bh, *head; | 206 | struct buffer_head *bh, *head; |
@@ -236,14 +237,6 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
236 | } while (bh != head); | 237 | } while (bh != head); |
237 | } | 238 | } |
238 | 239 | ||
239 | if (--io_end->pages[i]->p_count == 0) { | ||
240 | struct page *page = io_end->pages[i]->p_page; | ||
241 | |||
242 | end_page_writeback(page); | ||
243 | put_page(page); | ||
244 | kmem_cache_free(io_page_cachep, io_end->pages[i]); | ||
245 | } | ||
246 | |||
247 | /* | 240 | /* |
248 | * If this is a partial write which happened to make | 241 | * If this is a partial write which happened to make |
249 | * all buffers uptodate then we can optimize away a | 242 | * all buffers uptodate then we can optimize away a |
@@ -253,9 +246,22 @@ static void ext4_end_bio(struct bio *bio, int error) | |||
253 | */ | 246 | */ |
254 | if (!partial_write) | 247 | if (!partial_write) |
255 | SetPageUptodate(page); | 248 | SetPageUptodate(page); |
256 | } | ||
257 | 249 | ||
250 | put_io_page(io_end->pages[i]); | ||
251 | } | ||
258 | io_end->num_io_pages = 0; | 252 | io_end->num_io_pages = 0; |
253 | inode = io_end->inode; | ||
254 | |||
255 | if (error) { | ||
256 | io_end->flag |= EXT4_IO_END_ERROR; | ||
257 | ext4_warning(inode->i_sb, "I/O error writing to inode %lu " | ||
258 | "(offset %llu size %ld starting block %llu)", | ||
259 | inode->i_ino, | ||
260 | (unsigned long long) io_end->offset, | ||
261 | (long) io_end->size, | ||
262 | (unsigned long long) | ||
263 | bio->bi_sector >> (inode->i_blkbits - 9)); | ||
264 | } | ||
259 | 265 | ||
260 | /* Add the io_end to per-inode completed io list*/ | 266 | /* Add the io_end to per-inode completed io list*/ |
261 | spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags); | 267 | spin_lock_irqsave(&EXT4_I(inode)->i_completed_io_lock, flags); |
@@ -305,7 +311,6 @@ static int io_submit_init(struct ext4_io_submit *io, | |||
305 | bio->bi_private = io->io_end = io_end; | 311 | bio->bi_private = io->io_end = io_end; |
306 | bio->bi_end_io = ext4_end_bio; | 312 | bio->bi_end_io = ext4_end_bio; |
307 | 313 | ||
308 | io_end->inode = inode; | ||
309 | io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh); | 314 | io_end->offset = (page->index << PAGE_CACHE_SHIFT) + bh_offset(bh); |
310 | 315 | ||
311 | io->io_bio = bio; | 316 | io->io_bio = bio; |
@@ -360,7 +365,7 @@ submit_and_retry: | |||
360 | if ((io_end->num_io_pages == 0) || | 365 | if ((io_end->num_io_pages == 0) || |
361 | (io_end->pages[io_end->num_io_pages-1] != io_page)) { | 366 | (io_end->pages[io_end->num_io_pages-1] != io_page)) { |
362 | io_end->pages[io_end->num_io_pages++] = io_page; | 367 | io_end->pages[io_end->num_io_pages++] = io_page; |
363 | io_page->p_count++; | 368 | atomic_inc(&io_page->p_count); |
364 | } | 369 | } |
365 | return 0; | 370 | return 0; |
366 | } | 371 | } |
@@ -389,7 +394,7 @@ int ext4_bio_write_page(struct ext4_io_submit *io, | |||
389 | return -ENOMEM; | 394 | return -ENOMEM; |
390 | } | 395 | } |
391 | io_page->p_page = page; | 396 | io_page->p_page = page; |
392 | io_page->p_count = 0; | 397 | atomic_set(&io_page->p_count, 1); |
393 | get_page(page); | 398 | get_page(page); |
394 | 399 | ||
395 | for (bh = head = page_buffers(page), block_start = 0; | 400 | for (bh = head = page_buffers(page), block_start = 0; |
@@ -421,10 +426,6 @@ int ext4_bio_write_page(struct ext4_io_submit *io, | |||
421 | * PageWriteback bit from the page to prevent the system from | 426 | * PageWriteback bit from the page to prevent the system from |
422 | * wedging later on. | 427 | * wedging later on. |
423 | */ | 428 | */ |
424 | if (io_page->p_count == 0) { | 429 | put_io_page(io_page); |
425 | put_page(page); | ||
426 | end_page_writeback(page); | ||
427 | kmem_cache_free(io_page_cachep, io_page); | ||
428 | } | ||
429 | return ret; | 430 | return ret; |
430 | } | 431 | } |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index 40131b777af6..fb15c9c0be74 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -828,12 +828,22 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
828 | ei->cur_aio_dio = NULL; | 828 | ei->cur_aio_dio = NULL; |
829 | ei->i_sync_tid = 0; | 829 | ei->i_sync_tid = 0; |
830 | ei->i_datasync_tid = 0; | 830 | ei->i_datasync_tid = 0; |
831 | atomic_set(&ei->i_ioend_count, 0); | ||
831 | 832 | ||
832 | return &ei->vfs_inode; | 833 | return &ei->vfs_inode; |
833 | } | 834 | } |
834 | 835 | ||
836 | static int ext4_drop_inode(struct inode *inode) | ||
837 | { | ||
838 | int drop = generic_drop_inode(inode); | ||
839 | |||
840 | trace_ext4_drop_inode(inode, drop); | ||
841 | return drop; | ||
842 | } | ||
843 | |||
835 | static void ext4_destroy_inode(struct inode *inode) | 844 | static void ext4_destroy_inode(struct inode *inode) |
836 | { | 845 | { |
846 | ext4_ioend_wait(inode); | ||
837 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { | 847 | if (!list_empty(&(EXT4_I(inode)->i_orphan))) { |
838 | ext4_msg(inode->i_sb, KERN_ERR, | 848 | ext4_msg(inode->i_sb, KERN_ERR, |
839 | "Inode %lu (%p): orphan list check failed!", | 849 | "Inode %lu (%p): orphan list check failed!", |
@@ -1016,6 +1026,8 @@ static int ext4_show_options(struct seq_file *seq, struct vfsmount *vfs) | |||
1016 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) | 1026 | !(def_mount_opts & EXT4_DEFM_NODELALLOC)) |
1017 | seq_puts(seq, ",nodelalloc"); | 1027 | seq_puts(seq, ",nodelalloc"); |
1018 | 1028 | ||
1029 | if (test_opt(sb, MBLK_IO_SUBMIT)) | ||
1030 | seq_puts(seq, ",mblk_io_submit"); | ||
1019 | if (sbi->s_stripe) | 1031 | if (sbi->s_stripe) |
1020 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); | 1032 | seq_printf(seq, ",stripe=%lu", sbi->s_stripe); |
1021 | /* | 1033 | /* |
@@ -1173,6 +1185,7 @@ static const struct super_operations ext4_sops = { | |||
1173 | .destroy_inode = ext4_destroy_inode, | 1185 | .destroy_inode = ext4_destroy_inode, |
1174 | .write_inode = ext4_write_inode, | 1186 | .write_inode = ext4_write_inode, |
1175 | .dirty_inode = ext4_dirty_inode, | 1187 | .dirty_inode = ext4_dirty_inode, |
1188 | .drop_inode = ext4_drop_inode, | ||
1176 | .evict_inode = ext4_evict_inode, | 1189 | .evict_inode = ext4_evict_inode, |
1177 | .put_super = ext4_put_super, | 1190 | .put_super = ext4_put_super, |
1178 | .sync_fs = ext4_sync_fs, | 1191 | .sync_fs = ext4_sync_fs, |
@@ -1186,7 +1199,6 @@ static const struct super_operations ext4_sops = { | |||
1186 | .quota_write = ext4_quota_write, | 1199 | .quota_write = ext4_quota_write, |
1187 | #endif | 1200 | #endif |
1188 | .bdev_try_to_free_page = bdev_try_to_free_page, | 1201 | .bdev_try_to_free_page = bdev_try_to_free_page, |
1189 | .trim_fs = ext4_trim_fs | ||
1190 | }; | 1202 | }; |
1191 | 1203 | ||
1192 | static const struct super_operations ext4_nojournal_sops = { | 1204 | static const struct super_operations ext4_nojournal_sops = { |
@@ -1194,6 +1206,7 @@ static const struct super_operations ext4_nojournal_sops = { | |||
1194 | .destroy_inode = ext4_destroy_inode, | 1206 | .destroy_inode = ext4_destroy_inode, |
1195 | .write_inode = ext4_write_inode, | 1207 | .write_inode = ext4_write_inode, |
1196 | .dirty_inode = ext4_dirty_inode, | 1208 | .dirty_inode = ext4_dirty_inode, |
1209 | .drop_inode = ext4_drop_inode, | ||
1197 | .evict_inode = ext4_evict_inode, | 1210 | .evict_inode = ext4_evict_inode, |
1198 | .write_super = ext4_write_super, | 1211 | .write_super = ext4_write_super, |
1199 | .put_super = ext4_put_super, | 1212 | .put_super = ext4_put_super, |
@@ -1228,8 +1241,8 @@ enum { | |||
1228 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, | 1241 | Opt_jqfmt_vfsold, Opt_jqfmt_vfsv0, Opt_jqfmt_vfsv1, Opt_quota, |
1229 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, | 1242 | Opt_noquota, Opt_ignore, Opt_barrier, Opt_nobarrier, Opt_err, |
1230 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, | 1243 | Opt_resize, Opt_usrquota, Opt_grpquota, Opt_i_version, |
1231 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, | 1244 | Opt_stripe, Opt_delalloc, Opt_nodelalloc, Opt_mblk_io_submit, |
1232 | Opt_block_validity, Opt_noblock_validity, | 1245 | Opt_nomblk_io_submit, Opt_block_validity, Opt_noblock_validity, |
1233 | Opt_inode_readahead_blks, Opt_journal_ioprio, | 1246 | Opt_inode_readahead_blks, Opt_journal_ioprio, |
1234 | Opt_dioread_nolock, Opt_dioread_lock, | 1247 | Opt_dioread_nolock, Opt_dioread_lock, |
1235 | Opt_discard, Opt_nodiscard, | 1248 | Opt_discard, Opt_nodiscard, |
@@ -1293,6 +1306,8 @@ static const match_table_t tokens = { | |||
1293 | {Opt_resize, "resize"}, | 1306 | {Opt_resize, "resize"}, |
1294 | {Opt_delalloc, "delalloc"}, | 1307 | {Opt_delalloc, "delalloc"}, |
1295 | {Opt_nodelalloc, "nodelalloc"}, | 1308 | {Opt_nodelalloc, "nodelalloc"}, |
1309 | {Opt_mblk_io_submit, "mblk_io_submit"}, | ||
1310 | {Opt_nomblk_io_submit, "nomblk_io_submit"}, | ||
1296 | {Opt_block_validity, "block_validity"}, | 1311 | {Opt_block_validity, "block_validity"}, |
1297 | {Opt_noblock_validity, "noblock_validity"}, | 1312 | {Opt_noblock_validity, "noblock_validity"}, |
1298 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, | 1313 | {Opt_inode_readahead_blks, "inode_readahead_blks=%u"}, |
@@ -1714,6 +1729,12 @@ set_qf_format: | |||
1714 | case Opt_nodelalloc: | 1729 | case Opt_nodelalloc: |
1715 | clear_opt(sbi->s_mount_opt, DELALLOC); | 1730 | clear_opt(sbi->s_mount_opt, DELALLOC); |
1716 | break; | 1731 | break; |
1732 | case Opt_mblk_io_submit: | ||
1733 | set_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); | ||
1734 | break; | ||
1735 | case Opt_nomblk_io_submit: | ||
1736 | clear_opt(sbi->s_mount_opt, MBLK_IO_SUBMIT); | ||
1737 | break; | ||
1717 | case Opt_stripe: | 1738 | case Opt_stripe: |
1718 | if (match_int(&args[0], &option)) | 1739 | if (match_int(&args[0], &option)) |
1719 | return 0; | 1740 | return 0; |
@@ -2699,7 +2720,6 @@ static int ext4_lazyinit_thread(void *arg) | |||
2699 | struct ext4_li_request *elr; | 2720 | struct ext4_li_request *elr; |
2700 | unsigned long next_wakeup; | 2721 | unsigned long next_wakeup; |
2701 | DEFINE_WAIT(wait); | 2722 | DEFINE_WAIT(wait); |
2702 | int ret; | ||
2703 | 2723 | ||
2704 | BUG_ON(NULL == eli); | 2724 | BUG_ON(NULL == eli); |
2705 | 2725 | ||
@@ -2723,13 +2743,12 @@ cont_thread: | |||
2723 | elr = list_entry(pos, struct ext4_li_request, | 2743 | elr = list_entry(pos, struct ext4_li_request, |
2724 | lr_request); | 2744 | lr_request); |
2725 | 2745 | ||
2726 | if (time_after_eq(jiffies, elr->lr_next_sched)) | 2746 | if (time_after_eq(jiffies, elr->lr_next_sched)) { |
2727 | ret = ext4_run_li_request(elr); | 2747 | if (ext4_run_li_request(elr) != 0) { |
2728 | 2748 | /* error, remove the lazy_init job */ | |
2729 | if (ret) { | 2749 | ext4_remove_li_request(elr); |
2730 | ret = 0; | 2750 | continue; |
2731 | ext4_remove_li_request(elr); | 2751 | } |
2732 | continue; | ||
2733 | } | 2752 | } |
2734 | 2753 | ||
2735 | if (time_before(elr->lr_next_sched, next_wakeup)) | 2754 | if (time_before(elr->lr_next_sched, next_wakeup)) |
@@ -2740,7 +2759,8 @@ cont_thread: | |||
2740 | if (freezing(current)) | 2759 | if (freezing(current)) |
2741 | refrigerator(); | 2760 | refrigerator(); |
2742 | 2761 | ||
2743 | if (time_after_eq(jiffies, next_wakeup)) { | 2762 | if ((time_after_eq(jiffies, next_wakeup)) || |
2763 | (MAX_JIFFY_OFFSET == next_wakeup)) { | ||
2744 | cond_resched(); | 2764 | cond_resched(); |
2745 | continue; | 2765 | continue; |
2746 | } | 2766 | } |
@@ -2788,9 +2808,6 @@ static void ext4_clear_request_list(void) | |||
2788 | struct ext4_li_request *elr; | 2808 | struct ext4_li_request *elr; |
2789 | 2809 | ||
2790 | mutex_lock(&ext4_li_info->li_list_mtx); | 2810 | mutex_lock(&ext4_li_info->li_list_mtx); |
2791 | if (list_empty(&ext4_li_info->li_request_list)) | ||
2792 | return; | ||
2793 | |||
2794 | list_for_each_safe(pos, n, &ext4_li_info->li_request_list) { | 2811 | list_for_each_safe(pos, n, &ext4_li_info->li_request_list) { |
2795 | elr = list_entry(pos, struct ext4_li_request, | 2812 | elr = list_entry(pos, struct ext4_li_request, |
2796 | lr_request); | 2813 | lr_request); |
@@ -3257,13 +3274,14 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3257 | * Test whether we have more sectors than will fit in sector_t, | 3274 | * Test whether we have more sectors than will fit in sector_t, |
3258 | * and whether the max offset is addressable by the page cache. | 3275 | * and whether the max offset is addressable by the page cache. |
3259 | */ | 3276 | */ |
3260 | ret = generic_check_addressable(sb->s_blocksize_bits, | 3277 | err = generic_check_addressable(sb->s_blocksize_bits, |
3261 | ext4_blocks_count(es)); | 3278 | ext4_blocks_count(es)); |
3262 | if (ret) { | 3279 | if (err) { |
3263 | ext4_msg(sb, KERN_ERR, "filesystem" | 3280 | ext4_msg(sb, KERN_ERR, "filesystem" |
3264 | " too large to mount safely on this system"); | 3281 | " too large to mount safely on this system"); |
3265 | if (sizeof(sector_t) < 8) | 3282 | if (sizeof(sector_t) < 8) |
3266 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); | 3283 | ext4_msg(sb, KERN_WARNING, "CONFIG_LBDAF not enabled"); |
3284 | ret = err; | ||
3267 | goto failed_mount; | 3285 | goto failed_mount; |
3268 | } | 3286 | } |
3269 | 3287 | ||
@@ -3348,6 +3366,24 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3348 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); | 3366 | get_random_bytes(&sbi->s_next_generation, sizeof(u32)); |
3349 | spin_lock_init(&sbi->s_next_gen_lock); | 3367 | spin_lock_init(&sbi->s_next_gen_lock); |
3350 | 3368 | ||
3369 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | ||
3370 | ext4_count_free_blocks(sb)); | ||
3371 | if (!err) { | ||
3372 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | ||
3373 | ext4_count_free_inodes(sb)); | ||
3374 | } | ||
3375 | if (!err) { | ||
3376 | err = percpu_counter_init(&sbi->s_dirs_counter, | ||
3377 | ext4_count_dirs(sb)); | ||
3378 | } | ||
3379 | if (!err) { | ||
3380 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | ||
3381 | } | ||
3382 | if (err) { | ||
3383 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | ||
3384 | goto failed_mount3; | ||
3385 | } | ||
3386 | |||
3351 | sbi->s_stripe = ext4_get_stripe_size(sbi); | 3387 | sbi->s_stripe = ext4_get_stripe_size(sbi); |
3352 | sbi->s_max_writeback_mb_bump = 128; | 3388 | sbi->s_max_writeback_mb_bump = 128; |
3353 | 3389 | ||
@@ -3446,22 +3482,19 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent) | |||
3446 | } | 3482 | } |
3447 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); | 3483 | set_task_ioprio(sbi->s_journal->j_task, journal_ioprio); |
3448 | 3484 | ||
3449 | no_journal: | 3485 | /* |
3450 | err = percpu_counter_init(&sbi->s_freeblocks_counter, | 3486 | * The journal may have updated the bg summary counts, so we |
3451 | ext4_count_free_blocks(sb)); | 3487 | * need to update the global counters. |
3452 | if (!err) | 3488 | */ |
3453 | err = percpu_counter_init(&sbi->s_freeinodes_counter, | 3489 | percpu_counter_set(&sbi->s_freeblocks_counter, |
3454 | ext4_count_free_inodes(sb)); | 3490 | ext4_count_free_blocks(sb)); |
3455 | if (!err) | 3491 | percpu_counter_set(&sbi->s_freeinodes_counter, |
3456 | err = percpu_counter_init(&sbi->s_dirs_counter, | 3492 | ext4_count_free_inodes(sb)); |
3457 | ext4_count_dirs(sb)); | 3493 | percpu_counter_set(&sbi->s_dirs_counter, |
3458 | if (!err) | 3494 | ext4_count_dirs(sb)); |
3459 | err = percpu_counter_init(&sbi->s_dirtyblocks_counter, 0); | 3495 | percpu_counter_set(&sbi->s_dirtyblocks_counter, 0); |
3460 | if (err) { | ||
3461 | ext4_msg(sb, KERN_ERR, "insufficient memory"); | ||
3462 | goto failed_mount_wq; | ||
3463 | } | ||
3464 | 3496 | ||
3497 | no_journal: | ||
3465 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); | 3498 | EXT4_SB(sb)->dio_unwritten_wq = create_workqueue("ext4-dio-unwritten"); |
3466 | if (!EXT4_SB(sb)->dio_unwritten_wq) { | 3499 | if (!EXT4_SB(sb)->dio_unwritten_wq) { |
3467 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); | 3500 | printk(KERN_ERR "EXT4-fs: failed to create DIO workqueue\n"); |
@@ -3611,10 +3644,6 @@ failed_mount_wq: | |||
3611 | jbd2_journal_destroy(sbi->s_journal); | 3644 | jbd2_journal_destroy(sbi->s_journal); |
3612 | sbi->s_journal = NULL; | 3645 | sbi->s_journal = NULL; |
3613 | } | 3646 | } |
3614 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | ||
3615 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
3616 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
3617 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
3618 | failed_mount3: | 3647 | failed_mount3: |
3619 | if (sbi->s_flex_groups) { | 3648 | if (sbi->s_flex_groups) { |
3620 | if (is_vmalloc_addr(sbi->s_flex_groups)) | 3649 | if (is_vmalloc_addr(sbi->s_flex_groups)) |
@@ -3622,6 +3651,10 @@ failed_mount3: | |||
3622 | else | 3651 | else |
3623 | kfree(sbi->s_flex_groups); | 3652 | kfree(sbi->s_flex_groups); |
3624 | } | 3653 | } |
3654 | percpu_counter_destroy(&sbi->s_freeblocks_counter); | ||
3655 | percpu_counter_destroy(&sbi->s_freeinodes_counter); | ||
3656 | percpu_counter_destroy(&sbi->s_dirs_counter); | ||
3657 | percpu_counter_destroy(&sbi->s_dirtyblocks_counter); | ||
3625 | failed_mount2: | 3658 | failed_mount2: |
3626 | for (i = 0; i < db_count; i++) | 3659 | for (i = 0; i < db_count; i++) |
3627 | brelse(sbi->s_group_desc[i]); | 3660 | brelse(sbi->s_group_desc[i]); |
@@ -3949,13 +3982,11 @@ static int ext4_commit_super(struct super_block *sb, int sync) | |||
3949 | else | 3982 | else |
3950 | es->s_kbytes_written = | 3983 | es->s_kbytes_written = |
3951 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); | 3984 | cpu_to_le64(EXT4_SB(sb)->s_kbytes_written); |
3952 | if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeblocks_counter)) | 3985 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( |
3953 | ext4_free_blocks_count_set(es, percpu_counter_sum_positive( | 3986 | &EXT4_SB(sb)->s_freeblocks_counter)); |
3954 | &EXT4_SB(sb)->s_freeblocks_counter)); | 3987 | es->s_free_inodes_count = |
3955 | if (percpu_counter_initialized(&EXT4_SB(sb)->s_freeinodes_counter)) | 3988 | cpu_to_le32(percpu_counter_sum_positive( |
3956 | es->s_free_inodes_count = | 3989 | &EXT4_SB(sb)->s_freeinodes_counter)); |
3957 | cpu_to_le32(percpu_counter_sum_positive( | ||
3958 | &EXT4_SB(sb)->s_freeinodes_counter)); | ||
3959 | sb->s_dirt = 0; | 3990 | sb->s_dirt = 0; |
3960 | BUFFER_TRACE(sbh, "marking dirty"); | 3991 | BUFFER_TRACE(sbh, "marking dirty"); |
3961 | mark_buffer_dirty(sbh); | 3992 | mark_buffer_dirty(sbh); |
@@ -4556,12 +4587,10 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, | |||
4556 | 4587 | ||
4557 | static int ext4_quota_off(struct super_block *sb, int type) | 4588 | static int ext4_quota_off(struct super_block *sb, int type) |
4558 | { | 4589 | { |
4559 | /* Force all delayed allocation blocks to be allocated */ | 4590 | /* Force all delayed allocation blocks to be allocated. |
4560 | if (test_opt(sb, DELALLOC)) { | 4591 | * Caller already holds s_umount sem */ |
4561 | down_read(&sb->s_umount); | 4592 | if (test_opt(sb, DELALLOC)) |
4562 | sync_filesystem(sb); | 4593 | sync_filesystem(sb); |
4563 | up_read(&sb->s_umount); | ||
4564 | } | ||
4565 | 4594 | ||
4566 | return dquot_quota_off(sb, type); | 4595 | return dquot_quota_off(sb, type); |
4567 | } | 4596 | } |