Deleted Added
full compact
vfs_cache.c (227309) vfs_cache.c (227697)
1/*-
2 * Copyright (c) 1989, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Poul-Henning Kamp of the FreeBSD Project.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 19 unchanged lines hidden (view full) ---

28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * @(#)vfs_cache.c 8.5 (Berkeley) 3/22/95
33 */
34
35#include <sys/cdefs.h>
1/*-
2 * Copyright (c) 1989, 1993, 1995
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Poul-Henning Kamp of the FreeBSD Project.
7 *
8 * Redistribution and use in source and binary forms, with or without

--- 19 unchanged lines hidden (view full) ---

28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * @(#)vfs_cache.c 8.5 (Berkeley) 3/22/95
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/sys/kern/vfs_cache.c 227309 2011-11-07 15:43:11Z ed $");
36__FBSDID("$FreeBSD: head/sys/kern/vfs_cache.c 227697 2011-11-19 07:50:49Z kib $");
37
38#include "opt_kdtrace.h"
39#include "opt_ktrace.h"
40
41#include <sys/param.h>
42#include <sys/filedesc.h>
43#include <sys/fnv_hash.h>
44#include <sys/kernel.h>

--- 1018 unchanged lines hidden (view full) ---

1063
1064int
1065vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, u_int *buflen)
1066{
1067 int error;
1068
1069 CACHE_RLOCK();
1070 error = vn_vptocnp_locked(vp, cred, buf, buflen);
37
38#include "opt_kdtrace.h"
39#include "opt_ktrace.h"
40
41#include <sys/param.h>
42#include <sys/filedesc.h>
43#include <sys/fnv_hash.h>
44#include <sys/kernel.h>

--- 1018 unchanged lines hidden (view full) ---

1063
1064int
1065vn_vptocnp(struct vnode **vp, struct ucred *cred, char *buf, u_int *buflen)
1066{
1067 int error;
1068
1069 CACHE_RLOCK();
1070 error = vn_vptocnp_locked(vp, cred, buf, buflen);
1071 if (error == 0) {
1072 /*
1073 * vn_vptocnp_locked() dropped hold acquired by
1074 * VOP_VPTOCNP immediately after locking the
1075 * cache. Since we are going to drop the cache rlock,
1076 * re-hold the result.
1077 */
1078 vhold(*vp);
1071 if (error == 0)
1079 CACHE_RUNLOCK();
1072 CACHE_RUNLOCK();
1080 }
1081 return (error);
1082}
1083
1084static int
1085vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf,
1086 u_int *buflen)
1087{
1088 struct vnode *dvp;
1089 struct namecache *ncp;
1090 int error, vfslocked;
1091
1092 TAILQ_FOREACH(ncp, &((*vp)->v_cache_dst), nc_dst) {
1093 if ((ncp->nc_flag & NCF_ISDOTDOT) == 0)
1094 break;
1095 }
1096 if (ncp != NULL) {
1097 if (*buflen < ncp->nc_nlen) {
1098 CACHE_RUNLOCK();
1073 return (error);
1074}
1075
1076static int
1077vn_vptocnp_locked(struct vnode **vp, struct ucred *cred, char *buf,
1078 u_int *buflen)
1079{
1080 struct vnode *dvp;
1081 struct namecache *ncp;
1082 int error, vfslocked;
1083
1084 TAILQ_FOREACH(ncp, &((*vp)->v_cache_dst), nc_dst) {
1085 if ((ncp->nc_flag & NCF_ISDOTDOT) == 0)
1086 break;
1087 }
1088 if (ncp != NULL) {
1089 if (*buflen < ncp->nc_nlen) {
1090 CACHE_RUNLOCK();
1091 vfslocked = VFS_LOCK_GIANT((*vp)->v_mount);
1092 vrele(*vp);
1093 VFS_UNLOCK_GIANT(vfslocked);
1099 numfullpathfail4++;
1100 error = ENOMEM;
1101 SDT_PROBE(vfs, namecache, fullpath, return, error,
1102 vp, NULL, 0, 0);
1103 return (error);
1104 }
1105 *buflen -= ncp->nc_nlen;
1106 memcpy(buf + *buflen, ncp->nc_name, ncp->nc_nlen);
1107 SDT_PROBE(vfs, namecache, fullpath, hit, ncp->nc_dvp,
1108 ncp->nc_name, vp, 0, 0);
1094 numfullpathfail4++;
1095 error = ENOMEM;
1096 SDT_PROBE(vfs, namecache, fullpath, return, error,
1097 vp, NULL, 0, 0);
1098 return (error);
1099 }
1100 *buflen -= ncp->nc_nlen;
1101 memcpy(buf + *buflen, ncp->nc_name, ncp->nc_nlen);
1102 SDT_PROBE(vfs, namecache, fullpath, hit, ncp->nc_dvp,
1103 ncp->nc_name, vp, 0, 0);
1104 dvp = *vp;
1109 *vp = ncp->nc_dvp;
1105 *vp = ncp->nc_dvp;
1106 vref(*vp);
1107 CACHE_RUNLOCK();
1108 vfslocked = VFS_LOCK_GIANT(dvp->v_mount);
1109 vrele(dvp);
1110 VFS_UNLOCK_GIANT(vfslocked);
1111 CACHE_RLOCK();
1110 return (0);
1111 }
1112 SDT_PROBE(vfs, namecache, fullpath, miss, vp, 0, 0, 0, 0);
1113
1112 return (0);
1113 }
1114 SDT_PROBE(vfs, namecache, fullpath, miss, vp, 0, 0, 0, 0);
1115
1114 vhold(*vp);
1115 CACHE_RUNLOCK();
1116 vfslocked = VFS_LOCK_GIANT((*vp)->v_mount);
1117 vn_lock(*vp, LK_SHARED | LK_RETRY);
1118 error = VOP_VPTOCNP(*vp, &dvp, cred, buf, buflen);
1116 CACHE_RUNLOCK();
1117 vfslocked = VFS_LOCK_GIANT((*vp)->v_mount);
1118 vn_lock(*vp, LK_SHARED | LK_RETRY);
1119 error = VOP_VPTOCNP(*vp, &dvp, cred, buf, buflen);
1119 VOP_UNLOCK(*vp, 0);
1120 vdrop(*vp);
1120 vput(*vp);
1121 VFS_UNLOCK_GIANT(vfslocked);
1122 if (error) {
1123 numfullpathfail2++;
1124 SDT_PROBE(vfs, namecache, fullpath, return, error, vp,
1125 NULL, 0, 0);
1126 return (error);
1127 }
1128
1129 *vp = dvp;
1130 CACHE_RLOCK();
1121 VFS_UNLOCK_GIANT(vfslocked);
1122 if (error) {
1123 numfullpathfail2++;
1124 SDT_PROBE(vfs, namecache, fullpath, return, error, vp,
1125 NULL, 0, 0);
1126 return (error);
1127 }
1128
1129 *vp = dvp;
1130 CACHE_RLOCK();
1131 if ((*vp)->v_iflag & VI_DOOMED) {
1131 if (dvp->v_iflag & VI_DOOMED) {
1132 /* forced unmount */
1133 CACHE_RUNLOCK();
1132 /* forced unmount */
1133 CACHE_RUNLOCK();
1134 vdrop(*vp);
1134 vfslocked = VFS_LOCK_GIANT(dvp->v_mount);
1135 vrele(dvp);
1136 VFS_UNLOCK_GIANT(vfslocked);
1135 error = ENOENT;
1136 SDT_PROBE(vfs, namecache, fullpath, return, error, vp,
1137 NULL, 0, 0);
1138 return (error);
1139 }
1137 error = ENOENT;
1138 SDT_PROBE(vfs, namecache, fullpath, return, error, vp,
1139 NULL, 0, 0);
1140 return (error);
1141 }
1140 vdrop(*vp);
1142 /*
1143 * *vp has its use count incremented still.
1144 */
1141
1142 return (0);
1143}
1144
1145/*
1146 * The magic behind kern___getcwd() and vn_fullpath().
1147 */
1148static int
1149vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
1150 char *buf, char **retbuf, u_int buflen)
1151{
1145
1146 return (0);
1147}
1148
1149/*
1150 * The magic behind kern___getcwd() and vn_fullpath().
1151 */
1152static int
1153vn_fullpath1(struct thread *td, struct vnode *vp, struct vnode *rdir,
1154 char *buf, char **retbuf, u_int buflen)
1155{
1152 int error, slash_prefixed;
1156 int error, slash_prefixed, vfslocked;
1153#ifdef KDTRACE_HOOKS
1154 struct vnode *startvp = vp;
1155#endif
1157#ifdef KDTRACE_HOOKS
1158 struct vnode *startvp = vp;
1159#endif
1160 struct vnode *vp1;
1156
1157 buflen--;
1158 buf[buflen] = '\0';
1159 error = 0;
1160 slash_prefixed = 0;
1161
1162 SDT_PROBE(vfs, namecache, fullpath, entry, vp, 0, 0, 0, 0);
1163 numfullpathcalls++;
1161
1162 buflen--;
1163 buf[buflen] = '\0';
1164 error = 0;
1165 slash_prefixed = 0;
1166
1167 SDT_PROBE(vfs, namecache, fullpath, entry, vp, 0, 0, 0, 0);
1168 numfullpathcalls++;
1169 vref(vp);
1164 CACHE_RLOCK();
1165 if (vp->v_type != VDIR) {
1166 error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen);
1167 if (error)
1168 return (error);
1169 if (buflen == 0) {
1170 CACHE_RUNLOCK();
1170 CACHE_RLOCK();
1171 if (vp->v_type != VDIR) {
1172 error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen);
1173 if (error)
1174 return (error);
1175 if (buflen == 0) {
1176 CACHE_RUNLOCK();
1177 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1178 vrele(vp);
1179 VFS_UNLOCK_GIANT(vfslocked);
1171 return (ENOMEM);
1172 }
1173 buf[--buflen] = '/';
1174 slash_prefixed = 1;
1175 }
1176 while (vp != rdir && vp != rootvnode) {
1177 if (vp->v_vflag & VV_ROOT) {
1178 if (vp->v_iflag & VI_DOOMED) { /* forced unmount */
1179 CACHE_RUNLOCK();
1180 return (ENOMEM);
1181 }
1182 buf[--buflen] = '/';
1183 slash_prefixed = 1;
1184 }
1185 while (vp != rdir && vp != rootvnode) {
1186 if (vp->v_vflag & VV_ROOT) {
1187 if (vp->v_iflag & VI_DOOMED) { /* forced unmount */
1188 CACHE_RUNLOCK();
1189 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1190 vrele(vp);
1191 VFS_UNLOCK_GIANT(vfslocked);
1180 error = ENOENT;
1181 SDT_PROBE(vfs, namecache, fullpath, return,
1182 error, vp, NULL, 0, 0);
1183 break;
1184 }
1192 error = ENOENT;
1193 SDT_PROBE(vfs, namecache, fullpath, return,
1194 error, vp, NULL, 0, 0);
1195 break;
1196 }
1185 vp = vp->v_mount->mnt_vnodecovered;
1197 vp1 = vp->v_mount->mnt_vnodecovered;
1198 vref(vp1);
1199 CACHE_RUNLOCK();
1200 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1201 vrele(vp);
1202 VFS_UNLOCK_GIANT(vfslocked);
1203 vp = vp1;
1204 CACHE_RLOCK();
1186 continue;
1187 }
1188 if (vp->v_type != VDIR) {
1189 CACHE_RUNLOCK();
1205 continue;
1206 }
1207 if (vp->v_type != VDIR) {
1208 CACHE_RUNLOCK();
1209 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1210 vrele(vp);
1211 VFS_UNLOCK_GIANT(vfslocked);
1190 numfullpathfail1++;
1191 error = ENOTDIR;
1192 SDT_PROBE(vfs, namecache, fullpath, return,
1193 error, vp, NULL, 0, 0);
1194 break;
1195 }
1196 error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen);
1197 if (error)
1198 break;
1199 if (buflen == 0) {
1200 CACHE_RUNLOCK();
1212 numfullpathfail1++;
1213 error = ENOTDIR;
1214 SDT_PROBE(vfs, namecache, fullpath, return,
1215 error, vp, NULL, 0, 0);
1216 break;
1217 }
1218 error = vn_vptocnp_locked(&vp, td->td_ucred, buf, &buflen);
1219 if (error)
1220 break;
1221 if (buflen == 0) {
1222 CACHE_RUNLOCK();
1223 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1224 vrele(vp);
1225 VFS_UNLOCK_GIANT(vfslocked);
1201 error = ENOMEM;
1202 SDT_PROBE(vfs, namecache, fullpath, return, error,
1203 startvp, NULL, 0, 0);
1204 break;
1205 }
1206 buf[--buflen] = '/';
1207 slash_prefixed = 1;
1208 }
1209 if (error)
1210 return (error);
1211 if (!slash_prefixed) {
1212 if (buflen == 0) {
1213 CACHE_RUNLOCK();
1226 error = ENOMEM;
1227 SDT_PROBE(vfs, namecache, fullpath, return, error,
1228 startvp, NULL, 0, 0);
1229 break;
1230 }
1231 buf[--buflen] = '/';
1232 slash_prefixed = 1;
1233 }
1234 if (error)
1235 return (error);
1236 if (!slash_prefixed) {
1237 if (buflen == 0) {
1238 CACHE_RUNLOCK();
1239 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1240 vrele(vp);
1241 VFS_UNLOCK_GIANT(vfslocked);
1214 numfullpathfail4++;
1215 SDT_PROBE(vfs, namecache, fullpath, return, ENOMEM,
1216 startvp, NULL, 0, 0);
1217 return (ENOMEM);
1218 }
1219 buf[--buflen] = '/';
1220 }
1221 numfullpathfound++;
1222 CACHE_RUNLOCK();
1242 numfullpathfail4++;
1243 SDT_PROBE(vfs, namecache, fullpath, return, ENOMEM,
1244 startvp, NULL, 0, 0);
1245 return (ENOMEM);
1246 }
1247 buf[--buflen] = '/';
1248 }
1249 numfullpathfound++;
1250 CACHE_RUNLOCK();
1251 vfslocked = VFS_LOCK_GIANT(vp->v_mount);
1252 vrele(vp);
1253 VFS_UNLOCK_GIANT(vfslocked);
1223
1224 SDT_PROBE(vfs, namecache, fullpath, return, 0, startvp, buf + buflen,
1225 0, 0);
1226 *retbuf = buf + buflen;
1227 return (0);
1228}
1229
1230int

--- 19 unchanged lines hidden ---
1254
1255 SDT_PROBE(vfs, namecache, fullpath, return, 0, startvp, buf + buflen,
1256 0, 0);
1257 *retbuf = buf + buflen;
1258 return (0);
1259}
1260
1261int

--- 19 unchanged lines hidden ---