From patchwork Tue Jun 7 15:07:56 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Amir G." X-Patchwork-Id: 99251 X-Patchwork-Delegate: tytso@mit.edu 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 6E83AB6F91 for ; Wed, 8 Jun 2011 01:10:19 +1000 (EST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756596Ab1FGPKR (ORCPT ); Tue, 7 Jun 2011 11:10:17 -0400 Received: from mail-ww0-f44.google.com ([74.125.82.44]:41767 "EHLO mail-ww0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1755640Ab1FGPKQ (ORCPT ); Tue, 7 Jun 2011 11:10:16 -0400 Received: by mail-ww0-f44.google.com with SMTP id 36so5035787wwa.1 for ; Tue, 07 Jun 2011 08:10:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:sender:from:to:cc:subject:date:message-id :x-mailer:in-reply-to:references; bh=WjdNhrcivXcTrgb6WqQFHyUqpRvPXbkrA+tD1fQm760=; b=HseeKJrCtXJQFG/uvBxtSOm4asMqvJ4Axyb+Hg1YLDwjeSYChgHQD4InULxcmWqpVM 0VVjbPTd30yrDsPYo7MiWer7wrcB2fb0HdPmjdxGJAOWrtpz1h2XkwLt364xydNKbrR5 vOZ+E4QhYS3e9UvVrquPg/5hd1hOhZCZcea1A= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; b=xhYVju+o0tlvwXaD6CljsK6bVBzxl6IiqS3o/C0U7Hj+dy1jntuGT67ukukygGS+OH MoJC6Eth07D4ACVyN0Ygm9kK5HlVYHL0Q4lDi0YSxC+cGNhW+H+V57ePkW1FilISQx08 z8hRE8tJsOm3uf27WU82feJvGLyNrIgUiQ1m8= Received: by 10.227.55.20 with SMTP id s20mr6474885wbg.15.1307459415917; Tue, 07 Jun 2011 08:10:15 -0700 (PDT) Received: from localhost.localdomain (bzq-218-153-66.cablep.bezeqint.net [81.218.153.66]) by mx.google.com with ESMTPS id en1sm3622645wbb.52.2011.06.07.08.10.13 (version=TLSv1/SSLv3 cipher=OTHER); Tue, 07 Jun 2011 08:10:15 -0700 (PDT) From: amir73il@users.sourceforge.net To: linux-ext4@vger.kernel.org Cc: tytso@mit.edu, lczerner@redhat.com, Amir Goldstein , Yongqiang Yang Subject: [PATCH v1 29/36] ext4: snapshot race conditions - concurrent COW bitmap operations Date: Tue, 7 Jun 2011 18:07:56 +0300 Message-Id: <1307459283-22130-30-git-send-email-amir73il@users.sourceforge.net> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1307459283-22130-1-git-send-email-amir73il@users.sourceforge.net> References: <1307459283-22130-1-git-send-email-amir73il@users.sourceforge.net> Sender: linux-ext4-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-ext4@vger.kernel.org From: Amir Goldstein Wait for pending COW bitmap creations to complete. When concurrent tasks try to COW buffers from the same block group for the first time, the first task to reset the COW bitmap cache is elected to create the new COW bitmap block. The rest of the tasks wait (in msleep(1) loop), until the COW bitmap cache is uptodate. The COWing task copies the bitmap block into the new COW bitmap block and updates the COW bitmap cache with the new block number. Signed-off-by: Amir Goldstein Signed-off-by: Yongqiang Yang --- fs/ext4/snapshot.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 42 insertions(+), 3 deletions(-) diff --git a/fs/ext4/snapshot.c b/fs/ext4/snapshot.c index 2724381..000e655 100644 --- a/fs/ext4/snapshot.c +++ b/fs/ext4/snapshot.c @@ -248,9 +248,48 @@ ext4_snapshot_read_cow_bitmap(handle_t *handle, struct inode *snapshot, bitmap_blk = ext4_block_bitmap(sb, desc); - ext4_lock_group(sb, block_group); - cow_bitmap_blk = grp->bg_cow_bitmap; - ext4_unlock_group(sb, block_group); + /* + * Handle concurrent COW bitmap operations. + * bg_cow_bitmap has 3 states: + * = 0 - uninitialized (after mount and after snapshot take). + * = bg_block_bitmap - marks pending COW of block bitmap. + * other - location of initialized COW bitmap block. + * + * The first task to access block group after mount or snapshot take, + * will read the uninitialized state, mark pending COW state, initialize + * the COW bitmap block and update COW bitmap cache. Other tasks will + * busy wait until the COW bitmap cache is in initialized state, before + * reading the COW bitmap block. + */ + do { + ext4_lock_group(sb, block_group); + cow_bitmap_blk = grp->bg_cow_bitmap; + if (cow_bitmap_blk == 0) + /* mark pending COW of bitmap block */ + grp->bg_cow_bitmap = bitmap_blk; + ext4_unlock_group(sb, block_group); + + if (cow_bitmap_blk == 0) { + snapshot_debug(3, "initializing COW bitmap #%u " + "of snapshot (%u)...\n", + block_group, snapshot->i_generation); + /* sleep 1 tunable delay unit */ + snapshot_test_delay(SNAPTEST_BITMAP); + break; + } + if (cow_bitmap_blk == bitmap_blk) { + /* wait for another task to COW bitmap block */ + snapshot_debug_once(2, "waiting for pending COW " + "bitmap #%d...\n", block_group); + /* + * This is an unlikely event that can happen only once + * per block_group/snapshot, so msleep(1) is sufficient + * and there is no need for a wait queue. + */ + msleep(1); + } + /* XXX: Should we fail after N retries? */ + } while (cow_bitmap_blk == 0 || cow_bitmap_blk == bitmap_blk); if (cow_bitmap_blk) return sb_bread(sb, cow_bitmap_blk);