From: Akira Fujita Subject: Re: [PATCH]ext4: fix s_dirty_blocks_counter if block allocation failed with nodelalloc Date: Thu, 04 Dec 2008 17:32:58 +0900 Message-ID: <493795BA.4010507@rs.jp.nec.com> References: <4933BAC2.6080004@rs.jp.nec.com> <20081201103641.GA13242@skywalker> <493731FD.5040809@rs.jp.nec.com> <20081204050745.GC10787@skywalker> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: Theodore Tso , Li Zefan , linux-ext4@vger.kernel.org To: "Aneesh Kumar K.V" Return-path: Received: from TYO202.gate.nec.co.jp ([202.32.8.206]:62861 "EHLO tyo202.gate.nec.co.jp" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755538AbYLDIda (ORCPT ); Thu, 4 Dec 2008 03:33:30 -0500 In-Reply-To: <20081204050745.GC10787@skywalker> Sender: linux-ext4-owner@vger.kernel.org List-ID: Aneesh Kumar K.V wrote: > On Thu, Dec 04, 2008 at 10:27:25AM +0900, Akira Fujita wrote: >> Hi Aneesh, >> Aneesh Kumar K.V wrote: >>> On Mon, Dec 01, 2008 at 07:21:54PM +0900, Akira Fujita wrote: >>>> ext4: Fix s_dirty_blocks_counter if block allocation failed with nodelalloc >>>> >>>> From: Akira Fujita >>>> >>>> If block allocation failed after marking claimed blocks as dirty blocks >>>> with nodelalloc, we have to subtract these blocks from >>>> s_dirty_blocks_counter in error handling. >>>> Otherwise s_dirty_blocks_counter goes wrong so that >>>> filesystem's free blocks decreases incorrectly. >>> Why did the block allocation fail ? With delayed allocation ENOSPC >>> should not happen during block allocation. That would mean we did >>> something wrong in block reservation. >> My case was *nodelalloc* and FS was almost full. >> This problem occurs in multiple defrag running in short time. >> Usually defrag releases temporary inode's blocks with iput, >> then FS free blocks are recover but contiguous blocks do not recover >> until next journal commit. >> so we can not re-use contiguous blocks immediately. >> There are enough free blocks in FS so that >> ext4_claim_free_blocks marks claimed blocks as dirty, >> but ext4_regular_allocator can not find enough blocks, >> so mb_new_blocks returns ENOSPC without decreasing dirty blocks. >> > ok how about doing the check once in ext4_mb_new_blocks. It works fine. Thank you. Tested-by: Akira Fujita > diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c > index bacc2f4..22d31c3 100644 > --- a/fs/ext4/mballoc.c > +++ b/fs/ext4/mballoc.c > @@ -4550,7 +4550,7 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, > } > if (ar->len == 0) { > *errp = -EDQUOT; > - return 0; > + goto out3; > } > inquota = ar->len; > > @@ -4623,6 +4623,13 @@ ext4_fsblk_t ext4_mb_new_blocks(handle_t *handle, > out1: > if (ar->len < inquota) > DQUOT_FREE_BLOCK(ar->inode, inquota - ar->len); > +out3: > + if (!ar->len) { > + if (!EXT4_I(ar->inode)->i_delalloc_reserved_flag) > + /* release all the reserved blocks if non delalloc */ > + percpu_counter_sub(&sbi->s_dirtyblocks_counter, > + reserv_blks); > + } > > return block; > }