Updated patch for 2.1.119 knfsd

Bill Hawes (whawes@transmeta.com)
Mon, 31 Aug 1998 08:09:04 -0700


This is a multi-part message in MIME format.
--------------83CFEA5102E6BCC529848468
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

I've attached an updated and cleaned-up patch to fix the knfsd semaphore-count problem, which turned out
to be caused by an improperly initialized fh structure.

The fix was simple, and I've left in a few of the diagnostic messages in case any similar bugs remain to
be found.

Regards,
Bill

--------------83CFEA5102E6BCC529848468
Content-Type: text/plain; charset=us-ascii; name="nfsd_119-patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="nfsd_119-patch"

--- linux-2.1.119/include/linux/nfsd/nfsfh.h.old Fri Aug 28 08:30:03 1998
+++ linux-2.1.119/include/linux/nfsd/nfsfh.h Sun Aug 30 19:15:29 1998
@@ -20,6 +20,8 @@
#include <linux/nfsd/const.h>
#include <linux/nfsd/debug.h>

+/* #define NFSD_PARANOIA 1 */
+
/*
* This is the new "dentry style" Linux NFSv2 file handle.
*
@@ -110,9 +112,9 @@
static __inline__ struct svc_fh *
fh_copy(struct svc_fh *dst, struct svc_fh *src)
{
- if (src->fh_dverified) {
+ if (src->fh_dverified || src->fh_locked) {
struct dentry *dentry = src->fh_dentry;
- printk("fh_copy: copying %s/%s, already verified!\n",
+ printk(KERN_ERR "fh_copy: copying %s/%s, already verified!\n",
dentry->d_parent->d_name.name, dentry->d_name.name);
}

@@ -133,22 +135,37 @@
static inline void
fh_lock(struct svc_fh *fhp)
{
- struct inode *inode = fhp->fh_dentry->d_inode;
+ struct dentry *dentry = fhp->fh_dentry;
+ struct inode *inode;

/*
dfprintk(FILEOP, "nfsd: fh_lock(%x/%ld) locked = %d\n",
SVCFH_DEV(fhp), SVCFH_INO(fhp), fhp->fh_locked);
*/
+ if (!fhp->fh_dverified) {
+ printk(KERN_ERR "fh_lock: fh not verified!\n");
+ return;
+ }
if (fhp->fh_locked) {
printk(KERN_WARNING "fh_lock: %s/%s already locked!\n",
- fhp->fh_dentry->d_parent->d_name.name,
- fhp->fh_dentry->d_name.name);
+ dentry->d_parent->d_name.name, dentry->d_name.name);
return;
}
+
+ inode = dentry->d_inode;
down(&inode->i_sem);
if (!fhp->fh_pre_mtime)
fhp->fh_pre_mtime = inode->i_mtime;
fhp->fh_locked = 1;
+
+#ifdef NFSD_PARANOIA
+if (!fhp->fh_dverified)
+printk(KERN_ERR "fh_lock: not verified after down()!\n");
+if (atomic_read(&inode->i_sem.count) > 0)
+printk(KERN_ERR "fh_lock: %s/%s not really locked, count=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name,
+atomic_read(&inode->i_sem.count));
+#endif
}

/*
@@ -157,12 +174,24 @@
static inline void
fh_unlock(struct svc_fh *fhp)
{
+ if (!fhp->fh_dverified)
+ printk(KERN_ERR "fh_unlock: fh not verified!\n");
+
if (fhp->fh_locked) {
- struct inode *inode = fhp->fh_dentry->d_inode;
+ struct dentry *dentry = fhp->fh_dentry;
+ struct inode *inode = dentry->d_inode;
+
if (!fhp->fh_post_version)
fhp->fh_post_version = inode->i_version;
fhp->fh_locked = 0;
up(&inode->i_sem);
+
+#ifdef NFSD_PARANOIA
+if (atomic_read(&inode->i_sem.count) > 1)
+printk(KERN_ERR "fh_unlock: %s/%s has bad count %d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name,
+atomic_read(&inode->i_sem.count));
+#endif
}
}

--- linux-2.1.119/fs/nfsd/nfsfh.c.old Thu Aug 6 16:54:09 1998
+++ linux-2.1.119/fs/nfsd/nfsfh.c Sun Aug 30 19:17:47 1998
@@ -1107,7 +1107,7 @@

dprintk("nfsd: fh_compose(exp %x/%ld %s/%s, ino=%ld)\n",
exp->ex_dev, exp->ex_ino,
- dentry->d_parent->d_name.name, dentry->d_name.name,
+ parent->d_name.name, dentry->d_name.name,
(inode ? inode->i_ino : 0));

/*
@@ -1115,7 +1115,12 @@
* may not be done on error paths, but the cleanup must call fh_put.
* Fix this soon!
*/
+ if (fhp->fh_dverified || fhp->fh_locked || fhp->fh_dentry) {
+ printk(KERN_ERR "fh_compose: fh %s/%s not initialized!\n",
+ parent->d_name.name, dentry->d_name.name);
+ }
fh_init(fhp);
+
fhp->fh_handle.fh_dcookie = dentry;
if (inode) {
fhp->fh_handle.fh_ino = ino_t_to_u32(inode->i_ino);
--- linux-2.1.119/fs/nfsd/lockd.c.old Tue Dec 9 12:16:25 1997
+++ linux-2.1.119/fs/nfsd/lockd.c Sat Aug 29 18:49:00 1998
@@ -22,12 +22,13 @@
static u32
nlm_fopen(struct svc_rqst *rqstp, struct knfs_fh *f, struct file *filp)
{
- struct svc_fh fh;
u32 nfserr;
+ struct svc_fh fh;

+ /* must initialize before using! */
+ fh_init(&fh);
fh.fh_handle = *f;
fh.fh_export = NULL;
- fh.fh_dverified = 0;

nfserr = nfsd_open(rqstp, &fh, S_IFREG, 0, filp);
if (!nfserr)
--- linux-2.1.119/fs/nfsd/export.c.old Thu May 21 13:57:47 1998
+++ linux-2.1.119/fs/nfsd/export.c Sat Aug 29 12:01:04 1998
@@ -392,14 +392,15 @@
int
exp_rootfh(struct svc_client *clp, kdev_t dev, ino_t ino, struct knfs_fh *f)
{
- struct svc_export *exp = NULL;
- struct svc_fh fh;
+ struct svc_export *exp;
struct dentry *dentry;
struct inode *inode;
+ struct svc_fh fh;

dprintk("nfsd: exp_rootfh(%s:%x/%ld)\n", clp->cl_ident, dev, ino);

- if (!(exp = exp_get(clp, dev, ino)))
+ exp = exp_get(clp, dev, ino);
+ if (!exp)
return -EPERM;

dentry = exp->ex_dentry;
@@ -414,8 +415,11 @@
dev, ino, inode->i_dev, inode->i_ino);
}

- dget(dentry);
- fh_compose(&fh, exp, dentry);
+ /*
+ * fh must be initialized before calling fh_compose
+ */
+ fh_init(&fh);
+ fh_compose(&fh, exp, dget(dentry));
memcpy(f, &fh.fh_handle, sizeof(struct knfs_fh));
fh_put(&fh);

--------------83CFEA5102E6BCC529848468--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.altern.org/andrebalsa/doc/lkml-faq.html