NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: kern/42348
The following reply was made to PR kern/42348; it has been noted by GNATS.
From: Antti Kantee <pooka%cs.hut.fi@localhost>
To: dholland%netbsd.org@localhost
Cc: gnats-bugs%netbsd.org@localhost
Subject: Re: kern/42348
Date: Thu, 19 Nov 2009 21:13:49 +0200
I think this should do the trick (lightly tested, i.e. i'm running the
patch on my desktop now). I consider the path buffer to be owned by the
namei caller in cases relating to SAVESTART. VOP_ABORTOP on the other
hand clears file system status. So we can relookup with SAVESTART as
long as we release the extra reference. The only question is if the file
system is allowed to damage componentname in abortop so it couldn't be
used for relookup. It's a gray area, but I don't think it's any more gray
than the subject in general. Maybe we can NDINIT it again to be sure?
The only thing I can't remember is why SAVESTART was originally handled
like this for rename relookup. I remember we discussed it, but I can't
remember why.
(nfsd also needs a similar adjustment if this is deemed a sensible approach)
Index: vfs_syscalls.c
===================================================================
RCS file: /cvsroot/src/sys/kern/vfs_syscalls.c,v
retrieving revision 1.376.4.3
diff -p -u -r1.376.4.3 vfs_syscalls.c
--- vfs_syscalls.c 1 Jul 2009 22:47:05 -0000 1.376.4.3
+++ vfs_syscalls.c 19 Nov 2009 19:04:12 -0000
@@ -3314,13 +3314,14 @@ do_sys_rename(const char *from, const ch
struct mount *fs;
struct lwp *l = curlwp;
struct proc *p;
- uint32_t saveflag;
int error;
NDINIT(&fromnd, DELETE, LOCKPARENT | SAVESTART | TRYEMULROOT,
seg, from);
if ((error = namei(&fromnd)) != 0)
return (error);
+ VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
+
if (fromnd.ni_dvp != fromnd.ni_vp)
VOP_UNLOCK(fromnd.ni_dvp, 0);
fvp = fromnd.ni_vp;
@@ -3328,7 +3329,6 @@ do_sys_rename(const char *from, const ch
fs = fvp->v_mount;
error = VFS_RENAMELOCK_ENTER(fs);
if (error) {
- VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
vrele(fromnd.ni_dvp);
vrele(fvp);
goto out1;
@@ -3359,30 +3359,26 @@ do_sys_rename(const char *from, const ch
fromnd.ni_cnd.cn_nameptr[1] == '.')) {
error = EINVAL;
VFS_RENAMELOCK_EXIT(fs);
- VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
vrele(fromnd.ni_dvp);
goto out1;
}
- saveflag = fromnd.ni_cnd.cn_flags & SAVESTART;
- fromnd.ni_cnd.cn_flags &= ~SAVESTART;
vn_lock(fromnd.ni_dvp, LK_EXCLUSIVE | LK_RETRY);
error = relookup(fromnd.ni_dvp, &fromnd.ni_vp, &fromnd.ni_cnd);
- fromnd.ni_cnd.cn_flags |= saveflag;
if (error) {
VOP_UNLOCK(fromnd.ni_dvp, 0);
VFS_RENAMELOCK_EXIT(fs);
- VOP_ABORTOP(fromnd.ni_dvp, &fromnd.ni_cnd);
vrele(fromnd.ni_dvp);
goto out1;
}
VOP_UNLOCK(fromnd.ni_vp, 0);
if (fromnd.ni_dvp != fromnd.ni_vp)
VOP_UNLOCK(fromnd.ni_dvp, 0);
+ vrele(fromnd.ni_dvp); /* from relookup with SAVESTART */
fvp = fromnd.ni_vp;
NDINIT(&tond, RENAME,
LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | TRYEMULROOT
Home |
Main Index |
Thread Index |
Old Index