Commit 2712419f authored by Neil Brown's avatar Neil Brown Committed by Linus Torvalds

[PATCH] PATCH 1/7: knfsd cleanups - big fixes

Fix bugs recently introduced into kNFSd

When searching a list.h list, we cannot export
to find NULL at the end.  Instead we return a pointer
when found, or NULL if nothing found.  Same bug, 4 times.

The seq_file improvements to /proc/fs/nfs/exports got the counting
wrong so that some clients would get reported twice, always the last.
parent 4d32c6ba
...@@ -73,18 +73,17 @@ svc_export * ...@@ -73,18 +73,17 @@ svc_export *
exp_get(svc_client *clp, kdev_t dev, ino_t ino) exp_get(svc_client *clp, kdev_t dev, ino_t ino)
{ {
struct list_head *head, *p; struct list_head *head, *p;
svc_export *exp = NULL;
if (!clp) if (!clp)
return NULL; return NULL;
head = &clp->cl_export[EXPORT_HASH(dev)]; head = &clp->cl_export[EXPORT_HASH(dev)];
list_for_each(p, head) { list_for_each(p, head) {
exp = list_entry(p, svc_export, ex_hash); svc_export *exp = list_entry(p, svc_export, ex_hash);
if (exp->ex_ino == ino && kdev_same(exp->ex_dev, dev)) if (exp->ex_ino == ino && kdev_same(exp->ex_dev, dev))
break;
}
return exp; return exp;
}
return NULL;
} }
svc_export * svc_export *
...@@ -92,18 +91,17 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry) ...@@ -92,18 +91,17 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry)
{ {
struct list_head *head, *p; struct list_head *head, *p;
int hash = EXPORT_HASH(mnt->mnt_sb->s_dev); int hash = EXPORT_HASH(mnt->mnt_sb->s_dev);
svc_export *exp = NULL;
if (!clp) if (!clp)
return NULL; return NULL;
head = &clp->cl_export[hash]; head = &clp->cl_export[hash];
list_for_each(p, head) { list_for_each(p, head) {
exp = list_entry(p, svc_export, ex_hash); svc_export *exp = list_entry(p, svc_export, ex_hash);
if (exp->ex_dentry == dentry && exp->ex_mnt == mnt) if (exp->ex_dentry == dentry && exp->ex_mnt == mnt)
break; break;
} }
return exp; return NULL;
} }
/* /*
...@@ -114,14 +112,13 @@ exp_parent(svc_client *clp, struct super_block *sb, struct dentry *dentry) ...@@ -114,14 +112,13 @@ exp_parent(svc_client *clp, struct super_block *sb, struct dentry *dentry)
{ {
struct list_head *head = &clp->cl_export[EXPORT_HASH(sb->s_dev)]; struct list_head *head = &clp->cl_export[EXPORT_HASH(sb->s_dev)];
struct list_head *p; struct list_head *p;
svc_export *exp = NULL;
list_for_each(p, head) { list_for_each(p, head) {
exp = list_entry(p, svc_export, ex_hash); svc_export *exp = list_entry(p, svc_export, ex_hash);
if (is_subdir(dentry, exp->ex_dentry)) if (is_subdir(dentry, exp->ex_dentry))
break;
}
return exp; return exp;
}
return NULL;
} }
/* /*
...@@ -134,16 +131,15 @@ exp_child(svc_client *clp, struct super_block *sb, struct dentry *dentry) ...@@ -134,16 +131,15 @@ exp_child(svc_client *clp, struct super_block *sb, struct dentry *dentry)
{ {
struct list_head *head = &clp->cl_export[EXPORT_HASH(sb->s_dev)]; struct list_head *head = &clp->cl_export[EXPORT_HASH(sb->s_dev)];
struct list_head *p; struct list_head *p;
svc_export *exp = NULL;
struct dentry *ndentry; struct dentry *ndentry;
list_for_each(p, head) { list_for_each(p, head) {
exp = list_entry(p, svc_export, ex_hash); svc_export *exp = list_entry(p, svc_export, ex_hash);
ndentry = exp->ex_dentry; ndentry = exp->ex_dentry;
if (ndentry && is_subdir(ndentry->d_parent, dentry)) if (ndentry && is_subdir(ndentry->d_parent, dentry))
break;
}
return exp; return exp;
}
return NULL;
} }
/* Update parent pointers of all exports */ /* Update parent pointers of all exports */
...@@ -552,9 +548,10 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos) ...@@ -552,9 +548,10 @@ static void *e_next(struct seq_file *m, void *p, loff_t *pos)
if (p == (void *)1) if (p == (void *)1)
clp = clients; clp = clients;
else if (exp->ex_list.next == &exp->ex_client->cl_list) else if (exp->ex_list.next == &exp->ex_client->cl_list) {
clp = exp->ex_client->cl_next; clp = exp->ex_client->cl_next;
else { *pos += 1LL<<32;
} else {
++*pos; ++*pos;
return list_entry(exp->ex_list.next, svc_export, ex_list); return list_entry(exp->ex_list.next, svc_export, ex_list);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment