patch-2.1.74 linux/fs/nfsd/vfs.c

Next file: linux/fs/nls/Config.in
Previous file: linux/fs/nfsd/nfssvc.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.1.73/linux/fs/nfsd/vfs.c linux/fs/nfsd/vfs.c
@@ -568,7 +568,8 @@
 		dchild = lookup_dentry(fname, dget(dentry), 0);
 		err = PTR_ERR(dchild);
 		if(IS_ERR(dchild))
-			return nfserrno(-err);
+			goto out_nfserr;
+		fh_compose(resfhp, fhp->fh_export, dchild);
 	} else
 		dchild = resfhp->fh_dentry;
 	/*
@@ -597,19 +598,14 @@
 	fh_unlock(fhp);
 
 	if (err < 0)
-		return nfserrno(-err);
+		goto out_nfserr;
 	if (EX_ISSYNC(fhp->fh_export))
 		write_inode_now(dirp);
 
 	/*
-	 * Assemble the file handle for the newly created file,
-	 * or update the filehandle to get the new inode info.
+	 * Update the filehandle to get the new inode info.
 	 */
-	if (!resfhp->fh_dverified) {
-		fh_compose(resfhp, fhp->fh_export, dchild);
-	} else {
-		fh_update(resfhp);
-	}
+	fh_update(resfhp);
 
 	/* Set file attributes. Mode has already been set and
 	 * setting uid/gid works only for root. Irix appears to
@@ -621,6 +617,10 @@
 		err = nfsd_setattr(rqstp, resfhp, iap);
 out:
 	return err;
+
+out_nfserr:
+	err = nfserrno(-err);
+	goto out;
 }
 
 /*
@@ -694,19 +694,21 @@
 		goto out;
 
 	UPDATE_ATIME(inode);
+	/* N.B. Why does this call need a get_fs()?? */
 	oldfs = get_fs(); set_fs(KERNEL_DS);
 	err = inode->i_op->readlink(inode, buf, *lenp);
 	set_fs(oldfs);
 
 	if (err < 0)
-		err = nfserrno(-err);
-	else {
-		*lenp = err;
-		err = 0;
-	}
-
+		goto out_nfserr;
+	*lenp = err;
+	err = 0;
 out:
 	return err;
+
+out_nfserr:
+	err = nfserrno(-err);
+	goto out;
 }
 
 /*
@@ -755,12 +757,14 @@
 		}
 	}
 	fh_compose(resfhp, fhp->fh_export, dnew);
-
-out_nfserr:
 	if (err)
-		err = nfserrno(-err);
+		goto out_nfserr;
 out:
 	return err;
+
+out_nfserr:
+	err = nfserrno(-err);
+	goto out;
 }
 
 /*
@@ -821,11 +825,14 @@
 	}
 dput_and_out:
 	dput(dnew);
-out_nfserr:
 	if (err)
-		err = nfserrno(-err);
+		goto out_nfserr;
 out:
 	return err;
+
+out_nfserr:
+	err = nfserrno(-err);
+	goto out;
 }
 
 /*
@@ -917,11 +924,14 @@
 
 out_dput_old:
 	dput(odentry);
-out_nfserr:
 	if (err)
-		err = nfserrno(-err);
+		goto out_nfserr;
 out:
 	return err;
+
+out_nfserr:
+	err = nfserrno(-err);
+	goto out;
 }
 
 /*
@@ -965,14 +975,16 @@
 	fh_unlock(fhp);
 
 	dput(rdentry);
-	if (!err && EX_ISSYNC(fhp->fh_export))
-		write_inode_now(dirp);
-
-out_nfserr:
 	if (err)
-		err = nfserrno(-err);
+		goto out_nfserr;
+	if (EX_ISSYNC(fhp->fh_export))
+		write_inode_now(dirp);
 out:
 	return err;
+
+out_nfserr:
+	err = nfserrno(-err);
+	goto out;
 }
 
 /*
@@ -982,22 +994,23 @@
 nfsd_readdir(struct svc_rqst *rqstp, struct svc_fh *fhp, loff_t offset, 
 			encode_dent_fn func, u32 *buffer, int *countp)
 {
-	struct readdir_cd cd;
 	struct inode	*inode;
-	struct file	file;
 	u32		*p;
 	int		oldlen, eof, err;
+	struct file	file;
+	struct readdir_cd cd;
 
+	err = 0;
 	if (offset > ~(u32) 0)
-		return 0;
+		goto out;
 
-	if ((err = nfsd_open(rqstp, fhp, S_IFDIR, OPEN_READ, &file)) != 0)
-		return err;
+	err = nfsd_open(rqstp, fhp, S_IFDIR, OPEN_READ, &file);
+	if (err)
+		goto out;
 
-	if (!file.f_op->readdir) {
-		nfsd_close(&file);
-		return nfserr_notdir;
-	}
+	err = nfserr_notdir;
+	if (!file.f_op->readdir)
+		goto out_close;
 	file.f_pos = offset;
 
 	/* Set up the readdir context */
@@ -1012,7 +1025,7 @@
 	 * may choose to do less.
 	 */
 	inode = file.f_dentry->d_inode;
-	do {
+	while (1) {
 		oldlen = cd.buflen;
 
 		/*
@@ -1020,16 +1033,16 @@
 			file.f_inode->i_dev, file.f_inode->i_ino,
 			(int) file.f_pos, (int) oldlen, (int) cd.buflen);
 		 */
-		err = file.f_op->readdir(&file,
-					 &cd, (filldir_t) func);
-
-		if (err < 0) {
-			nfsd_close(&file);
-			return nfserrno(-err);
-		}
+		down(&inode->i_sem);
+		err = file.f_op->readdir(&file, &cd, (filldir_t) func);
+		up(&inode->i_sem);
+		if (err < 0)
+			goto out_nfserr;
 		if (oldlen == cd.buflen)
 			break;
-	} while (oldlen != cd.buflen && !cd.eob);
+		if (cd.eob)
+			break;
+	}
 
 	/* If we didn't fill the buffer completely, we're at EOF */
 	eof = !cd.eob;
@@ -1040,9 +1053,6 @@
 	if (cd.offset && !eof)
 		*cd.offset = htonl(file.f_pos);
 
-	/* Close the file */
-	nfsd_close(&file);
-
 	p = cd.buffer;
 	*p++ = 0;			/* no more entries */
 	*p++ = htonl(eof);		/* end of directory */
@@ -1051,7 +1061,15 @@
 	dprintk("nfsd: readdir result %d bytes, eof %d offset %ld\n",
 				*countp, eof,
 				cd.offset? ntohl(*cd.offset) : -1);
-	return 0;
+	err = 0;
+out_close:
+	nfsd_close(&file);
+out:
+	return err;
+
+out_nfserr:
+	err = nfserrno(-err);
+	goto out_close;
 }
 
 /*

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov