svn commit: r224554 - head/sys/fs/nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Sun Jul 31 20:06:12 UTC 2011
Author: rmacklem
Date: Sun Jul 31 20:06:11 2011
New Revision: 224554
URL: http://svn.freebsd.org/changeset/base/224554
Log:
Fix rename in the new NFS server so that it does not require a
recursive vnode lock on the directory for the case where the
new file name is in the same directory as the old one. The patch
handles this as a special case, recognized by the new directory
having the same file handle as the old one and just VREF()s the old
dir vnode for this case, instead of doing a second VFS_FHTOVP() to get it.
This is required so that the server will work for file systems like
msdosfs, that do not support recursive vnode locking.
This problem was discovered during recent testing by pho@
when exporting an msdosfs file system via the new NFS server.
Tested by: pho
Reviewed by: zkirsch
Approved by: re (kib)
MFC after: 2 weeks
Modified:
head/sys/fs/nfsserver/nfs_nfsdserv.c
Modified: head/sys/fs/nfsserver/nfs_nfsdserv.c
==============================================================================
--- head/sys/fs/nfsserver/nfs_nfsdserv.c Sun Jul 31 18:34:38 2011 (r224553)
+++ head/sys/fs/nfsserver/nfs_nfsdserv.c Sun Jul 31 20:06:11 2011 (r224554)
@@ -1425,6 +1425,7 @@ nfsrvd_rename(struct nfsrv_descript *nd,
struct nfsrvfh tfh;
char *bufp, *tbufp = NULL;
u_long *hashp;
+ fhandle_t fh;
if (nd->nd_repstat) {
nfsrv_wcc(nd, fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
@@ -1450,19 +1451,34 @@ nfsrvd_rename(struct nfsrv_descript *nd,
tnes = *toexp;
tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred, p, 0);
} else {
+ tfh.nfsrvfh_len = 0;
error = nfsrv_mtofh(nd, &tfh);
+ if (error == 0)
+ error = nfsvno_getfh(dp, &fh, p);
if (error) {
vput(dp);
/* todp is always NULL except NFSv4 */
nfsvno_relpathbuf(&fromnd);
goto out;
}
- nd->nd_cred->cr_uid = nd->nd_saveduid;
- nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL, 0, p);
- if (tdp) {
+
+ /* If this is the same file handle, just VREF() the vnode. */
+ if (tfh.nfsrvfh_len == NFSX_MYFH &&
+ !NFSBCMP(tfh.nfsrvfh_data, &fh, NFSX_MYFH)) {
+ VREF(dp);
+ tdp = dp;
+ tnes = *exp;
tdirfor_ret = nfsvno_getattr(tdp, &tdirfor, nd->nd_cred,
p, 1);
- NFSVOPUNLOCK(tdp, 0);
+ } else {
+ nd->nd_cred->cr_uid = nd->nd_saveduid;
+ nfsd_fhtovp(nd, &tfh, LK_EXCLUSIVE, &tdp, &tnes, NULL,
+ 0, p);
+ if (tdp) {
+ tdirfor_ret = nfsvno_getattr(tdp, &tdirfor,
+ nd->nd_cred, p, 1);
+ NFSVOPUNLOCK(tdp, 0);
+ }
}
}
NFSNAMEICNDSET(&tond.ni_cnd, nd->nd_cred, RENAME, LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART);
More information about the svn-src-all
mailing list