aboutsummaryrefslogtreecommitdiffstats
path: root/fs/ext4
diff options
context:
space:
mode:
Diffstat (limited to 'fs/ext4')
-rw-r--r--fs/ext4/inode.c52
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 */
2155static int mpage_map_and_submit_extent(handle_t *handle, 2155static 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