Commit 1938a150 authored by Aneesh Kumar K.V's avatar Aneesh Kumar K.V Committed by Theodore Ts'o
Browse files

ext4: Avoid leaking blocks after a block allocation failure

We should add inode to the orphan list in the same transaction
as block allocation.  This ensures that if we crash after a failed
block allocation and before we do a vmtruncate we don't leak block
(ie block marked as used in bitmap but not claimed by the inode).

Signed-off-by: default avatarAneesh Kumar K.V <>
CC:  Jan Kara <>
Signed-off-by: default avatar"Theodore Ts'o" <>
parent b31e1552
......@@ -1459,7 +1459,7 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
struct page **pagep, void **fsdata)
struct inode *inode = mapping->host;
int ret, needed_blocks = ext4_writepage_trans_blocks(inode);
int ret, needed_blocks;
handle_t *handle;
int retries = 0;
struct page *page;
......@@ -1470,6 +1470,11 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
"dev %s ino %lu pos %llu len %u flags %u",
inode->i_sb->s_id, inode->i_ino,
(unsigned long long) pos, len, flags);
* Reserve one block more for addition to orphan list in case
* we allocate blocks but write fails for some reason
needed_blocks = ext4_writepage_trans_blocks(inode) + 1;
index = pos >> PAGE_CACHE_SHIFT;
from = pos & (PAGE_CACHE_SIZE - 1);
to = from + len;
......@@ -1503,15 +1508,30 @@ static int ext4_write_begin(struct file *file, struct address_space *mapping,
if (ret) {
* block_write_begin may have instantiated a few blocks
* outside i_size. Trim these off again. Don't need
* i_size_read because we hold i_mutex.
* Add inode to orphan list in case we crash before
* truncate finishes
if (pos + len > inode->i_size)
ext4_orphan_add(handle, inode);
if (pos + len > inode->i_size) {
vmtruncate(inode, inode->i_size);
* If vmtruncate failed early the inode might
* still be on the orphan list; we need to
* make sure the inode is removed from the
* orphan list in that case.
if (inode->i_nlink)
ext4_orphan_del(NULL, inode);
if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment