From mboxrd@z Thu Jan 1 00:00:00 1970 From: Andrew Morton Subject: Re: [PATCH]: ufs: ufs_get_locked_patch race fix Date: Mon, 31 Jul 2006 23:02:51 -0700 Message-ID: <20060731230251.3b149902.akpm@osdl.org> References: <20060731125702.GA5094@rain> Mime-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Cc: linux-kernel@vger.kernel.org, linux-fsdevel@vger.kernel.org Return-path: Received: from smtp.osdl.org ([65.172.181.4]:63895 "EHLO smtp.osdl.org") by vger.kernel.org with ESMTP id S1161086AbWHAGC7 (ORCPT ); Tue, 1 Aug 2006 02:02:59 -0400 To: Evgeniy Dushistov In-Reply-To: <20060731125702.GA5094@rain> Sender: linux-fsdevel-owner@vger.kernel.org List-Id: linux-fsdevel.vger.kernel.org On Mon, 31 Jul 2006 16:57:02 +0400 Evgeniy Dushistov wrote: > As discussed earlier: > http://lkml.org/lkml/2006/6/28/136 > this patch fixes such issue: > `ufs_get_locked_page' takes page from cache > after that `vmtruncate' takes page and deletes it from cache > `ufs_get_locked_page' locks page, and reports about EIO error. > > Also because of find_lock_page always return valid page or NULL, > we have no need check it if page not NULL. > > Signed-off-by: Evgeniy Dushistov > > > --- > > > Index: linux-2.6.18-rc2-mm1/fs/ufs/util.c > =================================================================== > --- linux-2.6.18-rc2-mm1.orig/fs/ufs/util.c > +++ linux-2.6.18-rc2-mm1/fs/ufs/util.c > @@ -257,6 +257,7 @@ try_again: > page = read_cache_page(mapping, index, > (filler_t*)mapping->a_ops->readpage, > NULL); > + > if (IS_ERR(page)) { > printk(KERN_ERR "ufs_change_blocknr: " > "read_cache_page error: ino %lu, index: %lu\n", > @@ -266,6 +267,13 @@ try_again: > > lock_page(page); > > + if (unlikely(page->mapping != mapping || > + page->index != index)) { > + unlock_page(page); > + page_cache_release(page); > + goto try_again; > + } > + > if (!PageUptodate(page) || PageError(page)) { > unlock_page(page); > page_cache_release(page); Looks good to me. Is there any need to be checking ->index? Normally we simply use the sequence: lock_page(page); if (page->mapping == NULL) /* truncate got there first */ to handle this case.