patch-2.4.0-test3 linux/fs/nfsd/nfsfh.c

Next file: linux/fs/nfsd/nfsproc.c
Previous file: linux/fs/nfsd/nfsctl.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.4.0-test2/linux/fs/nfsd/nfsfh.c linux/fs/nfsd/nfsfh.c
@@ -8,7 +8,6 @@
  * Extensive rewrite by Neil Brown <neilb@cse.unsw.edu.au> Southern-Spring 1999
  */
 
-#include <linux/config.h>
 #include <linux/sched.h>
 #include <linux/malloc.h>
 #include <linux/fs.h>
@@ -152,14 +151,17 @@
 	/* now to find a dentry.
 	 * If possible, get a well-connected one
 	 */
+	spin_lock(&dcache_lock);
 	for (lp = inode->i_dentry.next; lp != &inode->i_dentry ; lp=lp->next) {
 		result = list_entry(lp,struct dentry, d_alias);
 		if (! (result->d_flags & DCACHE_NFSD_DISCONNECTED)) {
-			dget(result);
+			dget_locked(result);
+			spin_unlock(&dcache_lock);
 			iput(inode);
 			return result;
 		}
 	}
+	spin_unlock(&dcache_lock);
 	result = d_alloc_root(inode);
 	if (result == NULL) {
 		iput(inode);
@@ -192,8 +194,10 @@
 	/* tdentry will have been made a "child" of target (the parent of target)
 	 * make it an IS_ROOT instead
 	 */
+	spin_lock(&dcache_lock);
 	list_del(&tdentry->d_child);
 	tdentry->d_parent = tdentry;
+	spin_unlock(&dcache_lock);
 	d_rehash(target);
 	dput(tdentry);
 
@@ -205,6 +209,7 @@
 		while (target) {
 			target->d_flags &= ~DCACHE_NFSD_DISCONNECTED;
 			parent = target;
+			spin_lock(&dcache_lock);
 			if (list_empty(&parent->d_subdirs))
 				target = NULL;
 			else {
@@ -217,6 +222,7 @@
 					       parent->d_name.name, target->d_name.name);
 #endif
 			}
+			spin_unlock(&dcache_lock);
 		}
 	}
 	return 0;
@@ -247,14 +253,16 @@
 		 * else make a root dentry
 		 */
 		struct list_head *aliases = &tdentry->d_inode->i_dentry;
+		spin_lock(&dcache_lock);
 		if (aliases->next != aliases) {
 			pdentry = list_entry(aliases->next, struct dentry, d_alias);
 			if (pdentry == tdentry)
 				pdentry = list_entry(aliases->prev, struct dentry, d_alias);
 			if (pdentry == tdentry)
 				pdentry = NULL;
-			if (pdentry) dget(pdentry);
+			if (pdentry) dget_locked(pdentry);
 		}
+		spin_unlock(&dcache_lock);
 		if (pdentry == NULL) {
 			pdentry = d_alloc_root(igrab(tdentry->d_inode));
 			if (pdentry) {
@@ -289,16 +297,20 @@
 	 * to a lookup (though nobody does this yet).  In this case, just succeed.
 	 */
 	if (child->d_parent == parent) goto out;
-	/* Possibly a new dentry has been made for this child->d_inode in parent by
-	 * a lookup.  In this case return that dentry. caller must notice and act accordingly
+	/* Possibly a new dentry has been made for this child->d_inode in
+	 * parent by a lookup.  In this case return that dentry. caller must
+	 * notice and act accordingly
 	 */
+	spin_lock(&dcache_lock);
 	for (lp = child->d_inode->i_dentry.next; lp != &child->d_inode->i_dentry ; lp=lp->next) {
 		tmp = list_entry(lp,struct dentry, d_alias);
 		if (tmp->d_parent == parent) {
-			child = dget(tmp);
+			child = dget_locked(tmp);
+			spin_unlock(&dcache_lock);
 			goto out;
 		}
 	}
+	spin_unlock(&dcache_lock);
 	/* well, if we can find a name for child in parent, it should be safe to splice it in */
 	err = get_ino_name(parent, &qs, child->d_inode->i_ino);
 	if (err)
@@ -495,17 +507,15 @@
 
 	dprintk("nfsd: fh_verify(%s)\n", SVCFH_fmt(fhp));
 
-	if (!fhp->fh_dverified) {
+	if (!fhp->fh_dentry) {
 		kdev_t xdev;
 		ino_t xino;
 		__u32 *datap=NULL;
 		int data_left = fh->fh_size/4;
 		int nfsdev;
 		error = nfserr_stale;
-#if CONFIG_NFSD_V3		
 		if (rqstp->rq_vers == 3)
 			error = nfserr_badhandle;
-#endif
 		if (fh->fh_version == 1) {
 			
 			datap = fh->fh_auth;
@@ -562,10 +572,8 @@
 		 * Look up the dentry using the NFS file handle.
 		 */
 		error = nfserr_stale;
-#if CONFIG_NFSD_V3		
 		if (rqstp->rq_vers == 3)
 			error = nfserr_badhandle;
-#endif
 
 		if (fh->fh_version == 1) {
 			/* if fileid_type != 0, and super_operations provide fh_to_dentry lookup,
@@ -611,7 +619,6 @@
 
 		fhp->fh_dentry = dentry;
 		fhp->fh_export = exp;
-		fhp->fh_dverified = 1;
 		nfsd_nr_verified++;
 	} else {
 		/* just rechecking permissions
@@ -731,7 +738,7 @@
 		parent->d_name.name, dentry->d_name.name,
 		(inode ? inode->i_ino : 0));
 
-	if (fhp->fh_dverified || fhp->fh_locked || fhp->fh_dentry) {
+	if (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);
 	}
@@ -757,8 +764,6 @@
 	fhp->fh_handle.fh_size = (datap-fhp->fh_handle.fh_auth+1)*4;
 
 
-	/* We stuck it there, we know it's good. */
-	fhp->fh_dverified = 1;
 	nfsd_nr_verified++;
 	if (fhp->fh_handle.fh_fileid_type == 255)
 		return nfserr_opnotsupp;
@@ -775,7 +780,7 @@
 	struct dentry *dentry;
 	__u32 *datap;
 	
-	if (!fhp->fh_dverified)
+	if (!fhp->fh_dentry)
 		goto out_bad;
 
 	dentry = fhp->fh_dentry;
@@ -811,10 +816,9 @@
 fh_put(struct svc_fh *fhp)
 {
 	struct dentry * dentry = fhp->fh_dentry;
-	if (fhp->fh_dverified) {
+	if (dentry) {
 		fh_unlock(fhp);
 		fhp->fh_dentry = NULL;
-		fhp->fh_dverified = 0;
 		dput(dentry);
 		nfsd_nr_put++;
 	}

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)