From: Bryan Schumaker <bjschuma@netapp.com>
To: "Trond >> \"Myklebust, Trond\"" <Trond.Myklebust@netapp.com>
Cc: "linux-nfs@vger.kernel.org" <linux-nfs@vger.kernel.org>
Subject: [PATCH 3/3] NFS: Detect loops in a readdir due to bad cookies
Date: Wed, 23 Mar 2011 13:39:44 -0400 [thread overview]
Message-ID: <4D8A3060.807@netapp.com> (raw)
Some filesystems (such as ext4) can return the same cookie value for multiple
files. If we try to start a readdir with one of these cookies, the server will
return the first file found with a cookie of the same value. This can cause
the client to enter an infinite loop.
Signed-off-by: Bryan Schumaker <bjschuma@netapp.com>
---
fs/nfs/dir.c | 23 ++++++++++++++++++++++-
include/linux/nfs_fs.h | 2 ++
2 files changed, 24 insertions(+), 1 deletions(-)
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;
};
/*
--
1.7.4.1
next reply other threads:[~2011-03-23 17:39 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-03-23 17:39 Bryan Schumaker [this message]
2011-03-23 18:10 ` [PATCH 3/3] NFS: Detect loops in a readdir due to bad cookies peter.staubach
2011-03-23 18:17 ` Trond Myklebust
2011-03-23 18:11 ` Trond Myklebust
2011-03-23 18:25 ` J. Bruce Fields
2011-03-23 18:34 ` Trond Myklebust
2011-03-23 18:42 ` peter.staubach
2011-03-23 18:48 ` Trond Myklebust
2011-03-23 21:27 ` NeilBrown
2011-03-23 21:36 ` Daniel.Muntz
2011-03-23 21:55 ` NeilBrown
2011-03-23 18:43 ` peter.staubach
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4D8A3060.807@netapp.com \
--to=bjschuma@netapp.com \
--cc=Trond.Myklebust@netapp.com \
--cc=linux-nfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.