1 /* $FreeBSD: releng/6.0/sys/nfs4client/nfs4_vn_subs.c 139823 2005-01-07 01:45:51Z imp $ */
2 /* $Id: nfs4_vn_subs.c,v 1.9 2003/11/05 14:59:00 rees Exp $ */
3
4 /*-
5 * copyright (c) 2003
6 * the regents of the university of michigan
7 * all rights reserved
8 *
9 * permission is granted to use, copy, create derivative works and redistribute
10 * this software and such derivative works for any purpose, so long as the name
11 * of the university of michigan is not used in any advertising or publicity
12 * pertaining to the use or distribution of this software without specific,
13 * written prior authorization. if the above copyright notice or any other
14 * identification of the university of michigan is included in any copy of any
15 * portion of this software, then the disclaimer below must also be included.
16 *
17 * this software is provided as is, without representation from the university
18 * of michigan as to its fitness for any purpose, and without warranty by the
19 * university of michigan of any kind, either express or implied, including
20 * without limitation the implied warranties of merchantability and fitness for
21 * a particular purpose. the regents of the university of michigan shall not be
22 * liable for any damages, including special, indirect, incidental, or
23 * consequential damages, with respect to any claim arising out of or in
24 * connection with the use of the software, even if it has been or is hereafter
25 * advised of the possibility of such damages.
26 */
27
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/kernel.h>
31 #include <sys/limits.h>
32 #include <sys/lock.h>
33 #include <sys/malloc.h>
34 #include <sys/mbuf.h>
35 #include <sys/module.h>
36 #include <sys/mount.h>
37 #include <sys/proc.h>
38 #include <sys/socket.h>
39 #include <sys/socketvar.h>
40 #include <sys/sockio.h>
41 #include <sys/vnode.h>
42 #include <sys/types.h>
43
44 #include <vm/vm.h>
45 #include <vm/vm_extern.h>
46 #include <vm/uma.h>
47
48 #include <net/if.h>
49 #include <net/route.h>
50 #include <netinet/in.h>
51
52 #include <rpc/rpcclnt.h>
53
54 #include <nfs/rpcv2.h>
55 #include <nfs/nfsproto.h>
56 #include <nfsclient/nfs.h>
57 #include <nfsclient/nfsmount.h>
58 #include <nfs/xdr_subs.h>
59 #include <nfsclient/nfsm_subs.h>
60 #include <nfsclient/nfsdiskless.h>
61
62 /* NFSv4 */
63 #include <nfs4client/nfs4.h>
64 #include <nfs4client/nfs4m_subs.h>
65 #include <nfs4client/nfs4_vn.h>
66
67 #include <nfsclient/nfsnode.h>
68
69 void
70 nfs4_vnop_loadattrcache(struct vnode *vp, struct nfsv4_fattr *fap,
71 struct vattr *vaper)
72 {
73 struct vattr *vap;
74 struct nfsnode *np;
75 int32_t rdev;
76 enum vtype vtyp;
77 u_short vmode;
78 struct timespec mtime;
79 struct timeval tv;
80
81 microtime(&tv);
82
83 vtyp = nv3tov_type[fap->fa4_type & 0x7];
84 vmode = (fap->fa4_valid & FA4V_MODE) ? fap->fa4_mode : 0777;
85 rdev = (fap->fa4_valid & FA4V_RDEV) ?
86 makedev(fap->fa4_rdev_major, fap->fa4_rdev_minor) : 0;
87 if (fap->fa4_valid & FA4V_MTIME)
88 mtime = fap->fa4_mtime;
89 else
90 bzero(&mtime, sizeof mtime);
91
92 /*
93 * If v_type == VNON it is a new node, so fill in the v_type,
94 * n_mtime fields. Check to see if it represents a special
95 * device, and if so, check for a possible alias. Once the
96 * correct vnode has been obtained, fill in the rest of the
97 * information.
98 */
99 np = VTONFS(vp);
100 vap = &np->n_vattr;
101 if (vp->v_type != vtyp || np->n_mtime.tv_sec == 0) {
102 bzero(vap, sizeof *vap);
103 vp->v_type = vtyp;
104 np->n_mtime.tv_sec = mtime.tv_sec;
105 }
106 vap->va_type = vtyp;
107 vap->va_mode = (vmode & 07777);
108 vap->va_rdev = rdev;
109 vap->va_mtime = mtime;
110 vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
111 if (fap->fa4_valid & FA4V_NLINK)
112 vap->va_nlink = fap->fa4_nlink;
113 if (fap->fa4_valid & FA4V_UID)
114 vap->va_uid = fap->fa4_uid;
115 if (fap->fa4_valid & FA4V_GID)
116 vap->va_gid = fap->fa4_gid;
117 vap->va_size = fap->fa4_size;
118 vap->va_blocksize = NFS_FABLKSIZE;
119 vap->va_bytes = fap->fa4_size;
120 if (fap->fa4_valid & FA4V_FILEID)
121 vap->va_fileid = nfs_v4fileid4_to_fileid(fap->fa4_fileid);
122 if (fap->fa4_valid & FA4V_ATIME)
123 vap->va_atime = fap->fa4_atime;
124 if (fap->fa4_valid & FA4V_CTIME)
125 vap->va_ctime = fap->fa4_ctime;
126 vap->va_flags = 0;
127 vap->va_filerev = 0;
128 /* XXX dontshrink flag? */
129 if (vap->va_size != np->n_size) {
130 if (vap->va_type == VREG) {
131 if (np->n_flag & NMODIFIED) {
132 if (vap->va_size < np->n_size)
133 vap->va_size = np->n_size;
134 else
135 np->n_size = vap->va_size;
136 } else
137 np->n_size = vap->va_size;
138 vnode_pager_setsize(vp, np->n_size);
139 } else
140 np->n_size = vap->va_size;
141 }
142 np->n_attrstamp = tv.tv_sec;
143 if (vaper != NULL) {
144 bcopy((caddr_t)vap, (caddr_t)vaper, sizeof(*vap));
145 if (np->n_flag & NCHG) {
146 if (np->n_flag & NACC)
147 vaper->va_atime = np->n_atim;
148 if (np->n_flag & NUPD)
149 vaper->va_mtime = np->n_mtim;
150 }
151 }
152 }
153
154 static uint64_t nfs_nullcookie = 0;
155 /*
156 * This function finds the directory cookie that corresponds to the
157 * logical byte offset given.
158 */
159 uint64_t *
160 nfs4_getcookie(struct nfsnode *np, off_t off, int add)
161 {
162 struct nfsdmap *dp, *dp2;
163 int pos;
164
165 pos = (uoff_t)off / NFS_DIRBLKSIZ;
166 if (pos == 0 || off < 0) {
167 #ifdef DIAGNOSTIC
168 if (add)
169 panic("nfs getcookie add at <= 0");
170 #endif
171 return (&nfs_nullcookie);
172 }
173 pos--;
174 dp = LIST_FIRST(&np->n_cookies);
175 if (!dp) {
176 if (add) {
177 MALLOC(dp, struct nfsdmap *, sizeof (struct nfsdmap),
178 M_NFSDIROFF, M_WAITOK);
179 dp->ndm_eocookie = 0;
180 LIST_INSERT_HEAD(&np->n_cookies, dp, ndm_list);
181 } else
182 return (NULL);
183 }
184 while (pos >= NFSNUMCOOKIES) {
185 pos -= NFSNUMCOOKIES;
186 if (LIST_NEXT(dp, ndm_list)) {
187 if (!add && dp->ndm_eocookie < NFSNUMCOOKIES &&
188 pos >= dp->ndm_eocookie)
189 return (NULL);
190 dp = LIST_NEXT(dp, ndm_list);
191 } else if (add) {
192 MALLOC(dp2, struct nfsdmap *, sizeof (struct nfsdmap),
193 M_NFSDIROFF, M_WAITOK);
194 dp2->ndm_eocookie = 0;
195 LIST_INSERT_AFTER(dp, dp2, ndm_list);
196 dp = dp2;
197 } else
198 return (NULL);
199 }
200 if (pos >= dp->ndm_eocookie) {
201 if (add)
202 dp->ndm_eocookie = pos + 1;
203 else
204 return (NULL);
205 }
206 return (&dp->ndm4_cookies[pos]);
207 }
208
209 /*
210 * Invalidate cached directory information, except for the actual directory
211 * blocks (which are invalidated separately).
212 * Done mainly to avoid the use of stale offset cookies.
213 */
214 void
215 nfs4_invaldir(struct vnode *vp)
216 {
217 struct nfsnode *np = VTONFS(vp);
218
219 np->n_direofoffset = 0;
220 bzero(np->n4_cookieverf, NFSX_V4VERF);
221 if (LIST_FIRST(&np->n_cookies))
222 LIST_FIRST(&np->n_cookies)->ndm_eocookie = 0;
223 }
Cache object: 091fdde058b5da3f3ea159c2e832dc45
|