154 lines
6.2 KiB
Diff
154 lines
6.2 KiB
Diff
|
|
Delivered-To: jwboyer@gmail.com
|
|
Received: by 10.229.191.66 with SMTP id dl2csp36421qcb;
|
|
Tue, 26 Jun 2012 07:55:48 -0700 (PDT)
|
|
Received: by 10.68.228.136 with SMTP id si8mr53042278pbc.159.1340722548310;
|
|
Tue, 26 Jun 2012 07:55:48 -0700 (PDT)
|
|
Return-Path: <stable-owner@vger.kernel.org>
|
|
Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67])
|
|
by mx.google.com with ESMTP id qg1si15735731pbc.300.2012.06.26.07.55.47;
|
|
Tue, 26 Jun 2012 07:55:48 -0700 (PDT)
|
|
Received-SPF: pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67;
|
|
Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mail=stable-owner@vger.kernel.org
|
|
Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
|
|
id S1757370Ab2FZOzp (ORCPT <rfc822;aaditya.kumar.30@gmail.com>
|
|
+ 23 others); Tue, 26 Jun 2012 10:55:45 -0400
|
|
Received: from mx1.redhat.com ([209.132.183.28]:64097 "EHLO mx1.redhat.com"
|
|
rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
|
|
id S1757325Ab2FZOzo (ORCPT <rfc822;stable@vger.kernel.org>);
|
|
Tue, 26 Jun 2012 10:55:44 -0400
|
|
Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11])
|
|
by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q5QEtbK2017450
|
|
(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK);
|
|
Tue, 26 Jun 2012 10:55:38 -0400
|
|
Received: from segfault.boston.devel.redhat.com (segfault.boston.devel.redhat.com [10.16.60.26])
|
|
by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id q5QEtZV9023431;
|
|
Tue, 26 Jun 2012 10:55:35 -0400
|
|
From: Jeff Moyer <jmoyer@redhat.com>
|
|
To: Jens Axboe <jaxboe@fusionio.com>, Nick Piggin <npiggin@kernel.dk>
|
|
Cc: LKML List <linux-kernel@vger.kernel.org>,
|
|
torsten.hilbrich@secunet.com, Richard Jones <rjones@redhat.com>,
|
|
stable@vger.kernel.org, Marcos Mello <marcosfrm@gmail.com>
|
|
Subject: [patch] block: fix infinite loop in __getblk_slow
|
|
X-PGP-KeyID: 1F78E1B4
|
|
X-PGP-CertKey: F6FE 280D 8293 F72C 65FD 5A58 1FF8 A7CA 1F78 E1B4
|
|
X-PCLoadLetter: What the f**k does that mean?
|
|
Date: Tue, 26 Jun 2012 10:55:34 -0400
|
|
Message-ID: <x49r4t2rul5.fsf@segfault.boston.devel.redhat.com>
|
|
User-Agent: Gnus/5.110011 (No Gnus v0.11) Emacs/23.1 (gnu/linux)
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=us-ascii
|
|
X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11
|
|
Sender: stable-owner@vger.kernel.org
|
|
Precedence: bulk
|
|
List-ID: <stable.vger.kernel.org>
|
|
X-Mailing-List: stable@vger.kernel.org
|
|
|
|
Hi,
|
|
|
|
This commit:
|
|
|
|
commit 080399aaaf3531f5b8761ec0ac30ff98891e8686
|
|
Author: Jeff Moyer <jmoyer@redhat.com>
|
|
Date: Fri May 11 16:34:10 2012 +0200
|
|
|
|
block: don't mark buffers beyond end of disk as mapped
|
|
|
|
exposed a bug in __getblk_slow that causes mount to hang as it loops
|
|
infinitely waiting for a buffer that lies beyond the end of the disk to
|
|
become uptodate. The problem was initially reported by Torsten Hilbrich
|
|
here: https://lkml.org/lkml/2012/6/18/54, and also reported
|
|
independently here:
|
|
http://www.sysresccd.org/forums/viewtopic.php?f=13&t=4511, and then
|
|
Richard W.M. Jones and Marcos Mello noted a few separate bugzillas also
|
|
associated with the same issue.
|
|
|
|
The main problem is here, in __getblk_slow:
|
|
|
|
for (;;) {
|
|
struct buffer_head * bh;
|
|
int ret;
|
|
|
|
bh = __find_get_block(bdev, block, size);
|
|
if (bh)
|
|
return bh;
|
|
|
|
ret = grow_buffers(bdev, block, size);
|
|
if (ret < 0)
|
|
return NULL;
|
|
if (ret == 0)
|
|
free_more_memory();
|
|
}
|
|
|
|
__find_get_block does not find the block, since it will not be marked as
|
|
mapped, and so grow_buffers is called to fill in the buffers for the
|
|
associated page. I believe the for (;;) loop is there primarily to
|
|
retry in the case of memory pressure keeping grow_buffers from
|
|
succeeding. However, we also continue to loop for other cases, like the
|
|
block lying beond the end of the disk. So, the fix I came up with is to
|
|
only loop when grow_buffers fails due to memory allocation issues
|
|
(return value of 0).
|
|
|
|
The attached patch was tested by myself, Torsten, and Rich, and was
|
|
found to resolve the problem in call cases.
|
|
|
|
Comments, as always, are appreciated.
|
|
|
|
Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
|
|
Reported-and-Tested-by: Torsten Hilbrich <torsten.hilbrich@secunet.com>
|
|
Tested-by: Richard W.M. Jones <rjones@redhat.com>
|
|
Cc: Stable <stable@vger.kernel.org>
|
|
|
|
--
|
|
Stable Notes: this patch requires backport to 3.0, 3.2 and 3.3.
|
|
|
|
diff --git a/fs/buffer.c b/fs/buffer.c
|
|
index 838a9cf..c7062c8 100644
|
|
--- a/fs/buffer.c
|
|
+++ b/fs/buffer.c
|
|
@@ -1036,6 +1036,9 @@ grow_buffers(struct block_device *bdev, sector_t block, int size)
|
|
static struct buffer_head *
|
|
__getblk_slow(struct block_device *bdev, sector_t block, int size)
|
|
{
|
|
+ int ret;
|
|
+ struct buffer_head *bh;
|
|
+
|
|
/* Size must be multiple of hard sectorsize */
|
|
if (unlikely(size & (bdev_logical_block_size(bdev)-1) ||
|
|
(size < 512 || size > PAGE_SIZE))) {
|
|
@@ -1048,20 +1051,21 @@ __getblk_slow(struct block_device *bdev, sector_t block, int size)
|
|
return NULL;
|
|
}
|
|
|
|
- for (;;) {
|
|
- struct buffer_head * bh;
|
|
- int ret;
|
|
+retry:
|
|
+ bh = __find_get_block(bdev, block, size);
|
|
+ if (bh)
|
|
+ return bh;
|
|
|
|
+ ret = grow_buffers(bdev, block, size);
|
|
+ if (ret == 0) {
|
|
+ free_more_memory();
|
|
+ goto retry;
|
|
+ } else if (ret > 0) {
|
|
bh = __find_get_block(bdev, block, size);
|
|
if (bh)
|
|
return bh;
|
|
-
|
|
- ret = grow_buffers(bdev, block, size);
|
|
- if (ret < 0)
|
|
- return NULL;
|
|
- if (ret == 0)
|
|
- free_more_memory();
|
|
}
|
|
+ return NULL;
|
|
}
|
|
|
|
/*
|
|
--
|
|
To unsubscribe from this list: send the line "unsubscribe stable" in
|
|
the body of a message to majordomo@vger.kernel.org
|
|
More majordomo info at http://vger.kernel.org/majordomo-info.html
|