Mon Sep 28 00:39:03 2009 UTC ()
Avoid nasal demons. Code of the form

   vput(vp);
   error = VFS_VGET(vp->v_mount, ...);

just isn't right. Because of vnode caching this *probably* never bit
anyone, except maybe under very heavy load, but still.


(dholland)
diff -r1.101 -r1.102 src/sys/ufs/ufs/ufs_lookup.c

cvs diff -r1.101 -r1.102 src/sys/ufs/ufs/ufs_lookup.c (expand / switch to unified diff)

--- src/sys/ufs/ufs/ufs_lookup.c 2009/02/22 20:28:07 1.101
+++ src/sys/ufs/ufs/ufs_lookup.c 2009/09/28 00:39:03 1.102
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: ufs_lookup.c,v 1.101 2009/02/22 20:28:07 ad Exp $ */ 1/* $NetBSD: ufs_lookup.c,v 1.102 2009/09/28 00:39:03 dholland Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1989, 1993 4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc. 6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed 7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph 8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc. 10 * the permission of UNIX System Laboratories, Inc.
11 * 11 *
12 * Redistribution and use in source and binary forms, with or without 12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions 13 * modification, are permitted provided that the following conditions
14 * are met: 14 * are met:
@@ -27,27 +27,27 @@ @@ -27,27 +27,27 @@
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE. 34 * SUCH DAMAGE.
35 * 35 *
36 * @(#)ufs_lookup.c 8.9 (Berkeley) 8/11/94 36 * @(#)ufs_lookup.c 8.9 (Berkeley) 8/11/94
37 */ 37 */
38 38
39#include <sys/cdefs.h> 39#include <sys/cdefs.h>
40__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.101 2009/02/22 20:28:07 ad Exp $"); 40__KERNEL_RCSID(0, "$NetBSD: ufs_lookup.c,v 1.102 2009/09/28 00:39:03 dholland Exp $");
41 41
42#ifdef _KERNEL_OPT 42#ifdef _KERNEL_OPT
43#include "opt_ffs.h" 43#include "opt_ffs.h"
44#include "fs_ffs.h" 44#include "fs_ffs.h"
45#endif 45#endif
46 46
47#include <sys/param.h> 47#include <sys/param.h>
48#include <sys/systm.h> 48#include <sys/systm.h>
49#include <sys/namei.h> 49#include <sys/namei.h>
50#include <sys/buf.h> 50#include <sys/buf.h>
51#include <sys/file.h> 51#include <sys/file.h>
52#include <sys/stat.h> 52#include <sys/stat.h>
53#include <sys/mount.h> 53#include <sys/mount.h>
@@ -1166,27 +1166,27 @@ ufs_dirempty(struct inode *ip, ino_t par @@ -1166,27 +1166,27 @@ ufs_dirempty(struct inode *ip, ino_t par
1166 return (0); 1166 return (0);
1167 } 1167 }
1168 return (1); 1168 return (1);
1169} 1169}
1170 1170
1171/* 1171/*
1172 * Check if source directory is in the path of the target directory. 1172 * Check if source directory is in the path of the target directory.
1173 * Target is supplied locked, source is unlocked. 1173 * Target is supplied locked, source is unlocked.
1174 * The target is always vput before returning. 1174 * The target is always vput before returning.
1175 */ 1175 */
1176int 1176int
1177ufs_checkpath(struct inode *source, struct inode *target, kauth_cred_t cred) 1177ufs_checkpath(struct inode *source, struct inode *target, kauth_cred_t cred)
1178{ 1178{
1179 struct vnode *vp = ITOV(target); 1179 struct vnode *nextvp, *vp;
1180 int error, rootino, namlen; 1180 int error, rootino, namlen;
1181 struct dirtemplate dirbuf; 1181 struct dirtemplate dirbuf;
1182 const int needswap = UFS_MPNEEDSWAP(target->i_ump); 1182 const int needswap = UFS_MPNEEDSWAP(target->i_ump);
1183 1183
1184 vp = ITOV(target); 1184 vp = ITOV(target);
1185 if (target->i_number == source->i_number) { 1185 if (target->i_number == source->i_number) {
1186 error = EEXIST; 1186 error = EEXIST;
1187 goto out; 1187 goto out;
1188 } 1188 }
1189 rootino = ROOTINO; 1189 rootino = ROOTINO;
1190 error = 0; 1190 error = 0;
1191 if (target->i_number == rootino) 1191 if (target->i_number == rootino)
1192 goto out; 1192 goto out;
@@ -1214,33 +1214,35 @@ ufs_checkpath(struct inode *source, stru @@ -1214,33 +1214,35 @@ ufs_checkpath(struct inode *source, stru
1214#endif 1214#endif
1215 if (namlen != 2 || 1215 if (namlen != 2 ||
1216 dirbuf.dotdot_name[0] != '.' || 1216 dirbuf.dotdot_name[0] != '.' ||
1217 dirbuf.dotdot_name[1] != '.') { 1217 dirbuf.dotdot_name[1] != '.') {
1218 error = ENOTDIR; 1218 error = ENOTDIR;
1219 break; 1219 break;
1220 } 1220 }
1221 if (ufs_rw32(dirbuf.dotdot_ino, needswap) == source->i_number) { 1221 if (ufs_rw32(dirbuf.dotdot_ino, needswap) == source->i_number) {
1222 error = EINVAL; 1222 error = EINVAL;
1223 break; 1223 break;
1224 } 1224 }
1225 if (ufs_rw32(dirbuf.dotdot_ino, needswap) == rootino) 1225 if (ufs_rw32(dirbuf.dotdot_ino, needswap) == rootino)
1226 break; 1226 break;
1227 vput(vp); 1227 VOP_UNLOCK(vp, 0);
1228 error = VFS_VGET(vp->v_mount, 1228 error = VFS_VGET(vp->v_mount,
1229 ufs_rw32(dirbuf.dotdot_ino, needswap), &vp); 1229 ufs_rw32(dirbuf.dotdot_ino, needswap), &nextvp);
 1230 vrele(vp);
1230 if (error) { 1231 if (error) {
1231 vp = NULL; 1232 vp = NULL;
1232 break; 1233 break;
1233 } 1234 }
 1235 vp = nextvp;
1234 } 1236 }
1235 1237
1236out: 1238out:
1237 if (error == ENOTDIR) 1239 if (error == ENOTDIR)
1238 printf("checkpath: .. not a directory\n"); 1240 printf("checkpath: .. not a directory\n");
1239 if (vp != NULL) 1241 if (vp != NULL)
1240 vput(vp); 1242 vput(vp);
1241 return (error); 1243 return (error);
1242} 1244}
1243 1245
1244#define UFS_DIRRABLKS 0 1246#define UFS_DIRRABLKS 0
1245int ufs_dirrablks = UFS_DIRRABLKS; 1247int ufs_dirrablks = UFS_DIRRABLKS;
1246 1248