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
This commit is contained in:
parent
67ad01694a
commit
6b3dfc6ab0
@ -1425,6 +1425,7 @@ nfsrvd_rename(struct nfsrv_descript *nd, int isdgram,
|
||||
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, int isdgram,
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user