Deleted Added
sdiff udiff text old ( 227543 ) new ( 230394 )
full compact
1/*-
2 * Copyright (c) 1989, 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Rick Macklem at The University of Guelph.
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 * from nfs_vnops.c 8.16 (Berkeley) 5/27/95
33 */
34
35#include <sys/cdefs.h>
36__FBSDID("$FreeBSD: head/sys/fs/nfsclient/nfs_clvnops.c 230394 2012-01-20 20:02:01Z jhb $");
37
38/*
39 * vnode op calls for Sun NFS version 2, 3 and 4
40 */
41
42#include "opt_kdtrace.h"
43#include "opt_inet.h"
44

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

1011 struct componentname *cnp = ap->a_cnp;
1012 struct vnode *dvp = ap->a_dvp;
1013 struct vnode **vpp = ap->a_vpp;
1014 struct mount *mp = dvp->v_mount;
1015 int flags = cnp->cn_flags;
1016 struct vnode *newvp;
1017 struct nfsmount *nmp;
1018 struct nfsnode *np, *newnp;
1019 int error = 0, attrflag, dattrflag, ltype, ncticks;
1020 struct thread *td = cnp->cn_thread;
1021 struct nfsfh *nfhp;
1022 struct nfsvattr dnfsva, nfsva;
1023 struct vattr vattr;
1024 struct timespec nctime;
1025
1026 *vpp = NULLVP;
1027 if ((flags & ISLASTCN) && (mp->mnt_flag & MNT_RDONLY) &&
1028 (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
1029 return (EROFS);
1030 if (dvp->v_type != VDIR)
1031 return (ENOTDIR);
1032 nmp = VFSTONFS(mp);

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

1037 while (NFSHASNFSV4(nmp) && (np->n_flag & NREMOVEINPROG)) {
1038 np->n_flag |= NREMOVEWANT;
1039 (void) msleep((caddr_t)np, &np->n_mtx, PZERO, "nfslkup", 0);
1040 }
1041 mtx_unlock(&np->n_mtx);
1042
1043 if ((error = VOP_ACCESS(dvp, VEXEC, cnp->cn_cred, td)) != 0)
1044 return (error);
1045 error = cache_lookup_times(dvp, vpp, cnp, &nctime, &ncticks);
1046 if (error > 0 && error != ENOENT)
1047 return (error);
1048 if (error == -1) {
1049 /*
1050 * Lookups of "." are special and always return the
1051 * current directory. cache_lookup() already handles
1052 * associated locking bookkeeping, etc.
1053 */
1054 if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.') {
1055 /* XXX: Is this really correct? */
1056 if (cnp->cn_nameiop != LOOKUP &&
1057 (flags & ISLASTCN))
1058 cnp->cn_flags |= SAVENAME;
1059 return (0);
1060 }
1061
1062 /*
1063 * We only accept a positive hit in the cache if the
1064 * change time of the file matches our cached copy.
1065 * Otherwise, we discard the cache entry and fallback
1066 * to doing a lookup RPC.
1067 *
1068 * To better handle stale file handles and attributes,
1069 * clear the attribute cache of this node if it is a
1070 * leaf component, part of an open() call, and not

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

1081 !(newnp->n_flag & NMODIFIED)) {
1082 mtx_lock(&newnp->n_mtx);
1083 newnp->n_attrstamp = 0;
1084 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(newvp);
1085 mtx_unlock(&newnp->n_mtx);
1086 }
1087 if (nfscl_nodeleg(newvp, 0) == 0 ||
1088 (VOP_GETATTR(newvp, &vattr, cnp->cn_cred) == 0 &&
1089 timespeccmp(&vattr.va_ctime, &nctime, ==))) {
1090 NFSINCRGLOBAL(newnfsstats.lookupcache_hits);
1091 if (cnp->cn_nameiop != LOOKUP &&
1092 (flags & ISLASTCN))
1093 cnp->cn_flags |= SAVENAME;
1094 return (0);
1095 }
1096 cache_purge(newvp);
1097 if (dvp != newvp)
1098 vput(newvp);
1099 else
1100 vrele(newvp);
1101 *vpp = NULLVP;
1102 } else if (error == ENOENT) {
1103 if (dvp->v_iflag & VI_DOOMED)
1104 return (ENOENT);
1105 /*
1106 * We only accept a negative hit in the cache if the
1107 * modification time of the parent directory matches
1108 * the cached copy in the name cache entry.
1109 * Otherwise, we discard all of the negative cache
1110 * entries for this directory. We also only trust
1111 * negative cache entries for up to nm_negnametimeo
1112 * seconds.
1113 */
1114 if ((u_int)(ticks - ncticks) < (nmp->nm_negnametimeo * hz) &&
1115 VOP_GETATTR(dvp, &vattr, cnp->cn_cred) == 0 &&
1116 timespeccmp(&vattr.va_mtime, &nctime, ==)) {
1117 NFSINCRGLOBAL(newnfsstats.lookupcache_hits);
1118 return (ENOENT);
1119 }
1120 cache_purge_negative(dvp);
1121 }
1122
1123 error = 0;
1124 newvp = NULLVP;
1125 NFSINCRGLOBAL(newnfsstats.lookupcache_misses);
1126 error = nfsrpc_lookup(dvp, cnp->cn_nameptr, cnp->cn_namelen,
1127 cnp->cn_cred, td, &dnfsva, &nfsva, &nfhp, &attrflag, &dattrflag,
1128 NULL);
1129 if (dattrflag)
1130 (void) nfscl_loadattrcache(&dvp, &dnfsva, NULL, NULL, 0, 1);

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

1150 * MNT_RDONLY.
1151 */
1152 if (mp->mnt_flag & MNT_RDONLY)
1153 return (EROFS);
1154 cnp->cn_flags |= SAVENAME;
1155 return (EJUSTRETURN);
1156 }
1157
1158 if ((cnp->cn_flags & MAKEENTRY) && cnp->cn_nameiop != CREATE &&
1159 dattrflag) {
1160 /*
1161 * Cache the modification time of the parent
1162 * directory from the post-op attributes in
1163 * the name cache entry. The negative cache
1164 * entry will be ignored once the directory
1165 * has changed. Don't bother adding the entry
1166 * if the directory has already changed.
1167 */
1168 mtx_lock(&np->n_mtx);
1169 if (timespeccmp(&np->n_vattr.na_mtime,
1170 &dnfsva.na_mtime, ==)) {
1171 mtx_unlock(&np->n_mtx);
1172 cache_enter_time(dvp, NULL, cnp,
1173 &dnfsva.na_mtime);
1174 } else
1175 mtx_unlock(&np->n_mtx);
1176 }
1177 return (ENOENT);
1178 }
1179
1180 /*
1181 * Handle RENAME case...

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

1264 np->n_attrstamp = 0;
1265 KDTRACE_NFS_ATTRCACHE_FLUSH_DONE(newvp);
1266 mtx_unlock(&np->n_mtx);
1267 }
1268 }
1269 if (cnp->cn_nameiop != LOOKUP && (flags & ISLASTCN))
1270 cnp->cn_flags |= SAVENAME;
1271 if ((cnp->cn_flags & MAKEENTRY) &&
1272 (cnp->cn_nameiop != DELETE || !(flags & ISLASTCN)) && attrflag) {
1273 cache_enter_time(dvp, newvp, cnp, &nfsva.na_ctime);
1274 }
1275 *vpp = newvp;
1276 return (0);
1277}
1278
1279/*
1280 * nfs read call.
1281 * Just call ncl_bioread() to do the work.

--- 2185 unchanged lines hidden ---