From patchwork Wed Dec 1 15:36:43 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Trond Myklebust X-Patchwork-Id: 371571 X-Patchwork-Delegate: Trond.Myklebust@netapp.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oB1FbhbO004717 for ; Wed, 1 Dec 2010 15:37:43 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753150Ab0LAPgy (ORCPT ); Wed, 1 Dec 2010 10:36:54 -0500 Received: from mx2.netapp.com ([216.240.18.37]:56731 "EHLO mx2.netapp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752796Ab0LAPgw (ORCPT ); Wed, 1 Dec 2010 10:36:52 -0500 X-IronPort-AV: E=Sophos;i="4.59,283,1288594800"; d="scan'208";a="489508129" Received: from smtp1.corp.netapp.com ([10.57.156.124]) by mx2-out.netapp.com with ESMTP; 01 Dec 2010 07:36:52 -0800 Received: from heimdal.trondhjem.org.com (martin-laptop.hq.netapp.com [10.58.52.59] (may be forged)) by smtp1.corp.netapp.com (8.13.1/8.13.1/NTAP-1.6) with ESMTP id oB1Fam3Y014923; Wed, 1 Dec 2010 07:36:51 -0800 (PST) From: Trond Myklebust To: Linus Torvalds , Nick Bowler Cc: Linux Kernel Mailing List , linux-nfs@vger.kernel.org Subject: [PATCH v2 2/3] NFS: lock the readdir page while it is in use Date: Wed, 1 Dec 2010 10:36:43 -0500 Message-Id: <1291217804-11257-3-git-send-email-Trond.Myklebust@netapp.com> X-Mailer: git-send-email 1.7.3.2 In-Reply-To: <1291217804-11257-2-git-send-email-Trond.Myklebust@netapp.com> References: <1291217804-11257-1-git-send-email-Trond.Myklebust@netapp.com> <1291217804-11257-2-git-send-email-Trond.Myklebust@netapp.com> In-Reply-To: <20101201150428.GA2879@elliptictech.com> References: <20101201150428.GA2879@elliptictech.com> Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter1.kernel.org [140.211.167.41]); Wed, 01 Dec 2010 15:37:44 +0000 (UTC) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index e03537f..3ec3f1c 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -639,6 +639,7 @@ int nfs_readdir_filler(nfs_readdir_descriptor_t *desc, struct page* page) static void cache_page_release(nfs_readdir_descriptor_t *desc) { + unlock_page(desc->page); page_cache_release(desc->page); desc->page = NULL; } @@ -646,8 +647,20 @@ void cache_page_release(nfs_readdir_descriptor_t *desc) static struct page *get_cache_page(nfs_readdir_descriptor_t *desc) { - return read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping, + struct page *page; + + for (;;) { + page = read_cache_page(desc->file->f_path.dentry->d_inode->i_mapping, desc->page_index, (filler_t *)nfs_readdir_filler, desc); + if (IS_ERR(page)) + break; + lock_page(page); + if (page->mapping != NULL && PageUptodate(page)) + break; + unlock_page(page); + page_cache_release(page); + } + return page; } /* @@ -771,6 +784,7 @@ int uncached_readdir(nfs_readdir_descriptor_t *desc, void *dirent, desc->page_index = 0; desc->last_cookie = *desc->dir_cookie; desc->page = page; + lock_page(page); status = nfs_readdir_xdr_to_array(desc, page, inode); if (status < 0)