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 --- |