From patchwork Wed Mar 23 18:10:09 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: peter.staubach@emc.com X-Patchwork-Id: 656571 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 p2NICAG1018681 for ; Wed, 23 Mar 2011 18:12:10 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932366Ab1CWSL6 (ORCPT ); Wed, 23 Mar 2011 14:11:58 -0400 Received: from mexforward.lss.emc.com ([128.222.32.20]:35610 "EHLO mexforward.lss.emc.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932419Ab1CWSL4 convert rfc822-to-8bit (ORCPT ); Wed, 23 Mar 2011 14:11:56 -0400 Received: from hop04-l1d11-si01.isus.emc.com (HOP04-L1D11-SI01.isus.emc.com [10.254.111.54]) by mexforward.lss.emc.com (Switch-3.4.3/Switch-3.4.3) with ESMTP id p2NIBqOV003189 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 23 Mar 2011 14:11:53 -0400 Received: from mailhub.lss.emc.com (mailhub.lss.emc.com [10.254.222.226]) by hop04-l1d11-si01.isus.emc.com (RSA Interceptor); Wed, 23 Mar 2011 14:11:47 -0400 Received: from mxhub21.corp.emc.com (mxhub21.corp.emc.com [128.221.56.107]) by mailhub.lss.emc.com (Switch-3.4.3/Switch-3.4.3) with ESMTP id p2NIAFRO002587; Wed, 23 Mar 2011 14:10:16 -0400 Received: from mx31a.corp.emc.com ([169.254.1.74]) by mxhub21.corp.emc.com ([128.221.56.107]) with mapi; Wed, 23 Mar 2011 14:10:15 -0400 From: To: , CC: Date: Wed, 23 Mar 2011 14:10:09 -0400 Subject: RE: [PATCH 3/3] NFS: Detect loops in a readdir due to bad cookies Thread-Topic: [PATCH 3/3] NFS: Detect loops in a readdir due to bad cookies Thread-Index: AcvpgWt7z/nJ1h6kQUKxE1Am+X28FgAA/mKQ Message-ID: <5E6794FC7B8FCA41A704019BE3C70E8B0693F02D@MX31A.corp.emc.com> References: <4D8A3060.807@netapp.com> In-Reply-To: <4D8A3060.807@netapp.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-cr-hashedpuzzle: AEh3 CMZr CwHE DPVF Fb2n FvAw I7e/ KgOM OK/C QBYq UCZY VNFJ aF/a dXZd dxg8 gw4P; 3; YgBqAHMAYwBoAHUAbQBhAEAAbgBlAHQAYQBwAHAALgBjAG8AbQA7AGwAaQBuAHUAeAAtAG4AZgBzAEAAdgBnAGUAcgAuAGsAZQByAG4AZQBsAC4AbwByAGcAOwB0AHIAbwBuAGQALgBtAHkAawBsAGUAYgB1AHMAdABAAG4AZQB0AGEAcABwAC4AYwBvAG0A; Sosha1_v1; 7; {604A9195-1CD4-471C-AEA2-70BD25BF80CD}; cABlAHQAZQByAC4AcwB0AGEAdQBiAGEAYwBoAEAAZQBtAGMALgBjAG8AbQA=; Wed, 23 Mar 2011 18:10:09 GMT; UgBFADoAIABbAFAAQQBUAEMASAAgADMALwAzAF0AIABOAEYAUwA6ACAARABlAHQAZQBjAHQAIABsAG8AbwBwAHMAIABpAG4AIABhACAAcgBlAGEAZABkAGkAcgAgAGQAdQBlACAAdABvACAAYgBhAGQAIABjAG8AbwBrAGkAZQBzAA== x-cr-puzzleid: {604A9195-1CD4-471C-AEA2-70BD25BF80CD} acceptlanguage: en-US MIME-Version: 1.0 X-EMM-MHVC: 1 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.6 (demeter1.kernel.org [140.211.167.41]); Wed, 23 Mar 2011 18:12:10 +0000 (UTC) diff --git a/fs/nfs/dir.c b/fs/nfs/dir.c index b503791..dc475a7 100644 --- a/fs/nfs/dir.c +++ b/fs/nfs/dir.c @@ -139,7 +139,9 @@ static struct nfs_open_dir_context *alloc_nfs_open_dir_context(struct rpc_cred * struct nfs_open_dir_context *ctx; ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); if (ctx != NULL) { + ctx->duped = 0; ctx->dir_cookie = 0; + ctx->dup_cookie = 0; ctx->cred = get_rpccred(cred); } return ctx; @@ -342,11 +344,18 @@ static int nfs_readdir_search_for_cookie(struct nfs_cache_array *array, nfs_readdir_descriptor_t *desc) { int i; + int new_pos; int status = -EAGAIN; + struct nfs_open_dir_context *ctx = desc->file->private_data; for (i = 0; i < array->size; i++) { if (array->array[i].cookie == *desc->dir_cookie) { - desc->file->f_pos = desc->current_index + i; + new_pos = desc->current_index + i; + if (new_pos < desc->file->f_pos) { + ctx->dup_cookie = *desc->dir_cookie; + ctx->duped = 1; + } + desc->file->f_pos = new_pos; desc->cache_entry_index = i; return 0; } @@ -731,6 +740,18 @@ int nfs_do_filldir(nfs_readdir_descriptor_t *desc, void *dirent, int i = 0; int res = 0; struct nfs_cache_array *array = NULL; + struct nfs_open_dir_context *ctx = file->private_data; + + if (ctx->duped == 1 && ctx->dup_cookie == *desc->dir_cookie) { + if (printk_ratelimit()) { + pr_notice("NFS: directory %s/%s contains a readdir loop. " + "Please contact your server vendor.", + file->f_dentry->d_parent->d_name.name, + file->f_dentry->d_name.name); + } + res = -ELOOP; + goto out; + } array = nfs_readdir_get_array(desc->page); if (IS_ERR(array)) { diff --git a/include/linux/nfs_fs.h b/include/linux/nfs_fs.h index 4b87c00..bbb812b 100644 --- a/include/linux/nfs_fs.h +++ b/include/linux/nfs_fs.h @@ -97,7 +97,9 @@ struct nfs_open_context { struct nfs_open_dir_context { struct rpc_cred *cred; + int duped; __u64 dir_cookie; + __u64 dup_cookie; }; /*