diff options
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/inode.c | 52 |
1 files changed, 28 insertions, 24 deletions
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 502a9e1f5aa3..0188e65e1f58 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -2153,7 +2153,8 @@ static int mpage_map_one_extent(handle_t *handle, struct mpage_da_data *mpd) | |||
2153 | * guaranteed). After mapping we submit all mapped pages for IO. | 2153 | * guaranteed). After mapping we submit all mapped pages for IO. |
2154 | */ | 2154 | */ |
2155 | static int mpage_map_and_submit_extent(handle_t *handle, | 2155 | static int mpage_map_and_submit_extent(handle_t *handle, |
2156 | struct mpage_da_data *mpd) | 2156 | struct mpage_da_data *mpd, |
2157 | bool *give_up_on_write) | ||
2157 | { | 2158 | { |
2158 | struct inode *inode = mpd->inode; | 2159 | struct inode *inode = mpd->inode; |
2159 | struct ext4_map_blocks *map = &mpd->map; | 2160 | struct ext4_map_blocks *map = &mpd->map; |
@@ -2167,29 +2168,30 @@ static int mpage_map_and_submit_extent(handle_t *handle, | |||
2167 | if (err < 0) { | 2168 | if (err < 0) { |
2168 | struct super_block *sb = inode->i_sb; | 2169 | struct super_block *sb = inode->i_sb; |
2169 | 2170 | ||
2171 | if (EXT4_SB(sb)->s_mount_flags & EXT4_MF_FS_ABORTED) | ||
2172 | goto invalidate_dirty_pages; | ||
2170 | /* | 2173 | /* |
2171 | * Need to commit transaction to free blocks. Let upper | 2174 | * Let the uper layers retry transient errors. |
2172 | * layers sort it out. | 2175 | * In the case of ENOSPC, if ext4_count_free_blocks() |
2176 | * is non-zero, a commit should free up blocks. | ||
2173 | */ | 2177 | */ |
2174 | if (err == -ENOSPC && ext4_count_free_clusters(sb)) | 2178 | if ((err == -ENOMEM) || |
2175 | return -ENOSPC; | 2179 | (err == -ENOSPC && ext4_count_free_clusters(sb))) |
2176 | 2180 | return err; | |
2177 | if (!(EXT4_SB(sb)->s_mount_flags & EXT4_MF_FS_ABORTED)) { | 2181 | ext4_msg(sb, KERN_CRIT, |
2178 | ext4_msg(sb, KERN_CRIT, | 2182 | "Delayed block allocation failed for " |
2179 | "Delayed block allocation failed for " | 2183 | "inode %lu at logical offset %llu with" |
2180 | "inode %lu at logical offset %llu with" | 2184 | " max blocks %u with error %d", |
2181 | " max blocks %u with error %d", | 2185 | inode->i_ino, |
2182 | inode->i_ino, | 2186 | (unsigned long long)map->m_lblk, |
2183 | (unsigned long long)map->m_lblk, | 2187 | (unsigned)map->m_len, -err); |
2184 | (unsigned)map->m_len, err); | 2188 | ext4_msg(sb, KERN_CRIT, |
2185 | ext4_msg(sb, KERN_CRIT, | 2189 | "This should not happen!! Data will " |
2186 | "This should not happen!! Data will " | 2190 | "be lost\n"); |
2187 | "be lost\n"); | 2191 | if (err == -ENOSPC) |
2188 | if (err == -ENOSPC) | 2192 | ext4_print_free_blocks(inode); |
2189 | ext4_print_free_blocks(inode); | 2193 | invalidate_dirty_pages: |
2190 | } | 2194 | *give_up_on_write = true; |
2191 | /* invalidate all the pages */ | ||
2192 | mpage_release_unused_pages(mpd, true); | ||
2193 | return err; | 2195 | return err; |
2194 | } | 2196 | } |
2195 | /* | 2197 | /* |
@@ -2377,6 +2379,7 @@ static int ext4_writepages(struct address_space *mapping, | |||
2377 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); | 2379 | struct ext4_sb_info *sbi = EXT4_SB(mapping->host->i_sb); |
2378 | bool done; | 2380 | bool done; |
2379 | struct blk_plug plug; | 2381 | struct blk_plug plug; |
2382 | bool give_up_on_write = false; | ||
2380 | 2383 | ||
2381 | trace_ext4_writepages(inode, wbc); | 2384 | trace_ext4_writepages(inode, wbc); |
2382 | 2385 | ||
@@ -2494,7 +2497,8 @@ retry: | |||
2494 | ret = mpage_prepare_extent_to_map(&mpd); | 2497 | ret = mpage_prepare_extent_to_map(&mpd); |
2495 | if (!ret) { | 2498 | if (!ret) { |
2496 | if (mpd.map.m_len) | 2499 | if (mpd.map.m_len) |
2497 | ret = mpage_map_and_submit_extent(handle, &mpd); | 2500 | ret = mpage_map_and_submit_extent(handle, &mpd, |
2501 | &give_up_on_write); | ||
2498 | else { | 2502 | else { |
2499 | /* | 2503 | /* |
2500 | * We scanned the whole range (or exhausted | 2504 | * We scanned the whole range (or exhausted |
@@ -2509,7 +2513,7 @@ retry: | |||
2509 | /* Submit prepared bio */ | 2513 | /* Submit prepared bio */ |
2510 | ext4_io_submit(&mpd.io_submit); | 2514 | ext4_io_submit(&mpd.io_submit); |
2511 | /* Unlock pages we didn't use */ | 2515 | /* Unlock pages we didn't use */ |
2512 | mpage_release_unused_pages(&mpd, false); | 2516 | mpage_release_unused_pages(&mpd, give_up_on_write); |
2513 | /* Drop our io_end reference we got from init */ | 2517 | /* Drop our io_end reference we got from init */ |
2514 | ext4_put_io_end(mpd.io_submit.io_end); | 2518 | ext4_put_io_end(mpd.io_submit.io_end); |
2515 | 2519 | ||