diff options
Diffstat (limited to 'fs/ext4/inode.c')
-rw-r--r-- | fs/ext4/inode.c | 85 |
1 files changed, 38 insertions, 47 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 0723774bdfb5..d6382b89ecbd 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1488,10 +1488,7 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, | |||
1488 | struct ext4_io_submit io_submit; | 1488 | struct ext4_io_submit io_submit; |
1489 | 1489 | ||
1490 | BUG_ON(mpd->next_page <= mpd->first_page); | 1490 | BUG_ON(mpd->next_page <= mpd->first_page); |
1491 | ext4_io_submit_init(&io_submit, mpd->wbc); | 1491 | memset(&io_submit, 0, sizeof(io_submit)); |
1492 | io_submit.io_end = ext4_init_io_end(inode, GFP_NOFS); | ||
1493 | if (!io_submit.io_end) | ||
1494 | return -ENOMEM; | ||
1495 | /* | 1492 | /* |
1496 | * We need to start from the first_page to the next_page - 1 | 1493 | * We need to start from the first_page to the next_page - 1 |
1497 | * to make sure we also write the mapped dirty buffer_heads. | 1494 | * to make sure we also write the mapped dirty buffer_heads. |
@@ -1579,8 +1576,6 @@ static int mpage_da_submit_io(struct mpage_da_data *mpd, | |||
1579 | pagevec_release(&pvec); | 1576 | pagevec_release(&pvec); |
1580 | } | 1577 | } |
1581 | ext4_io_submit(&io_submit); | 1578 | ext4_io_submit(&io_submit); |
1582 | /* Drop io_end reference we got from init */ | ||
1583 | ext4_put_io_end_defer(io_submit.io_end); | ||
1584 | return ret; | 1579 | return ret; |
1585 | } | 1580 | } |
1586 | 1581 | ||
@@ -2239,16 +2234,9 @@ static int ext4_writepage(struct page *page, | |||
2239 | */ | 2234 | */ |
2240 | return __ext4_journalled_writepage(page, len); | 2235 | return __ext4_journalled_writepage(page, len); |
2241 | 2236 | ||
2242 | ext4_io_submit_init(&io_submit, wbc); | 2237 | memset(&io_submit, 0, sizeof(io_submit)); |
2243 | io_submit.io_end = ext4_init_io_end(inode, GFP_NOFS); | ||
2244 | if (!io_submit.io_end) { | ||
2245 | redirty_page_for_writepage(wbc, page); | ||
2246 | return -ENOMEM; | ||
2247 | } | ||
2248 | ret = ext4_bio_write_page(&io_submit, page, len, wbc); | 2238 | ret = ext4_bio_write_page(&io_submit, page, len, wbc); |
2249 | ext4_io_submit(&io_submit); | 2239 | ext4_io_submit(&io_submit); |
2250 | /* Drop io_end reference we got from init */ | ||
2251 | ext4_put_io_end_defer(io_submit.io_end); | ||
2252 | return ret; | 2240 | return ret; |
2253 | } | 2241 | } |
2254 | 2242 | ||
@@ -3079,13 +3067,9 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, | |||
3079 | struct inode *inode = file_inode(iocb->ki_filp); | 3067 | struct inode *inode = file_inode(iocb->ki_filp); |
3080 | ext4_io_end_t *io_end = iocb->private; | 3068 | ext4_io_end_t *io_end = iocb->private; |
3081 | 3069 | ||
3082 | /* if not async direct IO just return */ | 3070 | /* if not async direct IO or dio with 0 bytes write, just return */ |
3083 | if (!io_end) { | 3071 | if (!io_end || !size) |
3084 | inode_dio_done(inode); | 3072 | goto out; |
3085 | if (is_async) | ||
3086 | aio_complete(iocb, ret, 0); | ||
3087 | return; | ||
3088 | } | ||
3089 | 3073 | ||
3090 | ext_debug("ext4_end_io_dio(): io_end 0x%p " | 3074 | ext_debug("ext4_end_io_dio(): io_end 0x%p " |
3091 | "for inode %lu, iocb 0x%p, offset %llu, size %zd\n", | 3075 | "for inode %lu, iocb 0x%p, offset %llu, size %zd\n", |
@@ -3093,13 +3077,25 @@ static void ext4_end_io_dio(struct kiocb *iocb, loff_t offset, | |||
3093 | size); | 3077 | size); |
3094 | 3078 | ||
3095 | iocb->private = NULL; | 3079 | iocb->private = NULL; |
3080 | |||
3081 | /* if not aio dio with unwritten extents, just free io and return */ | ||
3082 | if (!(io_end->flag & EXT4_IO_END_UNWRITTEN)) { | ||
3083 | ext4_free_io_end(io_end); | ||
3084 | out: | ||
3085 | inode_dio_done(inode); | ||
3086 | if (is_async) | ||
3087 | aio_complete(iocb, ret, 0); | ||
3088 | return; | ||
3089 | } | ||
3090 | |||
3096 | io_end->offset = offset; | 3091 | io_end->offset = offset; |
3097 | io_end->size = size; | 3092 | io_end->size = size; |
3098 | if (is_async) { | 3093 | if (is_async) { |
3099 | io_end->iocb = iocb; | 3094 | io_end->iocb = iocb; |
3100 | io_end->result = ret; | 3095 | io_end->result = ret; |
3101 | } | 3096 | } |
3102 | ext4_put_io_end_defer(io_end); | 3097 | |
3098 | ext4_add_complete_io(io_end); | ||
3103 | } | 3099 | } |
3104 | 3100 | ||
3105 | /* | 3101 | /* |
@@ -3133,7 +3129,6 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, | |||
3133 | get_block_t *get_block_func = NULL; | 3129 | get_block_t *get_block_func = NULL; |
3134 | int dio_flags = 0; | 3130 | int dio_flags = 0; |
3135 | loff_t final_size = offset + count; | 3131 | loff_t final_size = offset + count; |
3136 | ext4_io_end_t *io_end = NULL; | ||
3137 | 3132 | ||
3138 | /* Use the old path for reads and writes beyond i_size. */ | 3133 | /* Use the old path for reads and writes beyond i_size. */ |
3139 | if (rw != WRITE || final_size > inode->i_size) | 3134 | if (rw != WRITE || final_size > inode->i_size) |
@@ -3172,16 +3167,13 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, | |||
3172 | iocb->private = NULL; | 3167 | iocb->private = NULL; |
3173 | ext4_inode_aio_set(inode, NULL); | 3168 | ext4_inode_aio_set(inode, NULL); |
3174 | if (!is_sync_kiocb(iocb)) { | 3169 | if (!is_sync_kiocb(iocb)) { |
3175 | io_end = ext4_init_io_end(inode, GFP_NOFS); | 3170 | ext4_io_end_t *io_end = ext4_init_io_end(inode, GFP_NOFS); |
3176 | if (!io_end) { | 3171 | if (!io_end) { |
3177 | ret = -ENOMEM; | 3172 | ret = -ENOMEM; |
3178 | goto retake_lock; | 3173 | goto retake_lock; |
3179 | } | 3174 | } |
3180 | io_end->flag |= EXT4_IO_END_DIRECT; | 3175 | io_end->flag |= EXT4_IO_END_DIRECT; |
3181 | /* | 3176 | iocb->private = io_end; |
3182 | * Grab reference for DIO. Will be dropped in ext4_end_io_dio() | ||
3183 | */ | ||
3184 | iocb->private = ext4_get_io_end(io_end); | ||
3185 | /* | 3177 | /* |
3186 | * we save the io structure for current async direct | 3178 | * we save the io structure for current async direct |
3187 | * IO, so that later ext4_map_blocks() could flag the | 3179 | * IO, so that later ext4_map_blocks() could flag the |
@@ -3205,27 +3197,26 @@ static ssize_t ext4_ext_direct_IO(int rw, struct kiocb *iocb, | |||
3205 | NULL, | 3197 | NULL, |
3206 | dio_flags); | 3198 | dio_flags); |
3207 | 3199 | ||
3200 | if (iocb->private) | ||
3201 | ext4_inode_aio_set(inode, NULL); | ||
3208 | /* | 3202 | /* |
3209 | * Put our reference to io_end. This can free the io_end structure e.g. | 3203 | * The io_end structure takes a reference to the inode, that |
3210 | * in sync IO case or in case of error. It can even perform extent | 3204 | * structure needs to be destroyed and the reference to the |
3211 | * conversion if all bios we submitted finished before we got here. | 3205 | * inode need to be dropped, when IO is complete, even with 0 |
3212 | * Note that in that case iocb->private can be already set to NULL | 3206 | * byte write, or failed. |
3213 | * here. | 3207 | * |
3208 | * In the successful AIO DIO case, the io_end structure will | ||
3209 | * be destroyed and the reference to the inode will be dropped | ||
3210 | * after the end_io call back function is called. | ||
3211 | * | ||
3212 | * In the case there is 0 byte write, or error case, since VFS | ||
3213 | * direct IO won't invoke the end_io call back function, we | ||
3214 | * need to free the end_io structure here. | ||
3214 | */ | 3215 | */ |
3215 | if (io_end) { | 3216 | if (ret != -EIOCBQUEUED && ret <= 0 && iocb->private) { |
3216 | ext4_inode_aio_set(inode, NULL); | 3217 | ext4_free_io_end(iocb->private); |
3217 | ext4_put_io_end(io_end); | 3218 | iocb->private = NULL; |
3218 | /* | 3219 | } else if (ret > 0 && !overwrite && ext4_test_inode_state(inode, |
3219 | * In case of error or no write ext4_end_io_dio() was not | ||
3220 | * called so we have to put iocb's reference. | ||
3221 | */ | ||
3222 | if (ret <= 0 && ret != -EIOCBQUEUED) { | ||
3223 | WARN_ON(iocb->private != io_end); | ||
3224 | ext4_put_io_end(io_end); | ||
3225 | iocb->private = NULL; | ||
3226 | } | ||
3227 | } | ||
3228 | if (ret > 0 && !overwrite && ext4_test_inode_state(inode, | ||
3229 | EXT4_STATE_DIO_UNWRITTEN)) { | 3220 | EXT4_STATE_DIO_UNWRITTEN)) { |
3230 | int err; | 3221 | int err; |
3231 | /* | 3222 | /* |