From: Theodore Ts'o <tytso@mit.edu>
To: Ext4 Developers List <linux-ext4@vger.kernel.org>
Cc: Theodore Ts'o <tytso@mit.edu>
Subject: [PATCH] libext2fs: Make ext2fs_extent_set_bmap() more robust against ENOSPC
Date: Fri, 10 Jul 2009 00:23:50 -0400 [thread overview]
Message-ID: <1247199830-21179-1-git-send-email-tytso@mit.edu> (raw)
In the case where we ext2fs_extent_set_bmap() is replacing the block
mapping at the beginning of an already-existing extent, insert a new
extent if necessary before shrinking an existing extent, to avoid data
loss if the disk is full.
This mostly addresses the problem described in Red Hat Bugzilla's
statistics are still wrong, but at least the files on the filesystem
are not corrupted. If there is a failure during the
inode_scan_and_fix pass, the simplest thing to do may be to tell the
user to run e2fsck -fy.
Addresses-Red-Hat-Bug: #510379
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
---
lib/ext2fs/extent.c | 44 ++++++++++++++++++++++++++++++++------------
1 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/lib/ext2fs/extent.c b/lib/ext2fs/extent.c
index 4a4fd2c..2f280ea 100644
--- a/lib/ext2fs/extent.c
+++ b/lib/ext2fs/extent.c
@@ -1270,24 +1270,44 @@ again:
#ifdef DEBUG
printf("(re/un)mapping first block in extent\n");
#endif
+ if (physical) {
+ retval = ext2fs_extent_get(handle,
+ EXT2_EXTENT_PREV_LEAF,
+ &extent);
+ if (extent.e_flags & EXT2_EXTENT_FLAGS_UNINIT)
+ extent_uninit = 1;
+ if (retval == EXT2_ET_EXTENT_NO_PREV) {
+ retval = ext2fs_extent_insert(handle,
+ 0, &newextent);
+ } else if (retval)
+ goto done;
+ else if ((logical == extent.e_lblk + extent.e_len) &&
+ (physical == extent.e_pblk + extent.e_len) &&
+ (new_uninit == extent_uninit) &&
+ ((int) extent.e_len < max_len-1)) {
+ extent.e_len++;
+ retval = ext2fs_extent_replace(handle, 0,
+ &extent);
+ } else {
+ retval = ext2fs_extent_insert(handle,
+ EXT2_EXTENT_INSERT_AFTER, &newextent);
+ }
+ if (retval)
+ goto done;
+ }
+ retval = ext2fs_extent_fix_parents(handle);
+ if (retval)
+ goto done;
+ retval = ext2fs_extent_get(handle, EXT2_EXTENT_NEXT_LEAF,
+ &extent);
+ if (retval)
+ goto done;
extent.e_pblk++;
extent.e_lblk++;
extent.e_len--;
retval = ext2fs_extent_replace(handle, 0, &extent);
if (retval)
goto done;
- if (physical) {
- /*
- * We've removed the old block, now rely on
- * the optimized hueristics for adding a new
- * mapping with appropriate merging if necessary.
- */
- goto again;
- } else {
- retval = ext2fs_extent_fix_parents(handle);
- if (retval)
- goto done;
- }
} else {
__u32 orig_length;
--
1.6.3.2.1.gb9f7d.dirty
next reply other threads:[~2009-07-10 4:23 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-07-10 4:23 Theodore Ts'o [this message]
2009-07-10 4:45 ` [PATCH] libext2fs: Make ext2fs_extent_set_bmap() more robust against ENOSPC Eric Sandeen
2009-07-10 16:56 ` Eric Sandeen
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1247199830-21179-1-git-send-email-tytso@mit.edu \
--to=tytso@mit.edu \
--cc=linux-ext4@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).