From patchwork Mon Apr 2 15:14:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Foster X-Patchwork-Id: 150177 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 0CCCAB6EF3 for ; Tue, 3 Apr 2012 01:14:41 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753111Ab2DBPOj (ORCPT ); Mon, 2 Apr 2012 11:14:39 -0400 Received: from mx1.redhat.com ([209.132.183.28]:29526 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753107Ab2DBPOj (ORCPT ); Mon, 2 Apr 2012 11:14:39 -0400 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q32FEcdT027083 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Mon, 2 Apr 2012 11:14:38 -0400 Received: from bfoster.bfoster (dhcp-187-76.bos.redhat.com [10.16.187.76]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id q32FEc0k030190 for ; Mon, 2 Apr 2012 11:14:38 -0400 Message-ID: <4F79C24C.7070907@redhat.com> Date: Mon, 02 Apr 2012 11:14:20 -0400 From: Brian Foster User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:10.0.1) Gecko/20120216 Thunderbird/10.0.1 MIME-Version: 1.0 To: linux-ext4@vger.kernel.org Subject: [RFC PATCH 2/2] ext4: undo ei->i_da_metadata_calc_len increment if we fail to claim space X-Scanned-By: MIMEDefang 2.68 on 10.5.11.23 Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Brian Foster If we call ext4_calc_metadata_amount() and then fail to claim the space, a subsequent successful request to a block covered by the same ext2 indirect block will set md_needed to 0, fail to update the associated counters and result in a delayed md block allocation without a reservation. Decrement i_da_metadata_calc_len on failure to ensure the next reservation sets md_needed correctly. Signed-off-by: Brian Foster --- fs/ext4/inode.c | 18 ++++++++++++++++-- 1 files changed, 16 insertions(+), 2 deletions(-) diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index b58845c..7d2a3c0 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -1138,13 +1138,14 @@ repeat: * We do still charge estimated metadata to the sb though; * we cannot afford to run out of free blocks. */ - if (ext4_claim_free_clusters(sbi, md_needed + 1, 0)) { + ret = ext4_claim_free_clusters(sbi, md_needed + 1, 0); + if (ret) { dquot_release_reservation_block(inode, EXT4_C2B(sbi, 1)); if (ext4_should_retry_alloc(inode->i_sb, &retries)) { yield(); goto repeat; } - return -ENOSPC; + goto error; } spin_lock(&ei->i_block_reservation_lock); ei->i_reserved_data_blocks++; @@ -1152,6 +1153,19 @@ repeat: spin_unlock(&ei->i_block_reservation_lock); return 0; /* success */ + +error: + /* + * We've failed to reserve the space. Undo the effect + * of ext4_calc_metadata_amount() to ensure the next + * attempt correctly accounts for metadata. + */ + spin_lock(&ei->i_block_reservation_lock); + if (ei->i_da_metadata_calc_len) + ei->i_da_metadata_calc_len--; + spin_unlock(&ei->i_block_reservation_lock); + + return ret; } static void ext4_da_release_space(struct inode *inode, int to_free)