1 /* $NetBSD: nfs_vnops.c,v 1.281 2009/10/21 21:12:06 rmind Exp $ */
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * This code is derived from software contributed to Berkeley by
8 * Rick Macklem at The University of Guelph.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * @(#)nfs_vnops.c 8.19 (Berkeley) 7/31/95
38 * vnode op calls for Sun NFS version 2 and 3
41 #include <sys/cdefs.h>
42 __KERNEL_RCSID(0, "$NetBSD: nfs_vnops.c,v 1.281 2009/10/21 21:12:06 rmind Exp $");
46 #include "opt_uvmhist.h"
49 #include <sys/param.h>
51 #include <sys/kernel.h>
52 #include <sys/systm.h>
53 #include <sys/resourcevar.h>
54 #include <sys/mount.h>
56 #include <sys/condvar.h>
58 #include <sys/malloc.h>
61 #include <sys/mutex.h>
62 #include <sys/namei.h>
63 #include <sys/vnode.h>
64 #include <sys/dirent.h>
65 #include <sys/fcntl.h>
67 #include <sys/lockf.h>
69 #include <sys/unistd.h>
70 #include <sys/kauth.h>
72 #include <uvm/uvm_extern.h>
75 #include <miscfs/fifofs/fifo.h>
76 #include <miscfs/genfs/genfs.h>
77 #include <miscfs/genfs/genfs_node.h>
78 #include <miscfs/specfs/specdev.h>
80 #include <nfs/rpcv2.h>
81 #include <nfs/nfsproto.h>
83 #include <nfs/nfsnode.h>
84 #include <nfs/nfsmount.h>
85 #include <nfs/xdr_subs.h>
86 #include <nfs/nfsm_subs.h>
87 #include <nfs/nfs_var.h>
90 #include <netinet/in.h>
91 #include <netinet/in_var.h>
94 * Global vfs data structures for nfs
96 int (**nfsv2_vnodeop_p
)(void *);
97 const struct vnodeopv_entry_desc nfsv2_vnodeop_entries
[] = {
98 { &vop_default_desc
, vn_default_error
},
99 { &vop_lookup_desc
, nfs_lookup
}, /* lookup */
100 { &vop_create_desc
, nfs_create
}, /* create */
101 { &vop_mknod_desc
, nfs_mknod
}, /* mknod */
102 { &vop_open_desc
, nfs_open
}, /* open */
103 { &vop_close_desc
, nfs_close
}, /* close */
104 { &vop_access_desc
, nfs_access
}, /* access */
105 { &vop_getattr_desc
, nfs_getattr
}, /* getattr */
106 { &vop_setattr_desc
, nfs_setattr
}, /* setattr */
107 { &vop_read_desc
, nfs_read
}, /* read */
108 { &vop_write_desc
, nfs_write
}, /* write */
109 { &vop_fcntl_desc
, genfs_fcntl
}, /* fcntl */
110 { &vop_ioctl_desc
, nfs_ioctl
}, /* ioctl */
111 { &vop_poll_desc
, nfs_poll
}, /* poll */
112 { &vop_kqfilter_desc
, nfs_kqfilter
}, /* kqfilter */
113 { &vop_revoke_desc
, nfs_revoke
}, /* revoke */
114 { &vop_mmap_desc
, nfs_mmap
}, /* mmap */
115 { &vop_fsync_desc
, nfs_fsync
}, /* fsync */
116 { &vop_seek_desc
, nfs_seek
}, /* seek */
117 { &vop_remove_desc
, nfs_remove
}, /* remove */
118 { &vop_link_desc
, nfs_link
}, /* link */
119 { &vop_rename_desc
, nfs_rename
}, /* rename */
120 { &vop_mkdir_desc
, nfs_mkdir
}, /* mkdir */
121 { &vop_rmdir_desc
, nfs_rmdir
}, /* rmdir */
122 { &vop_symlink_desc
, nfs_symlink
}, /* symlink */
123 { &vop_readdir_desc
, nfs_readdir
}, /* readdir */
124 { &vop_readlink_desc
, nfs_readlink
}, /* readlink */
125 { &vop_abortop_desc
, nfs_abortop
}, /* abortop */
126 { &vop_inactive_desc
, nfs_inactive
}, /* inactive */
127 { &vop_reclaim_desc
, nfs_reclaim
}, /* reclaim */
128 { &vop_lock_desc
, nfs_lock
}, /* lock */
129 { &vop_unlock_desc
, nfs_unlock
}, /* unlock */
130 { &vop_bmap_desc
, nfs_bmap
}, /* bmap */
131 { &vop_strategy_desc
, nfs_strategy
}, /* strategy */
132 { &vop_print_desc
, nfs_print
}, /* print */
133 { &vop_islocked_desc
, nfs_islocked
}, /* islocked */
134 { &vop_pathconf_desc
, nfs_pathconf
}, /* pathconf */
135 { &vop_advlock_desc
, nfs_advlock
}, /* advlock */
136 { &vop_bwrite_desc
, genfs_badop
}, /* bwrite */
137 { &vop_getpages_desc
, nfs_getpages
}, /* getpages */
138 { &vop_putpages_desc
, genfs_putpages
}, /* putpages */
141 const struct vnodeopv_desc nfsv2_vnodeop_opv_desc
=
142 { &nfsv2_vnodeop_p
, nfsv2_vnodeop_entries
};
145 * Special device vnode ops
147 int (**spec_nfsv2nodeop_p
)(void *);
148 const struct vnodeopv_entry_desc spec_nfsv2nodeop_entries
[] = {
149 { &vop_default_desc
, vn_default_error
},
150 { &vop_lookup_desc
, spec_lookup
}, /* lookup */
151 { &vop_create_desc
, spec_create
}, /* create */
152 { &vop_mknod_desc
, spec_mknod
}, /* mknod */
153 { &vop_open_desc
, spec_open
}, /* open */
154 { &vop_close_desc
, nfsspec_close
}, /* close */
155 { &vop_access_desc
, nfsspec_access
}, /* access */
156 { &vop_getattr_desc
, nfs_getattr
}, /* getattr */
157 { &vop_setattr_desc
, nfs_setattr
}, /* setattr */
158 { &vop_read_desc
, nfsspec_read
}, /* read */
159 { &vop_write_desc
, nfsspec_write
}, /* write */
160 { &vop_fcntl_desc
, genfs_fcntl
}, /* fcntl */
161 { &vop_ioctl_desc
, spec_ioctl
}, /* ioctl */
162 { &vop_poll_desc
, spec_poll
}, /* poll */
163 { &vop_kqfilter_desc
, spec_kqfilter
}, /* kqfilter */
164 { &vop_revoke_desc
, spec_revoke
}, /* revoke */
165 { &vop_mmap_desc
, spec_mmap
}, /* mmap */
166 { &vop_fsync_desc
, spec_fsync
}, /* fsync */
167 { &vop_seek_desc
, spec_seek
}, /* seek */
168 { &vop_remove_desc
, spec_remove
}, /* remove */
169 { &vop_link_desc
, spec_link
}, /* link */
170 { &vop_rename_desc
, spec_rename
}, /* rename */
171 { &vop_mkdir_desc
, spec_mkdir
}, /* mkdir */
172 { &vop_rmdir_desc
, spec_rmdir
}, /* rmdir */
173 { &vop_symlink_desc
, spec_symlink
}, /* symlink */
174 { &vop_readdir_desc
, spec_readdir
}, /* readdir */
175 { &vop_readlink_desc
, spec_readlink
}, /* readlink */
176 { &vop_abortop_desc
, spec_abortop
}, /* abortop */
177 { &vop_inactive_desc
, nfs_inactive
}, /* inactive */
178 { &vop_reclaim_desc
, nfs_reclaim
}, /* reclaim */
179 { &vop_lock_desc
, nfs_lock
}, /* lock */
180 { &vop_unlock_desc
, nfs_unlock
}, /* unlock */
181 { &vop_bmap_desc
, spec_bmap
}, /* bmap */
182 { &vop_strategy_desc
, spec_strategy
}, /* strategy */
183 { &vop_print_desc
, nfs_print
}, /* print */
184 { &vop_islocked_desc
, nfs_islocked
}, /* islocked */
185 { &vop_pathconf_desc
, spec_pathconf
}, /* pathconf */
186 { &vop_advlock_desc
, spec_advlock
}, /* advlock */
187 { &vop_bwrite_desc
, spec_bwrite
}, /* bwrite */
188 { &vop_getpages_desc
, spec_getpages
}, /* getpages */
189 { &vop_putpages_desc
, spec_putpages
}, /* putpages */
192 const struct vnodeopv_desc spec_nfsv2nodeop_opv_desc
=
193 { &spec_nfsv2nodeop_p
, spec_nfsv2nodeop_entries
};
195 int (**fifo_nfsv2nodeop_p
)(void *);
196 const struct vnodeopv_entry_desc fifo_nfsv2nodeop_entries
[] = {
197 { &vop_default_desc
, vn_default_error
},
198 { &vop_lookup_desc
, fifo_lookup
}, /* lookup */
199 { &vop_create_desc
, fifo_create
}, /* create */
200 { &vop_mknod_desc
, fifo_mknod
}, /* mknod */
201 { &vop_open_desc
, fifo_open
}, /* open */
202 { &vop_close_desc
, nfsfifo_close
}, /* close */
203 { &vop_access_desc
, nfsspec_access
}, /* access */
204 { &vop_getattr_desc
, nfs_getattr
}, /* getattr */
205 { &vop_setattr_desc
, nfs_setattr
}, /* setattr */
206 { &vop_read_desc
, nfsfifo_read
}, /* read */
207 { &vop_write_desc
, nfsfifo_write
}, /* write */
208 { &vop_fcntl_desc
, genfs_fcntl
}, /* fcntl */
209 { &vop_ioctl_desc
, fifo_ioctl
}, /* ioctl */
210 { &vop_poll_desc
, fifo_poll
}, /* poll */
211 { &vop_kqfilter_desc
, fifo_kqfilter
}, /* kqfilter */
212 { &vop_revoke_desc
, fifo_revoke
}, /* revoke */
213 { &vop_mmap_desc
, fifo_mmap
}, /* mmap */
214 { &vop_fsync_desc
, nfs_fsync
}, /* fsync */
215 { &vop_seek_desc
, fifo_seek
}, /* seek */
216 { &vop_remove_desc
, fifo_remove
}, /* remove */
217 { &vop_link_desc
, fifo_link
}, /* link */
218 { &vop_rename_desc
, fifo_rename
}, /* rename */
219 { &vop_mkdir_desc
, fifo_mkdir
}, /* mkdir */
220 { &vop_rmdir_desc
, fifo_rmdir
}, /* rmdir */
221 { &vop_symlink_desc
, fifo_symlink
}, /* symlink */
222 { &vop_readdir_desc
, fifo_readdir
}, /* readdir */
223 { &vop_readlink_desc
, fifo_readlink
}, /* readlink */
224 { &vop_abortop_desc
, fifo_abortop
}, /* abortop */
225 { &vop_inactive_desc
, nfs_inactive
}, /* inactive */
226 { &vop_reclaim_desc
, nfs_reclaim
}, /* reclaim */
227 { &vop_lock_desc
, nfs_lock
}, /* lock */
228 { &vop_unlock_desc
, nfs_unlock
}, /* unlock */
229 { &vop_bmap_desc
, fifo_bmap
}, /* bmap */
230 { &vop_strategy_desc
, genfs_badop
}, /* strategy */
231 { &vop_print_desc
, nfs_print
}, /* print */
232 { &vop_islocked_desc
, nfs_islocked
}, /* islocked */
233 { &vop_pathconf_desc
, fifo_pathconf
}, /* pathconf */
234 { &vop_advlock_desc
, fifo_advlock
}, /* advlock */
235 { &vop_bwrite_desc
, genfs_badop
}, /* bwrite */
236 { &vop_putpages_desc
, fifo_putpages
}, /* putpages */
239 const struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc
=
240 { &fifo_nfsv2nodeop_p
, fifo_nfsv2nodeop_entries
};
242 static int nfs_linkrpc(struct vnode
*, struct vnode
*, const char *,
243 size_t, kauth_cred_t
, struct lwp
*);
244 static void nfs_writerpc_extfree(struct mbuf
*, void *, size_t, void *);
249 extern u_int32_t nfs_true
, nfs_false
;
250 extern u_int32_t nfs_xdrneg1
;
251 extern const nfstype nfsv3_type
[9];
253 int nfs_numasync
= 0;
254 #define DIRHDSIZ _DIRENT_NAMEOFF(dp)
255 #define UIO_ADVANCE(uio, siz) \
256 (void)((uio)->uio_resid -= (siz), \
257 (uio)->uio_iov->iov_base = (char *)(uio)->uio_iov->iov_base + (siz), \
258 (uio)->uio_iov->iov_len -= (siz))
260 static void nfs_cache_enter(struct vnode
*, struct vnode
*,
261 struct componentname
*);
264 nfs_cache_enter(struct vnode
*dvp
, struct vnode
*vp
,
265 struct componentname
*cnp
)
267 struct nfsnode
*dnp
= VTONFS(dvp
);
270 struct nfsnode
*np
= VTONFS(vp
);
272 np
->n_ctime
= np
->n_vattr
->va_ctime
.tv_sec
;
275 if (!timespecisset(&dnp
->n_nctime
))
276 dnp
->n_nctime
= dnp
->n_vattr
->va_mtime
;
278 cache_enter(dvp
, vp
, cnp
);
282 * nfs null call from vfs.
285 nfs_null(struct vnode
*vp
, kauth_cred_t cred
, struct lwp
*l
)
289 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
290 struct nfsnode
*np
= VTONFS(vp
);
292 nfsm_reqhead(np
, NFSPROC_NULL
, 0);
293 nfsm_request(np
, NFSPROC_NULL
, l
, cred
);
299 * nfs access vnode op.
300 * For nfs version 2, just return ok. File accesses may fail later.
301 * For nfs version 3, use the access rpc to check accessibility. If file modes
302 * are changed on the server, accesses might still fail later.
307 struct vop_access_args
/* {
312 struct vnode
*vp
= ap
->a_vp
;
317 char *bpos
, *dpos
, *cp2
;
318 int error
= 0, attrflag
;
319 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
320 u_int32_t mode
, rmode
;
321 const int v3
= NFS_ISV3(vp
);
324 struct nfsnode
*np
= VTONFS(vp
);
325 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
327 cachevalid
= (np
->n_accstamp
!= -1 &&
328 (time_uptime
- np
->n_accstamp
) < nfs_attrtimeo(nmp
, np
) &&
329 np
->n_accuid
== kauth_cred_geteuid(ap
->a_cred
));
332 * Check access cache first. If this request has been made for this
333 * uid shortly before, use the cached result.
336 if (!np
->n_accerror
) {
337 if ((np
->n_accmode
& ap
->a_mode
) == ap
->a_mode
)
338 return np
->n_accerror
;
339 } else if ((np
->n_accmode
& ap
->a_mode
) == np
->n_accmode
)
340 return np
->n_accerror
;
345 * For nfs v3, do an access rpc, otherwise you are stuck emulating
346 * ufs_access() locally using the vattr. This may not be correct,
347 * since the server may apply other access criteria such as
348 * client uid-->server uid mapping that we do not know about, but
349 * this is better than just returning anything that is lying about
353 nfsstats
.rpccnt
[NFSPROC_ACCESS
]++;
354 nfsm_reqhead(np
, NFSPROC_ACCESS
, NFSX_FH(v3
) + NFSX_UNSIGNED
);
356 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
);
357 if (ap
->a_mode
& VREAD
)
358 mode
= NFSV3ACCESS_READ
;
361 if (vp
->v_type
!= VDIR
) {
362 if (ap
->a_mode
& VWRITE
)
363 mode
|= (NFSV3ACCESS_MODIFY
| NFSV3ACCESS_EXTEND
);
364 if (ap
->a_mode
& VEXEC
)
365 mode
|= NFSV3ACCESS_EXECUTE
;
367 if (ap
->a_mode
& VWRITE
)
368 mode
|= (NFSV3ACCESS_MODIFY
| NFSV3ACCESS_EXTEND
|
370 if (ap
->a_mode
& VEXEC
)
371 mode
|= NFSV3ACCESS_LOOKUP
;
373 *tl
= txdr_unsigned(mode
);
374 nfsm_request(np
, NFSPROC_ACCESS
, curlwp
, ap
->a_cred
);
375 nfsm_postop_attr(vp
, attrflag
, 0);
377 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
378 rmode
= fxdr_unsigned(u_int32_t
, *tl
);
380 * The NFS V3 spec does not clarify whether or not
381 * the returned access bits can be a superset of
382 * the ones requested, so...
384 if ((rmode
& mode
) != mode
)
390 return (nfsspec_access(ap
));
393 * Disallow write attempts on filesystems mounted read-only;
394 * unless the file is a socket, fifo, or a block or character
395 * device resident on the filesystem.
397 if (!error
&& (ap
->a_mode
& VWRITE
) &&
398 (vp
->v_mount
->mnt_flag
& MNT_RDONLY
)) {
399 switch (vp
->v_type
) {
409 if (!error
|| error
== EACCES
) {
411 * If we got the same result as for a previous,
412 * different request, OR it in. Don't update
413 * the timestamp in that case.
415 if (cachevalid
&& np
->n_accstamp
!= -1 &&
416 error
== np
->n_accerror
) {
418 np
->n_accmode
|= ap
->a_mode
;
419 else if ((np
->n_accmode
& ap
->a_mode
) == ap
->a_mode
)
420 np
->n_accmode
= ap
->a_mode
;
422 np
->n_accstamp
= time_uptime
;
423 np
->n_accuid
= kauth_cred_geteuid(ap
->a_cred
);
424 np
->n_accmode
= ap
->a_mode
;
425 np
->n_accerror
= error
;
435 * Check to see if the type is ok
436 * and that deletion is not in progress.
437 * For paged in text files, you will need to flush the page cache
438 * if consistency is lost.
444 struct vop_open_args
/* {
449 struct vnode
*vp
= ap
->a_vp
;
450 struct nfsnode
*np
= VTONFS(vp
);
453 if (vp
->v_type
!= VREG
&& vp
->v_type
!= VDIR
&& vp
->v_type
!= VLNK
) {
457 if (ap
->a_mode
& FREAD
) {
458 if (np
->n_rcred
!= NULL
)
459 kauth_cred_free(np
->n_rcred
);
460 np
->n_rcred
= ap
->a_cred
;
461 kauth_cred_hold(np
->n_rcred
);
463 if (ap
->a_mode
& FWRITE
) {
464 if (np
->n_wcred
!= NULL
)
465 kauth_cred_free(np
->n_wcred
);
466 np
->n_wcred
= ap
->a_cred
;
467 kauth_cred_hold(np
->n_wcred
);
470 error
= nfs_flushstalebuf(vp
, ap
->a_cred
, curlwp
, 0);
474 NFS_INVALIDATE_ATTRCACHE(np
); /* For Open/Close consistency */
481 * What an NFS client should do upon close after writing is a debatable issue.
482 * Most NFS clients push delayed writes to the server upon close, basically for
484 * 1 - So that any write errors may be reported back to the client process
485 * doing the close system call. By far the two most likely errors are
486 * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure.
487 * 2 - To put a worst case upper bound on cache inconsistency between
488 * multiple clients for the file.
489 * There is also a consistency problem for Version 2 of the protocol w.r.t.
490 * not being able to tell if other clients are writing a file concurrently,
491 * since there is no way of knowing if the changed modify time in the reply
492 * is only due to the write for this client.
493 * (NFS Version 3 provides weak cache consistency data in the reply that
494 * should be sufficient to detect and handle this case.)
496 * The current code does the following:
497 * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers
498 * for NFS Version 3 - flush dirty buffers to the server but don't invalidate
499 * or commit them (this satisfies 1 and 2 except for the
500 * case where the server crashes after this close but
501 * before the commit RPC, which is felt to be "good
502 * enough". Changing the last argument to nfs_flush() to
503 * a 1 would force a commit operation, if it is felt a
504 * commit is necessary now.
510 struct vop_close_args
/* {
511 struct vnodeop_desc *a_desc;
516 struct vnode
*vp
= ap
->a_vp
;
517 struct nfsnode
*np
= VTONFS(vp
);
519 UVMHIST_FUNC("nfs_close"); UVMHIST_CALLED(ubchist
);
521 if (vp
->v_type
== VREG
) {
522 if (np
->n_flag
& NMODIFIED
) {
525 error
= nfs_flush(vp
, ap
->a_cred
, MNT_WAIT
, curlwp
, 0);
526 np
->n_flag
&= ~NMODIFIED
;
529 error
= nfs_vinvalbuf(vp
, V_SAVE
, ap
->a_cred
, curlwp
, 1);
530 NFS_INVALIDATE_ATTRCACHE(np
);
532 if (np
->n_flag
& NWRITEERR
) {
533 np
->n_flag
&= ~NWRITEERR
;
537 UVMHIST_LOG(ubchist
, "returning %d", error
,0,0,0);
542 * nfs getattr call from vfs.
547 struct vop_getattr_args
/* {
552 struct vnode
*vp
= ap
->a_vp
;
553 struct nfsnode
*np
= VTONFS(vp
);
559 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
560 const int v3
= NFS_ISV3(vp
);
563 * Update local times for special files.
565 if (np
->n_flag
& (NACC
| NUPD
))
569 * if we have delayed truncation, do it now.
571 nfs_delayedtruncate(vp
);
574 * First look in the cache.
576 if (nfs_getattrcache(vp
, ap
->a_vap
) == 0)
578 nfsstats
.rpccnt
[NFSPROC_GETATTR
]++;
579 nfsm_reqhead(np
, NFSPROC_GETATTR
, NFSX_FH(v3
));
581 nfsm_request(np
, NFSPROC_GETATTR
, curlwp
, ap
->a_cred
);
583 nfsm_loadattr(vp
, ap
->a_vap
, 0);
584 if (vp
->v_type
== VDIR
&&
585 ap
->a_vap
->va_blocksize
< NFS_DIRFRAGSIZ
)
586 ap
->a_vap
->va_blocksize
= NFS_DIRFRAGSIZ
;
598 struct vop_setattr_args
/* {
599 struct vnodeop_desc *a_desc;
604 struct vnode
*vp
= ap
->a_vp
;
605 struct nfsnode
*np
= VTONFS(vp
);
606 struct vattr
*vap
= ap
->a_vap
;
611 * Setting of flags is not supported.
613 if (vap
->va_flags
!= VNOVAL
)
617 * Disallow write attempts if the filesystem is mounted read-only.
619 if ((vap
->va_uid
!= (uid_t
)VNOVAL
||
620 vap
->va_gid
!= (gid_t
)VNOVAL
|| vap
->va_atime
.tv_sec
!= VNOVAL
||
621 vap
->va_mtime
.tv_sec
!= VNOVAL
|| vap
->va_mode
!= (mode_t
)VNOVAL
) &&
622 (vp
->v_mount
->mnt_flag
& MNT_RDONLY
))
624 if (vap
->va_size
!= VNOVAL
) {
625 if (vap
->va_size
> VFSTONFS(vp
->v_mount
)->nm_maxfilesize
) {
628 switch (vp
->v_type
) {
635 if (vap
->va_mtime
.tv_sec
== VNOVAL
&&
636 vap
->va_atime
.tv_sec
== VNOVAL
&&
637 vap
->va_mode
== (mode_t
)VNOVAL
&&
638 vap
->va_uid
== (uid_t
)VNOVAL
&&
639 vap
->va_gid
== (gid_t
)VNOVAL
)
641 vap
->va_size
= VNOVAL
;
645 * Disallow write attempts if the filesystem is
648 if (vp
->v_mount
->mnt_flag
& MNT_RDONLY
)
650 genfs_node_wrlock(vp
);
651 uvm_vnp_setsize(vp
, vap
->va_size
);
653 np
->n_size
= vap
->va_size
;
654 if (vap
->va_size
== 0)
655 error
= nfs_vinvalbuf(vp
, 0,
656 ap
->a_cred
, curlwp
, 1);
658 error
= nfs_vinvalbuf(vp
, V_SAVE
,
659 ap
->a_cred
, curlwp
, 1);
661 uvm_vnp_setsize(vp
, tsize
);
662 genfs_node_unlock(vp
);
665 np
->n_vattr
->va_size
= vap
->va_size
;
669 * flush files before setattr because a later write of
670 * cached data might change timestamps or reset sugid bits
672 if ((vap
->va_mtime
.tv_sec
!= VNOVAL
||
673 vap
->va_atime
.tv_sec
!= VNOVAL
||
674 vap
->va_mode
!= VNOVAL
) &&
675 vp
->v_type
== VREG
&&
676 (error
= nfs_vinvalbuf(vp
, V_SAVE
, ap
->a_cred
,
677 curlwp
, 1)) == EINTR
)
680 error
= nfs_setattrrpc(vp
, vap
, ap
->a_cred
, curlwp
);
681 if (vap
->va_size
!= VNOVAL
) {
683 np
->n_size
= np
->n_vattr
->va_size
= tsize
;
684 uvm_vnp_setsize(vp
, np
->n_size
);
686 genfs_node_unlock(vp
);
688 VN_KNOTE(vp
, NOTE_ATTRIB
);
693 * Do an nfs setattr rpc.
696 nfs_setattrrpc(struct vnode
*vp
, struct vattr
*vap
, kauth_cred_t cred
, struct lwp
*l
)
698 struct nfsv2_sattr
*sp
;
704 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
705 const int v3
= NFS_ISV3(vp
);
706 struct nfsnode
*np
= VTONFS(vp
);
708 int wccflag
= NFSV3_WCCRATTR
;
712 nfsstats
.rpccnt
[NFSPROC_SETATTR
]++;
713 nfsm_reqhead(np
, NFSPROC_SETATTR
, NFSX_FH(v3
) + NFSX_SATTR(v3
));
717 nfsm_v3attrbuild(vap
, true);
718 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
);
722 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
723 if (vap
->va_mode
== (mode_t
)VNOVAL
)
724 sp
->sa_mode
= nfs_xdrneg1
;
726 sp
->sa_mode
= vtonfsv2_mode(vp
->v_type
, vap
->va_mode
);
727 if (vap
->va_uid
== (uid_t
)VNOVAL
)
728 sp
->sa_uid
= nfs_xdrneg1
;
730 sp
->sa_uid
= txdr_unsigned(vap
->va_uid
);
731 if (vap
->va_gid
== (gid_t
)VNOVAL
)
732 sp
->sa_gid
= nfs_xdrneg1
;
734 sp
->sa_gid
= txdr_unsigned(vap
->va_gid
);
735 sp
->sa_size
= txdr_unsigned(vap
->va_size
);
736 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
737 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
741 nfsm_request(np
, NFSPROC_SETATTR
, l
, cred
);
744 nfsm_wcc_data(vp
, wccflag
, NAC_NOTRUNC
, false);
747 nfsm_loadattr(vp
, (struct vattr
*)0, NAC_NOTRUNC
);
753 * nfs lookup call, one step at a time...
754 * First look in cache
755 * If not found, do the rpc.
760 struct vop_lookup_args
/* {
761 struct vnodeop_desc *a_desc;
763 struct vnode **a_vpp;
764 struct componentname *a_cnp;
766 struct componentname
*cnp
= ap
->a_cnp
;
767 struct vnode
*dvp
= ap
->a_dvp
;
768 struct vnode
**vpp
= ap
->a_vpp
;
774 char *bpos
, *dpos
, *cp2
;
775 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
779 int error
= 0, attrflag
, fhsize
;
780 const int v3
= NFS_ISV3(dvp
);
782 flags
= cnp
->cn_flags
;
786 if ((flags
& ISLASTCN
) && (dvp
->v_mount
->mnt_flag
& MNT_RDONLY
) &&
787 (cnp
->cn_nameiop
== DELETE
|| cnp
->cn_nameiop
== RENAME
))
789 if (dvp
->v_type
!= VDIR
)
793 * RFC1813(nfsv3) 3.2 says clients should handle "." by themselves.
795 if (cnp
->cn_namelen
== 1 && cnp
->cn_nameptr
[0] == '.') {
796 error
= VOP_ACCESS(dvp
, VEXEC
, cnp
->cn_cred
);
799 if (cnp
->cn_nameiop
== RENAME
&& (flags
& ISLASTCN
))
803 if (cnp
->cn_nameiop
!= LOOKUP
&& (flags
& ISLASTCN
))
804 cnp
->cn_flags
|= SAVENAME
;
811 * Before performing an RPC, check the name cache to see if
812 * the directory/name pair we are looking for is known already.
813 * If the directory/name pair is found in the name cache,
814 * we have to ensure the directory has not changed from
815 * the time the cache entry has been created. If it has,
816 * the cache entry has to be ignored.
818 error
= cache_lookup_raw(dvp
, vpp
, cnp
);
819 KASSERT(dvp
!= *vpp
);
820 KASSERT((cnp
->cn_flags
& ISWHITEOUT
) == 0);
825 if (error
&& error
!= ENOENT
) {
830 err2
= VOP_ACCESS(dvp
, VEXEC
, cnp
->cn_cred
);
838 if (VOP_GETATTR(dvp
, &vattr
, cnp
->cn_cred
)
839 || timespeccmp(&vattr
.va_mtime
,
840 &VTONFS(dvp
)->n_nctime
, !=)) {
845 cache_purge1(dvp
, NULL
, PURGE_CHILDREN
);
846 timespecclear(&np
->n_nctime
);
850 if (error
== ENOENT
) {
855 * investigate the vnode returned by cache_lookup_raw.
856 * if it isn't appropriate, do an rpc.
859 if ((flags
& ISDOTDOT
) != 0) {
862 error
= vn_lock(newvp
, LK_EXCLUSIVE
);
863 if ((flags
& ISDOTDOT
) != 0) {
864 vn_lock(dvp
, LK_EXCLUSIVE
| LK_RETRY
);
867 /* newvp has been reclaimed. */
872 if (!VOP_GETATTR(newvp
, &vattr
, cnp
->cn_cred
)
873 && vattr
.va_ctime
.tv_sec
== VTONFS(newvp
)->n_ctime
) {
874 nfsstats
.lookupcache_hits
++;
875 if (cnp
->cn_nameiop
!= LOOKUP
&& (flags
& ISLASTCN
))
876 cnp
->cn_flags
|= SAVENAME
;
877 KASSERT(newvp
->v_type
!= VNON
);
880 cache_purge1(newvp
, NULL
, PURGE_PARENTS
);
887 * because nfsv3 has the same CREATE semantics as ours,
888 * we don't have to perform LOOKUPs beforehand.
890 * XXX ideally we can do the same for nfsv2 in the case of !O_EXCL.
891 * XXX although we have no way to know if O_EXCL is requested or not.
894 if (v3
&& cnp
->cn_nameiop
== CREATE
&&
895 (flags
& (ISLASTCN
|ISDOTDOT
)) == ISLASTCN
&&
896 (dvp
->v_mount
->mnt_flag
& MNT_RDONLY
) == 0) {
897 cnp
->cn_flags
|= SAVENAME
;
898 return (EJUSTRETURN
);
904 nfsstats
.lookupcache_misses
++;
905 nfsstats
.rpccnt
[NFSPROC_LOOKUP
]++;
906 len
= cnp
->cn_namelen
;
907 nfsm_reqhead(np
, NFSPROC_LOOKUP
,
908 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(len
));
910 nfsm_strtom(cnp
->cn_nameptr
, len
, NFS_MAXNAMLEN
);
911 nfsm_request(np
, NFSPROC_LOOKUP
, curlwp
, cnp
->cn_cred
);
913 nfsm_postop_attr(dvp
, attrflag
, 0);
917 nfsm_getfh(fhp
, fhsize
, v3
);
920 * Handle RENAME case...
922 if (cnp
->cn_nameiop
== RENAME
&& (flags
& ISLASTCN
)) {
923 if (NFS_CMPFH(np
, fhp
, fhsize
)) {
927 error
= nfs_nget(dvp
->v_mount
, fhp
, fhsize
, &np
);
935 nfsm_postop_attr(newvp
, attrflag
, 0);
936 nfsm_postop_attr(dvp
, attrflag
, 0);
939 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
942 cnp
->cn_flags
|= SAVENAME
;
947 * The postop attr handling is duplicated for each if case,
948 * because it should be done while dvp is locked (unlocking
949 * dvp is different for each case).
952 if (NFS_CMPFH(np
, fhp
, fhsize
)) {
954 * as we handle "." lookup locally, this should be
961 nfsm_postop_attr(newvp
, attrflag
, 0);
962 nfsm_postop_attr(dvp
, attrflag
, 0);
965 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
966 } else if (flags
& ISDOTDOT
) {
971 error
= nfs_nget(dvp
->v_mount
, fhp
, fhsize
, &np
);
972 vn_lock(dvp
, LK_EXCLUSIVE
| LK_RETRY
);
981 nfsm_postop_attr(newvp
, attrflag
, 0);
982 nfsm_postop_attr(dvp
, attrflag
, 0);
985 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
990 error
= nfs_nget(dvp
->v_mount
, fhp
, fhsize
, &np
);
998 nfsm_postop_attr(newvp
, attrflag
, 0);
999 nfsm_postop_attr(dvp
, attrflag
, 0);
1002 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
1004 if (cnp
->cn_nameiop
!= LOOKUP
&& (flags
& ISLASTCN
))
1005 cnp
->cn_flags
|= SAVENAME
;
1006 if ((cnp
->cn_flags
& MAKEENTRY
) &&
1007 (cnp
->cn_nameiop
!= DELETE
|| !(flags
& ISLASTCN
))) {
1008 nfs_cache_enter(dvp
, newvp
, cnp
);
1014 * We get here only because of errors returned by
1015 * the RPC. Otherwise we'll have returned above
1016 * (the nfsm_* macros will jump to nfsm_reqdone
1019 if (error
== ENOENT
&& (cnp
->cn_flags
& MAKEENTRY
) &&
1020 cnp
->cn_nameiop
!= CREATE
) {
1021 nfs_cache_enter(dvp
, NULL
, cnp
);
1023 if (newvp
!= NULLVP
) {
1031 if ((cnp
->cn_nameiop
== CREATE
|| cnp
->cn_nameiop
== RENAME
) &&
1032 (flags
& ISLASTCN
) && error
== ENOENT
) {
1033 if (dvp
->v_mount
->mnt_flag
& MNT_RDONLY
) {
1036 error
= EJUSTRETURN
;
1037 cnp
->cn_flags
|= SAVENAME
;
1046 * make sure we have valid type and size.
1050 if (newvp
->v_type
== VNON
) {
1051 struct vattr vattr
; /* dummy */
1053 KASSERT(VTONFS(newvp
)->n_attrstamp
== 0);
1054 error
= VOP_GETATTR(newvp
, &vattr
, cnp
->cn_cred
);
1066 * Just call nfs_bioread() to do the work.
1071 struct vop_read_args
/* {
1075 kauth_cred_t a_cred;
1077 struct vnode
*vp
= ap
->a_vp
;
1079 if (vp
->v_type
!= VREG
)
1081 return (nfs_bioread(vp
, ap
->a_uio
, ap
->a_ioflag
, ap
->a_cred
, 0));
1088 nfs_readlink(void *v
)
1090 struct vop_readlink_args
/* {
1093 kauth_cred_t a_cred;
1095 struct vnode
*vp
= ap
->a_vp
;
1096 struct nfsnode
*np
= VTONFS(vp
);
1098 if (vp
->v_type
!= VLNK
)
1101 if (np
->n_rcred
!= NULL
) {
1102 kauth_cred_free(np
->n_rcred
);
1104 np
->n_rcred
= ap
->a_cred
;
1105 kauth_cred_hold(np
->n_rcred
);
1107 return (nfs_bioread(vp
, ap
->a_uio
, 0, ap
->a_cred
, 0));
1111 * Do a readlink rpc.
1112 * Called by nfs_doio() from below the buffer cache.
1115 nfs_readlinkrpc(struct vnode
*vp
, struct uio
*uiop
, kauth_cred_t cred
)
1120 char *bpos
, *dpos
, *cp2
;
1123 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1124 const int v3
= NFS_ISV3(vp
);
1125 struct nfsnode
*np
= VTONFS(vp
);
1130 nfsstats
.rpccnt
[NFSPROC_READLINK
]++;
1131 nfsm_reqhead(np
, NFSPROC_READLINK
, NFSX_FH(v3
));
1133 nfsm_request(np
, NFSPROC_READLINK
, curlwp
, cred
);
1136 nfsm_postop_attr(vp
, attrflag
, 0);
1141 nfsm_dissect(tl
, uint32_t *, NFSX_UNSIGNED
);
1142 len
= fxdr_unsigned(uint32_t, *tl
);
1143 if (len
> MAXPATHLEN
) {
1145 * this pathname is too long for us.
1148 /* Solaris returns EINVAL. should we follow? */
1149 error
= ENAMETOOLONG
;
1155 nfsm_strsiz(len
, NFS_MAXPATHLEN
);
1157 nfsm_mtouio(uiop
, len
);
1168 nfs_readrpc(struct vnode
*vp
, struct uio
*uiop
)
1173 char *bpos
, *dpos
, *cp2
;
1174 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1175 struct nfsmount
*nmp
;
1176 int error
= 0, len
, retlen
, tsiz
, eof
, byte_count
;
1177 const int v3
= NFS_ISV3(vp
);
1178 struct nfsnode
*np
= VTONFS(vp
);
1186 nmp
= VFSTONFS(vp
->v_mount
);
1187 tsiz
= uiop
->uio_resid
;
1188 if (uiop
->uio_offset
+ tsiz
> nmp
->nm_maxfilesize
)
1190 iostat_busy(nmp
->nm_stats
);
1191 byte_count
= 0; /* count bytes actually transferred */
1193 nfsstats
.rpccnt
[NFSPROC_READ
]++;
1194 len
= (tsiz
> nmp
->nm_rsize
) ? nmp
->nm_rsize
: tsiz
;
1195 nfsm_reqhead(np
, NFSPROC_READ
, NFSX_FH(v3
) + NFSX_UNSIGNED
* 3);
1197 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
* 3);
1200 txdr_hyper(uiop
->uio_offset
, tl
);
1201 *(tl
+ 2) = txdr_unsigned(len
);
1205 *tl
++ = txdr_unsigned(uiop
->uio_offset
);
1206 *tl
++ = txdr_unsigned(len
);
1209 nfsm_request(np
, NFSPROC_READ
, curlwp
, np
->n_rcred
);
1212 nfsm_postop_attr(vp
, attrflag
, NAC_NOTRUNC
);
1217 nfsm_dissect(tl
, u_int32_t
*, 2 * NFSX_UNSIGNED
);
1218 eof
= fxdr_unsigned(int, *(tl
+ 1));
1221 nfsm_loadattr(vp
, (struct vattr
*)0, NAC_NOTRUNC
);
1222 nfsm_strsiz(retlen
, nmp
->nm_rsize
);
1223 nfsm_mtouio(uiop
, retlen
);
1226 byte_count
+= retlen
;
1229 if (eof
|| retlen
== 0)
1237 iostat_unbusy(nmp
->nm_stats
, byte_count
, 1);
1241 struct nfs_writerpc_context
{
1248 * free mbuf used to refer protected pages while write rpc call.
1252 nfs_writerpc_extfree(struct mbuf
*m
, void *tbuf
, size_t size
, void *arg
)
1254 struct nfs_writerpc_context
*ctx
= arg
;
1257 KASSERT(ctx
!= NULL
);
1258 pool_cache_put(mb_cache
, m
);
1259 mutex_enter(&ctx
->nwc_lock
);
1260 if (--ctx
->nwc_mbufcount
== 0) {
1261 cv_signal(&ctx
->nwc_cv
);
1263 mutex_exit(&ctx
->nwc_lock
);
1270 nfs_writerpc(struct vnode
*vp
, struct uio
*uiop
, int *iomode
, bool pageprotected
, bool *stalewriteverfp
)
1276 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1277 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
1278 int error
= 0, len
, tsiz
, wccflag
= NFSV3_WCCRATTR
;
1279 const int v3
= NFS_ISV3(vp
);
1280 int committed
= NFSV3WRITE_FILESYNC
;
1281 struct nfsnode
*np
= VTONFS(vp
);
1282 struct nfs_writerpc_context ctx
;
1290 mutex_init(&ctx
.nwc_lock
, MUTEX_DRIVER
, IPL_VM
);
1291 cv_init(&ctx
.nwc_cv
, "nfsmblk");
1292 ctx
.nwc_mbufcount
= 1;
1294 if (vp
->v_mount
->mnt_flag
& MNT_RDONLY
) {
1295 panic("writerpc readonly vp %p", vp
);
1299 if (uiop
->uio_iovcnt
!= 1)
1300 panic("nfs: writerpc iovcnt > 1");
1302 tsiz
= uiop
->uio_resid
;
1303 if (uiop
->uio_offset
+ tsiz
> nmp
->nm_maxfilesize
)
1306 origresid
= uiop
->uio_resid
;
1307 KASSERT(origresid
== uiop
->uio_iov
->iov_len
);
1308 iostat_busy(nmp
->nm_stats
);
1309 byte_count
= 0; /* count of bytes actually written */
1311 uint32_t datalen
; /* data bytes need to be allocated in mbuf */
1313 bool stalewriteverf
= false;
1315 nfsstats
.rpccnt
[NFSPROC_WRITE
]++;
1316 len
= min(tsiz
, nmp
->nm_wsize
);
1317 datalen
= pageprotected
? 0 : nfsm_rndup(len
);
1318 nfsm_reqhead(np
, NFSPROC_WRITE
,
1319 NFSX_FH(v3
) + 5 * NFSX_UNSIGNED
+ datalen
);
1323 nfsm_build(tl
, u_int32_t
*, 5 * NFSX_UNSIGNED
);
1324 txdr_hyper(uiop
->uio_offset
, tl
);
1326 *tl
++ = txdr_unsigned(len
);
1327 *tl
++ = txdr_unsigned(*iomode
);
1328 *tl
= txdr_unsigned(len
);
1334 nfsm_build(tl
, u_int32_t
*, 4 * NFSX_UNSIGNED
);
1335 /* Set both "begin" and "current" to non-garbage. */
1336 x
= txdr_unsigned((u_int32_t
)uiop
->uio_offset
);
1337 *tl
++ = x
; /* "begin offset" */
1338 *tl
++ = x
; /* "current offset" */
1339 x
= txdr_unsigned(len
);
1340 *tl
++ = x
; /* total to this offset */
1341 *tl
= x
; /* size of this write */
1344 if (pageprotected
) {
1346 * since we know pages can't be modified during i/o,
1347 * no need to copy them for us.
1350 struct iovec
*iovp
= uiop
->uio_iov
;
1352 m
= m_get(M_WAIT
, MT_DATA
);
1353 MCLAIM(m
, &nfs_mowner
);
1354 MEXTADD(m
, iovp
->iov_base
, len
, M_MBUF
,
1355 nfs_writerpc_extfree
, &ctx
);
1356 m
->m_flags
|= M_EXT_ROMAP
;
1360 * no need to maintain mb and bpos here
1361 * because no one care them later.
1365 bpos
= mtod(void *, mb
) + mb
->m_len
;
1367 UIO_ADVANCE(uiop
, len
);
1368 uiop
->uio_offset
+= len
;
1369 mutex_enter(&ctx
.nwc_lock
);
1370 ctx
.nwc_mbufcount
++;
1371 mutex_exit(&ctx
.nwc_lock
);
1372 nfs_zeropad(mb
, 0, nfsm_padlen(len
));
1374 nfsm_uiotom(uiop
, len
);
1376 nfsm_request(np
, NFSPROC_WRITE
, curlwp
, np
->n_wcred
);
1379 wccflag
= NFSV3_WCCCHK
;
1380 nfsm_wcc_data(vp
, wccflag
, NAC_NOTRUNC
, !error
);
1382 nfsm_dissect(tl
, u_int32_t
*, 2 * NFSX_UNSIGNED
1383 + NFSX_V3WRITEVERF
);
1384 rlen
= fxdr_unsigned(int, *tl
++);
1389 } else if (rlen
< len
) {
1390 backup
= len
- rlen
;
1391 UIO_ADVANCE(uiop
, -backup
);
1392 uiop
->uio_offset
-= backup
;
1395 commit
= fxdr_unsigned(int, *tl
++);
1398 * Return the lowest committment level
1399 * obtained by any of the RPCs.
1401 if (committed
== NFSV3WRITE_FILESYNC
)
1403 else if (committed
== NFSV3WRITE_DATASYNC
&&
1404 commit
== NFSV3WRITE_UNSTABLE
)
1406 mutex_enter(&nmp
->nm_lock
);
1407 if ((nmp
->nm_iflag
& NFSMNT_HASWRITEVERF
) == 0){
1408 memcpy(nmp
->nm_writeverf
, tl
,
1410 nmp
->nm_iflag
|= NFSMNT_HASWRITEVERF
;
1411 } else if ((nmp
->nm_iflag
&
1412 NFSMNT_STALEWRITEVERF
) ||
1413 memcmp(tl
, nmp
->nm_writeverf
,
1414 NFSX_V3WRITEVERF
)) {
1415 memcpy(nmp
->nm_writeverf
, tl
,
1418 * note NFSMNT_STALEWRITEVERF
1419 * if we're the first thread to
1422 if ((nmp
->nm_iflag
&
1423 NFSMNT_STALEWRITEVERF
) == 0) {
1424 stalewriteverf
= true;
1426 NFSMNT_STALEWRITEVERF
;
1429 mutex_exit(&nmp
->nm_lock
);
1433 nfsm_loadattr(vp
, (struct vattr
*)0, NAC_NOTRUNC
);
1435 VTONFS(vp
)->n_mtime
= VTONFS(vp
)->n_vattr
->va_mtime
;
1441 if (stalewriteverf
) {
1442 *stalewriteverfp
= true;
1443 stalewriteverf
= false;
1444 if (committed
== NFSV3WRITE_UNSTABLE
&&
1447 * if our write requests weren't atomic but
1448 * unstable, datas in previous iterations
1449 * might have already been lost now.
1450 * then, we should resend them to nfsd.
1452 backup
= origresid
- tsiz
;
1453 UIO_ADVANCE(uiop
, -backup
);
1454 uiop
->uio_offset
-= backup
;
1461 iostat_unbusy(nmp
->nm_stats
, byte_count
, 0);
1462 if (pageprotected
) {
1464 * wait until mbufs go away.
1465 * retransmitted mbufs can survive longer than rpc requests
1468 mutex_enter(&ctx
.nwc_lock
);
1469 ctx
.nwc_mbufcount
--;
1470 while (ctx
.nwc_mbufcount
> 0) {
1471 cv_wait(&ctx
.nwc_cv
, &ctx
.nwc_lock
);
1473 mutex_exit(&ctx
.nwc_lock
);
1475 mutex_destroy(&ctx
.nwc_lock
);
1476 cv_destroy(&ctx
.nwc_cv
);
1477 *iomode
= committed
;
1479 uiop
->uio_resid
= tsiz
;
1485 * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the
1486 * mode set to specify the file type and the size field for rdev.
1489 nfs_mknodrpc(struct vnode
*dvp
, struct vnode
**vpp
, struct componentname
*cnp
, struct vattr
*vap
)
1491 struct nfsv2_sattr
*sp
;
1495 struct vnode
*newvp
= (struct vnode
*)0;
1496 struct nfsnode
*dnp
, *np
;
1499 int error
= 0, wccflag
= NFSV3_WCCRATTR
, gotvp
= 0;
1500 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1502 const int v3
= NFS_ISV3(dvp
);
1504 if (vap
->va_type
== VCHR
|| vap
->va_type
== VBLK
)
1505 rdev
= txdr_unsigned(vap
->va_rdev
);
1506 else if (vap
->va_type
== VFIFO
|| vap
->va_type
== VSOCK
)
1509 VOP_ABORTOP(dvp
, cnp
);
1511 return (EOPNOTSUPP
);
1513 nfsstats
.rpccnt
[NFSPROC_MKNOD
]++;
1515 nfsm_reqhead(dnp
, NFSPROC_MKNOD
, NFSX_FH(v3
) + 4 * NFSX_UNSIGNED
+
1516 + nfsm_rndup(cnp
->cn_namelen
) + NFSX_SATTR(v3
));
1517 nfsm_fhtom(dnp
, v3
);
1518 nfsm_strtom(cnp
->cn_nameptr
, cnp
->cn_namelen
, NFS_MAXNAMLEN
);
1521 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
);
1522 *tl
++ = vtonfsv3_type(vap
->va_type
);
1523 nfsm_v3attrbuild(vap
, false);
1524 if (vap
->va_type
== VCHR
|| vap
->va_type
== VBLK
) {
1525 nfsm_build(tl
, u_int32_t
*, 2 * NFSX_UNSIGNED
);
1526 *tl
++ = txdr_unsigned(major(vap
->va_rdev
));
1527 *tl
= txdr_unsigned(minor(vap
->va_rdev
));
1532 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
1533 sp
->sa_mode
= vtonfsv2_mode(vap
->va_type
, vap
->va_mode
);
1534 sp
->sa_uid
= nfs_xdrneg1
;
1535 sp
->sa_gid
= nfs_xdrneg1
;
1537 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
1538 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
1540 nfsm_request(dnp
, NFSPROC_MKNOD
, curlwp
, cnp
->cn_cred
);
1542 nfsm_mtofh(dvp
, newvp
, v3
, gotvp
);
1544 error
= nfs_lookitup(dvp
, cnp
->cn_nameptr
,
1545 cnp
->cn_namelen
, cnp
->cn_cred
, curlwp
, &np
);
1552 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
1559 if (cnp
->cn_flags
& MAKEENTRY
)
1560 nfs_cache_enter(dvp
, newvp
, cnp
);
1563 PNBUF_PUT(cnp
->cn_pnbuf
);
1564 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
1566 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
1573 * just call nfs_mknodrpc() to do the work.
1579 struct vop_mknod_args
/* {
1580 struct vnode *a_dvp;
1581 struct vnode **a_vpp;
1582 struct componentname *a_cnp;
1583 struct vattr *a_vap;
1585 struct vnode
*dvp
= ap
->a_dvp
;
1586 struct componentname
*cnp
= ap
->a_cnp
;
1589 error
= nfs_mknodrpc(dvp
, ap
->a_vpp
, cnp
, ap
->a_vap
);
1590 VN_KNOTE(dvp
, NOTE_WRITE
);
1591 if (error
== 0 || error
== EEXIST
)
1592 cache_purge1(dvp
, cnp
, 0);
1597 * nfs file create call
1602 struct vop_create_args
/* {
1603 struct vnode *a_dvp;
1604 struct vnode **a_vpp;
1605 struct componentname *a_cnp;
1606 struct vattr *a_vap;
1608 struct vnode
*dvp
= ap
->a_dvp
;
1609 struct vattr
*vap
= ap
->a_vap
;
1610 struct componentname
*cnp
= ap
->a_cnp
;
1611 struct nfsv2_sattr
*sp
;
1615 struct nfsnode
*dnp
, *np
= (struct nfsnode
*)0;
1616 struct vnode
*newvp
= (struct vnode
*)0;
1617 char *bpos
, *dpos
, *cp2
;
1618 int error
, wccflag
= NFSV3_WCCRATTR
, gotvp
= 0;
1619 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1620 const int v3
= NFS_ISV3(dvp
);
1621 u_int32_t excl_mode
= NFSV3CREATE_UNCHECKED
;
1624 * Oops, not for me..
1626 if (vap
->va_type
== VSOCK
)
1627 return (nfs_mknodrpc(dvp
, ap
->a_vpp
, cnp
, vap
));
1629 KASSERT(vap
->va_type
== VREG
);
1632 if (vap
->va_vaflags
& VA_EXCLUSIVE
) {
1633 excl_mode
= NFSV3CREATE_EXCLUSIVE
;
1638 nfsstats
.rpccnt
[NFSPROC_CREATE
]++;
1640 nfsm_reqhead(dnp
, NFSPROC_CREATE
, NFSX_FH(v3
) + 2 * NFSX_UNSIGNED
+
1641 nfsm_rndup(cnp
->cn_namelen
) + NFSX_SATTR(v3
));
1642 nfsm_fhtom(dnp
, v3
);
1643 nfsm_strtom(cnp
->cn_nameptr
, cnp
->cn_namelen
, NFS_MAXNAMLEN
);
1646 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
);
1647 if (excl_mode
== NFSV3CREATE_EXCLUSIVE
) {
1648 *tl
= txdr_unsigned(NFSV3CREATE_EXCLUSIVE
);
1649 nfsm_build(tl
, u_int32_t
*, NFSX_V3CREATEVERF
);
1650 *tl
++ = arc4random();
1653 *tl
= txdr_unsigned(excl_mode
);
1654 nfsm_v3attrbuild(vap
, false);
1659 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
1660 sp
->sa_mode
= vtonfsv2_mode(vap
->va_type
, vap
->va_mode
);
1661 sp
->sa_uid
= nfs_xdrneg1
;
1662 sp
->sa_gid
= nfs_xdrneg1
;
1664 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
1665 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
1667 nfsm_request(dnp
, NFSPROC_CREATE
, curlwp
, cnp
->cn_cred
);
1669 nfsm_mtofh(dvp
, newvp
, v3
, gotvp
);
1671 error
= nfs_lookitup(dvp
, cnp
->cn_nameptr
,
1672 cnp
->cn_namelen
, cnp
->cn_cred
, curlwp
, &np
);
1679 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
1684 * nfs_request maps NFSERR_NOTSUPP to ENOTSUP.
1686 if (v3
&& error
== ENOTSUP
) {
1687 if (excl_mode
== NFSV3CREATE_EXCLUSIVE
) {
1688 excl_mode
= NFSV3CREATE_GUARDED
;
1690 } else if (excl_mode
== NFSV3CREATE_GUARDED
) {
1691 excl_mode
= NFSV3CREATE_UNCHECKED
;
1695 } else if (v3
&& (excl_mode
== NFSV3CREATE_EXCLUSIVE
)) {
1701 * make sure that we'll update timestamps as
1702 * most server implementations use them to store
1703 * the create verifier.
1705 * XXX it's better to use TOSERVER always.
1708 if (vap
->va_atime
.tv_sec
== VNOVAL
)
1710 if (vap
->va_mtime
.tv_sec
== VNOVAL
)
1713 error
= nfs_setattrrpc(newvp
, vap
, cnp
->cn_cred
, curlwp
);
1716 if (cnp
->cn_flags
& MAKEENTRY
)
1717 nfs_cache_enter(dvp
, newvp
, cnp
);
1719 cache_purge1(dvp
, cnp
, 0);
1724 if (error
== EEXIST
)
1725 cache_purge1(dvp
, cnp
, 0);
1727 PNBUF_PUT(cnp
->cn_pnbuf
);
1728 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
1730 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
1731 VN_KNOTE(ap
->a_dvp
, NOTE_WRITE
);
1737 * nfs file remove call
1738 * To try and make nfs semantics closer to ufs semantics, a file that has
1739 * other processes using the vnode is renamed instead of removed and then
1740 * removed later on the last close.
1741 * - If v_usecount > 1
1742 * If a rename is not already in the works
1743 * call nfs_sillyrename() to set it up
1750 struct vop_remove_args
/* {
1751 struct vnodeop_desc *a_desc;
1752 struct vnode * a_dvp;
1753 struct vnode * a_vp;
1754 struct componentname * a_cnp;
1756 struct vnode
*vp
= ap
->a_vp
;
1757 struct vnode
*dvp
= ap
->a_dvp
;
1758 struct componentname
*cnp
= ap
->a_cnp
;
1759 struct nfsnode
*np
= VTONFS(vp
);
1764 if ((cnp
->cn_flags
& HASBUF
) == 0)
1765 panic("nfs_remove: no name");
1766 if (vp
->v_usecount
< 1)
1767 panic("nfs_remove: bad v_usecount");
1769 if (vp
->v_type
== VDIR
)
1771 else if (vp
->v_usecount
== 1 || (np
->n_sillyrename
&&
1772 VOP_GETATTR(vp
, &vattr
, cnp
->cn_cred
) == 0 &&
1773 vattr
.va_nlink
> 1)) {
1775 * Purge the name cache so that the chance of a lookup for
1776 * the name succeeding while the remove is in progress is
1777 * minimized. Without node locking it can still happen, such
1778 * that an I/O op returns ESTALE, but since you get this if
1779 * another host removes the file..
1783 * throw away biocache buffers, mainly to avoid
1784 * unnecessary delayed writes later.
1786 error
= nfs_vinvalbuf(vp
, 0, cnp
->cn_cred
, curlwp
, 1);
1789 error
= nfs_removerpc(dvp
, cnp
->cn_nameptr
,
1790 cnp
->cn_namelen
, cnp
->cn_cred
, curlwp
);
1791 } else if (!np
->n_sillyrename
)
1792 error
= nfs_sillyrename(dvp
, vp
, cnp
, false);
1793 PNBUF_PUT(cnp
->cn_pnbuf
);
1794 if (!error
&& nfs_getattrcache(vp
, &vattr
) == 0 &&
1795 vattr
.va_nlink
== 1) {
1796 np
->n_flag
|= NREMOVED
;
1798 NFS_INVALIDATE_ATTRCACHE(np
);
1799 VN_KNOTE(vp
, NOTE_DELETE
);
1800 VN_KNOTE(dvp
, NOTE_WRITE
);
1810 * nfs file remove rpc called from nfs_inactive
1813 nfs_removeit(struct sillyrename
*sp
)
1816 return (nfs_removerpc(sp
->s_dvp
, sp
->s_name
, sp
->s_namlen
, sp
->s_cred
,
1821 * Nfs remove rpc, called from nfs_remove() and nfs_removeit().
1824 nfs_removerpc(struct vnode
*dvp
, const char *name
, int namelen
, kauth_cred_t cred
, struct lwp
*l
)
1834 int error
= 0, wccflag
= NFSV3_WCCRATTR
;
1835 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1836 const int v3
= NFS_ISV3(dvp
);
1838 struct nfsnode
*dnp
= VTONFS(dvp
);
1840 nfsstats
.rpccnt
[NFSPROC_REMOVE
]++;
1841 nfsm_reqhead(dnp
, NFSPROC_REMOVE
,
1842 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(namelen
));
1843 nfsm_fhtom(dnp
, v3
);
1844 nfsm_strtom(name
, namelen
, NFS_MAXNAMLEN
);
1845 nfsm_request1(dnp
, NFSPROC_REMOVE
, l
, cred
, &rexmit
);
1848 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
1851 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
1853 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
1855 * Kludge City: If the first reply to the remove rpc is lost..
1856 * the reply to the retransmitted request will be ENOENT
1857 * since the file was in fact removed
1858 * Therefore, we cheat and return success.
1860 if (rexmit
&& error
== ENOENT
)
1866 * nfs file rename call
1871 struct vop_rename_args
/* {
1872 struct vnode *a_fdvp;
1873 struct vnode *a_fvp;
1874 struct componentname *a_fcnp;
1875 struct vnode *a_tdvp;
1876 struct vnode *a_tvp;
1877 struct componentname *a_tcnp;
1879 struct vnode
*fvp
= ap
->a_fvp
;
1880 struct vnode
*tvp
= ap
->a_tvp
;
1881 struct vnode
*fdvp
= ap
->a_fdvp
;
1882 struct vnode
*tdvp
= ap
->a_tdvp
;
1883 struct componentname
*tcnp
= ap
->a_tcnp
;
1884 struct componentname
*fcnp
= ap
->a_fcnp
;
1888 if ((tcnp
->cn_flags
& HASBUF
) == 0 ||
1889 (fcnp
->cn_flags
& HASBUF
) == 0)
1890 panic("nfs_rename: no name");
1892 /* Check for cross-device rename */
1893 if ((fvp
->v_mount
!= tdvp
->v_mount
) ||
1894 (tvp
&& (fvp
->v_mount
!= tvp
->v_mount
))) {
1900 * If the tvp exists and is in use, sillyrename it before doing the
1901 * rename of the new file over it.
1903 * Have sillyrename use link instead of rename if possible,
1904 * so that we don't lose the file if the rename fails, and so
1905 * that there's no window when the "to" file doesn't exist.
1907 if (tvp
&& tvp
->v_usecount
> 1 && !VTONFS(tvp
)->n_sillyrename
&&
1908 tvp
->v_type
!= VDIR
&& !nfs_sillyrename(tdvp
, tvp
, tcnp
, true)) {
1909 VN_KNOTE(tvp
, NOTE_DELETE
);
1914 error
= nfs_renamerpc(fdvp
, fcnp
->cn_nameptr
, fcnp
->cn_namelen
,
1915 tdvp
, tcnp
->cn_nameptr
, tcnp
->cn_namelen
, tcnp
->cn_cred
,
1918 VN_KNOTE(fdvp
, NOTE_WRITE
);
1919 VN_KNOTE(tdvp
, NOTE_WRITE
);
1920 if (error
== 0 || error
== EEXIST
) {
1921 if (fvp
->v_type
== VDIR
)
1924 cache_purge1(fdvp
, fcnp
, 0);
1925 if (tvp
!= NULL
&& tvp
->v_type
== VDIR
)
1928 cache_purge1(tdvp
, tcnp
, 0);
1943 * nfs file rename rpc called from nfs_remove() above
1946 nfs_renameit(struct vnode
*sdvp
, struct componentname
*scnp
, struct sillyrename
*sp
)
1948 return (nfs_renamerpc(sdvp
, scnp
->cn_nameptr
, scnp
->cn_namelen
,
1949 sdvp
, sp
->s_name
, sp
->s_namlen
, scnp
->cn_cred
, curlwp
));
1953 * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit().
1956 nfs_renamerpc(struct vnode
*fdvp
, const char *fnameptr
, int fnamelen
, struct vnode
*tdvp
, const char *tnameptr
, int tnamelen
, kauth_cred_t cred
, struct lwp
*l
)
1966 int error
= 0, fwccflag
= NFSV3_WCCRATTR
, twccflag
= NFSV3_WCCRATTR
;
1967 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1968 const int v3
= NFS_ISV3(fdvp
);
1970 struct nfsnode
*fdnp
= VTONFS(fdvp
);
1972 nfsstats
.rpccnt
[NFSPROC_RENAME
]++;
1973 nfsm_reqhead(fdnp
, NFSPROC_RENAME
,
1974 (NFSX_FH(v3
) + NFSX_UNSIGNED
)*2 + nfsm_rndup(fnamelen
) +
1975 nfsm_rndup(tnamelen
));
1976 nfsm_fhtom(fdnp
, v3
);
1977 nfsm_strtom(fnameptr
, fnamelen
, NFS_MAXNAMLEN
);
1978 nfsm_fhtom(VTONFS(tdvp
), v3
);
1979 nfsm_strtom(tnameptr
, tnamelen
, NFS_MAXNAMLEN
);
1980 nfsm_request1(fdnp
, NFSPROC_RENAME
, l
, cred
, &rexmit
);
1983 nfsm_wcc_data(fdvp
, fwccflag
, 0, !error
);
1984 nfsm_wcc_data(tdvp
, twccflag
, 0, !error
);
1988 VTONFS(fdvp
)->n_flag
|= NMODIFIED
;
1989 VTONFS(tdvp
)->n_flag
|= NMODIFIED
;
1991 NFS_INVALIDATE_ATTRCACHE(VTONFS(fdvp
));
1993 NFS_INVALIDATE_ATTRCACHE(VTONFS(tdvp
));
1995 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
1997 if (rexmit
&& error
== ENOENT
)
2003 * NFS link RPC, called from nfs_link.
2004 * Assumes dvp and vp locked, and leaves them that way.
2008 nfs_linkrpc(struct vnode
*dvp
, struct vnode
*vp
, const char *name
,
2009 size_t namelen
, kauth_cred_t cred
, struct lwp
*l
)
2019 int error
= 0, wccflag
= NFSV3_WCCRATTR
, attrflag
= 0;
2020 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2021 const int v3
= NFS_ISV3(dvp
);
2023 struct nfsnode
*np
= VTONFS(vp
);
2025 nfsstats
.rpccnt
[NFSPROC_LINK
]++;
2026 nfsm_reqhead(np
, NFSPROC_LINK
,
2027 NFSX_FH(v3
)*2 + NFSX_UNSIGNED
+ nfsm_rndup(namelen
));
2029 nfsm_fhtom(VTONFS(dvp
), v3
);
2030 nfsm_strtom(name
, namelen
, NFS_MAXNAMLEN
);
2031 nfsm_request1(np
, NFSPROC_LINK
, l
, cred
, &rexmit
);
2034 nfsm_postop_attr(vp
, attrflag
, 0);
2035 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
2040 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
2042 NFS_INVALIDATE_ATTRCACHE(VTONFS(vp
));
2044 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
2047 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
2049 if (rexmit
&& error
== EEXIST
)
2056 * nfs hard link create call
2061 struct vop_link_args
/* {
2062 struct vnode *a_dvp;
2064 struct componentname *a_cnp;
2066 struct vnode
*vp
= ap
->a_vp
;
2067 struct vnode
*dvp
= ap
->a_dvp
;
2068 struct componentname
*cnp
= ap
->a_cnp
;
2071 if (dvp
->v_mount
!= vp
->v_mount
) {
2072 VOP_ABORTOP(dvp
, cnp
);
2077 error
= vn_lock(vp
, LK_EXCLUSIVE
);
2079 VOP_ABORTOP(dvp
, cnp
);
2086 * Push all writes to the server, so that the attribute cache
2087 * doesn't get "out of sync" with the server.
2088 * XXX There should be a better way!
2090 VOP_FSYNC(vp
, cnp
->cn_cred
, FSYNC_WAIT
, 0, 0);
2092 error
= nfs_linkrpc(dvp
, vp
, cnp
->cn_nameptr
, cnp
->cn_namelen
,
2093 cnp
->cn_cred
, curlwp
);
2096 cache_purge1(dvp
, cnp
, 0);
2097 PNBUF_PUT(cnp
->cn_pnbuf
);
2100 VN_KNOTE(vp
, NOTE_LINK
);
2101 VN_KNOTE(dvp
, NOTE_WRITE
);
2107 * nfs symbolic link create call
2110 nfs_symlink(void *v
)
2112 struct vop_symlink_args
/* {
2113 struct vnode *a_dvp;
2114 struct vnode **a_vpp;
2115 struct componentname *a_cnp;
2116 struct vattr *a_vap;
2119 struct vnode
*dvp
= ap
->a_dvp
;
2120 struct vattr
*vap
= ap
->a_vap
;
2121 struct componentname
*cnp
= ap
->a_cnp
;
2122 struct nfsv2_sattr
*sp
;
2126 char *bpos
, *dpos
, *cp2
;
2127 int slen
, error
= 0, wccflag
= NFSV3_WCCRATTR
, gotvp
;
2128 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2129 struct vnode
*newvp
= (struct vnode
*)0;
2130 const int v3
= NFS_ISV3(dvp
);
2132 struct nfsnode
*dnp
= VTONFS(dvp
);
2135 nfsstats
.rpccnt
[NFSPROC_SYMLINK
]++;
2136 slen
= strlen(ap
->a_target
);
2137 nfsm_reqhead(dnp
, NFSPROC_SYMLINK
, NFSX_FH(v3
) + 2*NFSX_UNSIGNED
+
2138 nfsm_rndup(cnp
->cn_namelen
) + nfsm_rndup(slen
) + NFSX_SATTR(v3
));
2139 nfsm_fhtom(dnp
, v3
);
2140 nfsm_strtom(cnp
->cn_nameptr
, cnp
->cn_namelen
, NFS_MAXNAMLEN
);
2143 nfsm_v3attrbuild(vap
, false);
2145 nfsm_strtom(ap
->a_target
, slen
, NFS_MAXPATHLEN
);
2148 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
2149 sp
->sa_mode
= vtonfsv2_mode(VLNK
, vap
->va_mode
);
2150 sp
->sa_uid
= nfs_xdrneg1
;
2151 sp
->sa_gid
= nfs_xdrneg1
;
2152 sp
->sa_size
= nfs_xdrneg1
;
2153 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
2154 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
2157 nfsm_request1(dnp
, NFSPROC_SYMLINK
, curlwp
, cnp
->cn_cred
,
2162 nfsm_mtofh(dvp
, newvp
, v3
, gotvp
);
2163 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
2168 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
2170 if (rexmit
&& error
== EEXIST
)
2172 if (error
== 0 || error
== EEXIST
)
2173 cache_purge1(dvp
, cnp
, 0);
2174 if (error
== 0 && newvp
== NULL
) {
2175 struct nfsnode
*np
= NULL
;
2177 error
= nfs_lookitup(dvp
, cnp
->cn_nameptr
, cnp
->cn_namelen
,
2178 cnp
->cn_cred
, curlwp
, &np
);
2188 PNBUF_PUT(cnp
->cn_pnbuf
);
2189 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
2191 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
2192 VN_KNOTE(dvp
, NOTE_WRITE
);
2203 struct vop_mkdir_args
/* {
2204 struct vnode *a_dvp;
2205 struct vnode **a_vpp;
2206 struct componentname *a_cnp;
2207 struct vattr *a_vap;
2209 struct vnode
*dvp
= ap
->a_dvp
;
2210 struct vattr
*vap
= ap
->a_vap
;
2211 struct componentname
*cnp
= ap
->a_cnp
;
2212 struct nfsv2_sattr
*sp
;
2217 struct nfsnode
*dnp
= VTONFS(dvp
), *np
= (struct nfsnode
*)0;
2218 struct vnode
*newvp
= (struct vnode
*)0;
2219 char *bpos
, *dpos
, *cp2
;
2220 int error
= 0, wccflag
= NFSV3_WCCRATTR
;
2223 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2224 const int v3
= NFS_ISV3(dvp
);
2226 len
= cnp
->cn_namelen
;
2227 nfsstats
.rpccnt
[NFSPROC_MKDIR
]++;
2228 nfsm_reqhead(dnp
, NFSPROC_MKDIR
,
2229 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(len
) + NFSX_SATTR(v3
));
2230 nfsm_fhtom(dnp
, v3
);
2231 nfsm_strtom(cnp
->cn_nameptr
, len
, NFS_MAXNAMLEN
);
2234 nfsm_v3attrbuild(vap
, false);
2238 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
2239 sp
->sa_mode
= vtonfsv2_mode(VDIR
, vap
->va_mode
);
2240 sp
->sa_uid
= nfs_xdrneg1
;
2241 sp
->sa_gid
= nfs_xdrneg1
;
2242 sp
->sa_size
= nfs_xdrneg1
;
2243 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
2244 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
2246 nfsm_request1(dnp
, NFSPROC_MKDIR
, curlwp
, cnp
->cn_cred
, &rexmit
);
2248 nfsm_mtofh(dvp
, newvp
, v3
, gotvp
);
2250 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
2252 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
2254 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
2256 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry
2257 * if we can succeed in looking up the directory.
2259 if ((rexmit
&& error
== EEXIST
) || (!error
&& !gotvp
)) {
2262 newvp
= (struct vnode
*)0;
2264 error
= nfs_lookitup(dvp
, cnp
->cn_nameptr
, len
, cnp
->cn_cred
,
2268 if (newvp
->v_type
!= VDIR
|| newvp
== dvp
)
2280 VN_KNOTE(dvp
, NOTE_WRITE
| NOTE_LINK
);
2281 if (cnp
->cn_flags
& MAKEENTRY
)
2282 nfs_cache_enter(dvp
, newvp
, cnp
);
2285 PNBUF_PUT(cnp
->cn_pnbuf
);
2291 * nfs remove directory call
2296 struct vop_rmdir_args
/* {
2297 struct vnode *a_dvp;
2299 struct componentname *a_cnp;
2301 struct vnode
*vp
= ap
->a_vp
;
2302 struct vnode
*dvp
= ap
->a_dvp
;
2303 struct componentname
*cnp
= ap
->a_cnp
;
2312 int error
= 0, wccflag
= NFSV3_WCCRATTR
;
2314 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2315 const int v3
= NFS_ISV3(dvp
);
2316 struct nfsnode
*dnp
;
2321 PNBUF_PUT(cnp
->cn_pnbuf
);
2324 nfsstats
.rpccnt
[NFSPROC_RMDIR
]++;
2326 nfsm_reqhead(dnp
, NFSPROC_RMDIR
,
2327 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(cnp
->cn_namelen
));
2328 nfsm_fhtom(dnp
, v3
);
2329 nfsm_strtom(cnp
->cn_nameptr
, cnp
->cn_namelen
, NFS_MAXNAMLEN
);
2330 nfsm_request1(dnp
, NFSPROC_RMDIR
, curlwp
, cnp
->cn_cred
, &rexmit
);
2333 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
2336 PNBUF_PUT(cnp
->cn_pnbuf
);
2337 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
2339 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
2340 VN_KNOTE(dvp
, NOTE_WRITE
| NOTE_LINK
);
2341 VN_KNOTE(vp
, NOTE_DELETE
);
2346 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
2348 if (rexmit
&& error
== ENOENT
)
2357 nfs_readdir(void *v
)
2359 struct vop_readdir_args
/* {
2362 kauth_cred_t a_cred;
2367 struct vnode
*vp
= ap
->a_vp
;
2368 struct uio
*uio
= ap
->a_uio
;
2369 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
2370 char *base
= uio
->uio_iov
->iov_base
;
2374 off_t
*cookies
= NULL
;
2375 int ncookies
= 0, nc
;
2377 if (vp
->v_type
!= VDIR
)
2380 lost
= uio
->uio_resid
& (NFS_DIRFRAGSIZ
- 1);
2381 count
= uio
->uio_resid
- lost
;
2386 * Call nfs_bioread() to do the real work.
2388 tresid
= uio
->uio_resid
= count
;
2389 error
= nfs_bioread(vp
, uio
, 0, ap
->a_cred
,
2390 ap
->a_cookies
? NFSBIO_CACHECOOKIES
: 0);
2392 if (!error
&& ap
->a_cookies
) {
2393 ncookies
= count
/ 16;
2394 cookies
= malloc(sizeof (off_t
) * ncookies
, M_TEMP
, M_WAITOK
);
2395 *ap
->a_cookies
= cookies
;
2398 if (!error
&& uio
->uio_resid
== tresid
) {
2399 uio
->uio_resid
+= lost
;
2400 nfsstats
.direofcache_misses
++;
2402 *ap
->a_ncookies
= 0;
2407 if (!error
&& ap
->a_cookies
) {
2409 * Only the NFS server and emulations use cookies, and they
2410 * load the directory block into system space, so we can
2411 * just look at it directly.
2413 if (!VMSPACE_IS_KERNEL_P(uio
->uio_vmspace
) ||
2414 uio
->uio_iovcnt
!= 1)
2415 panic("nfs_readdir: lost in space");
2416 for (nc
= 0; ncookies
-- &&
2417 base
< (char *)uio
->uio_iov
->iov_base
; nc
++){
2418 dp
= (struct dirent
*) base
;
2419 if (dp
->d_reclen
== 0)
2421 if (nmp
->nm_flag
& NFSMNT_XLATECOOKIE
)
2422 *(cookies
++) = (off_t
)NFS_GETCOOKIE32(dp
);
2424 *(cookies
++) = NFS_GETCOOKIE(dp
);
2425 base
+= dp
->d_reclen
;
2428 ((char *)uio
->uio_iov
->iov_base
- base
);
2429 uio
->uio_iov
->iov_len
+=
2430 ((char *)uio
->uio_iov
->iov_base
- base
);
2431 uio
->uio_iov
->iov_base
= base
;
2432 *ap
->a_ncookies
= nc
;
2435 uio
->uio_resid
+= lost
;
2442 * Called from below the buffer cache by nfs_doio().
2445 nfs_readdirrpc(struct vnode
*vp
, struct uio
*uiop
, kauth_cred_t cred
)
2448 struct dirent
*dp
= NULL
;
2452 char *bpos
, *dpos
, *cp2
;
2453 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2454 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
2455 struct nfsnode
*dnp
= VTONFS(vp
);
2457 int error
= 0, more_dirs
= 1, blksiz
= 0, bigenough
= 1;
2461 int nrpcs
= 0, reclen
;
2462 const int v3
= NFS_ISV3(vp
);
2466 * Should be called from buffer cache, so only amount of
2467 * NFS_DIRBLKSIZ will be requested.
2469 if (uiop
->uio_iovcnt
!= 1 || uiop
->uio_resid
!= NFS_DIRBLKSIZ
)
2470 panic("nfs readdirrpc bad uio");
2474 * Loop around doing readdir rpc's of size nm_readdirsize
2475 * truncated to a multiple of NFS_DIRFRAGSIZ.
2476 * The stopping criteria is EOF or buffer full.
2478 while (more_dirs
&& bigenough
) {
2480 * Heuristic: don't bother to do another RPC to further
2481 * fill up this block if there is not much room left. (< 50%
2482 * of the readdir RPC size). This wastes some buffer space
2483 * but can save up to 50% in RPC calls.
2485 if (nrpcs
> 0 && uiop
->uio_resid
< (nmp
->nm_readdirsize
/ 2)) {
2489 nfsstats
.rpccnt
[NFSPROC_READDIR
]++;
2490 nfsm_reqhead(dnp
, NFSPROC_READDIR
, NFSX_FH(v3
) +
2492 nfsm_fhtom(dnp
, v3
);
2495 nfsm_build(tl
, u_int32_t
*, 5 * NFSX_UNSIGNED
);
2496 if (nmp
->nm_iflag
& NFSMNT_SWAPCOOKIE
) {
2497 txdr_swapcookie3(uiop
->uio_offset
, tl
);
2499 txdr_cookie3(uiop
->uio_offset
, tl
);
2502 *tl
++ = dnp
->n_cookieverf
.nfsuquad
[0];
2503 *tl
++ = dnp
->n_cookieverf
.nfsuquad
[1];
2507 nfsm_build(tl
, u_int32_t
*, 2 * NFSX_UNSIGNED
);
2508 *tl
++ = txdr_unsigned(uiop
->uio_offset
);
2510 *tl
= txdr_unsigned(nmp
->nm_readdirsize
);
2511 nfsm_request(dnp
, NFSPROC_READDIR
, curlwp
, cred
);
2515 nfsm_postop_attr(vp
, attrflag
, 0);
2517 nfsm_dissect(tl
, u_int32_t
*,
2519 dnp
->n_cookieverf
.nfsuquad
[0] = *tl
++;
2520 dnp
->n_cookieverf
.nfsuquad
[1] = *tl
;
2527 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2528 more_dirs
= fxdr_unsigned(int, *tl
);
2530 /* loop thru the dir entries, doctoring them to 4bsd form */
2531 while (more_dirs
&& bigenough
) {
2534 nfsm_dissect(tl
, u_int32_t
*,
2536 fileno
= fxdr_hyper(tl
);
2537 len
= fxdr_unsigned(int, *(tl
+ 2));
2541 nfsm_dissect(tl
, u_int32_t
*,
2543 fileno
= fxdr_unsigned(u_quad_t
, *tl
++);
2544 len
= fxdr_unsigned(int, *tl
);
2546 if (len
<= 0 || len
> NFS_MAXNAMLEN
) {
2551 /* for cookie stashing */
2552 reclen
= _DIRENT_RECLEN(dp
, len
) + 2 * sizeof(off_t
);
2553 left
= NFS_DIRFRAGSIZ
- blksiz
;
2554 if (reclen
> left
) {
2555 memset(uiop
->uio_iov
->iov_base
, 0, left
);
2556 dp
->d_reclen
+= left
;
2557 UIO_ADVANCE(uiop
, left
);
2559 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2561 if (reclen
> uiop
->uio_resid
)
2566 dp
= (struct dirent
*)uiop
->uio_iov
->iov_base
;
2567 dp
->d_fileno
= fileno
;
2569 dp
->d_reclen
= reclen
;
2570 dp
->d_type
= DT_UNKNOWN
;
2572 if (blksiz
== NFS_DIRFRAGSIZ
)
2574 UIO_ADVANCE(uiop
, DIRHDSIZ
);
2575 nfsm_mtouio(uiop
, len
);
2576 tlen
= reclen
- (DIRHDSIZ
+ len
);
2577 (void)memset(uiop
->uio_iov
->iov_base
, 0, tlen
);
2578 UIO_ADVANCE(uiop
, tlen
);
2580 nfsm_adv(nfsm_rndup(len
));
2583 nfsm_dissect(tl
, u_int32_t
*,
2588 nfsm_dissect(tl
, u_int32_t
*,
2594 if (nmp
->nm_iflag
& NFSMNT_SWAPCOOKIE
)
2596 fxdr_swapcookie3(tl
);
2605 fxdr_unsigned(off_t
, *tl
);
2607 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2613 more_dirs
= fxdr_unsigned(int, *tl
);
2616 * If at end of rpc data, get the eof boolean
2619 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2620 more_dirs
= (fxdr_unsigned(int, *tl
) == 0);
2623 * kludge: if we got no entries, treat it as EOF.
2624 * some server sometimes send a reply without any
2626 * although it might mean the server has very long name,
2627 * we can't handle such entries anyway.
2630 if (uiop
->uio_resid
>= NFS_DIRBLKSIZ
)
2636 * Fill last record, iff any, out to a multiple of NFS_DIRFRAGSIZ
2637 * by increasing d_reclen for the last record.
2640 left
= NFS_DIRFRAGSIZ
- blksiz
;
2641 memset(uiop
->uio_iov
->iov_base
, 0, left
);
2642 dp
->d_reclen
+= left
;
2643 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2644 UIO_ADVANCE(uiop
, left
);
2648 * We are now either at the end of the directory or have filled the
2652 dnp
->n_direofoffset
= uiop
->uio_offset
;
2653 dnp
->n_flag
|= NEOFVALID
;
2661 * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc().
2664 nfs_readdirplusrpc(struct vnode
*vp
, struct uio
*uiop
, kauth_cred_t cred
)
2667 struct dirent
*dp
= NULL
;
2671 struct vnode
*newvp
;
2672 char *bpos
, *dpos
, *cp2
;
2673 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2674 struct nameidata nami
, *ndp
= &nami
;
2675 struct componentname
*cnp
= &ndp
->ni_cnd
;
2676 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
2677 struct nfsnode
*dnp
= VTONFS(vp
), *np
;
2680 int error
= 0, more_dirs
= 1, blksiz
= 0, doit
, bigenough
= 1, i
;
2681 int attrflag
, fhsize
, nrpcs
= 0, reclen
;
2682 struct nfs_fattr fattr
, *fp
;
2685 if (uiop
->uio_iovcnt
!= 1 || uiop
->uio_resid
!= NFS_DIRBLKSIZ
)
2686 panic("nfs readdirplusrpc bad uio");
2692 * Loop around doing readdir rpc's of size nm_readdirsize
2693 * truncated to a multiple of NFS_DIRFRAGSIZ.
2694 * The stopping criteria is EOF or buffer full.
2696 while (more_dirs
&& bigenough
) {
2697 if (nrpcs
> 0 && uiop
->uio_resid
< (nmp
->nm_readdirsize
/ 2)) {
2701 nfsstats
.rpccnt
[NFSPROC_READDIRPLUS
]++;
2702 nfsm_reqhead(dnp
, NFSPROC_READDIRPLUS
,
2703 NFSX_FH(1) + 6 * NFSX_UNSIGNED
);
2705 nfsm_build(tl
, u_int32_t
*, 6 * NFSX_UNSIGNED
);
2706 if (nmp
->nm_iflag
& NFSMNT_SWAPCOOKIE
) {
2707 txdr_swapcookie3(uiop
->uio_offset
, tl
);
2709 txdr_cookie3(uiop
->uio_offset
, tl
);
2712 *tl
++ = dnp
->n_cookieverf
.nfsuquad
[0];
2713 *tl
++ = dnp
->n_cookieverf
.nfsuquad
[1];
2714 *tl
++ = txdr_unsigned(nmp
->nm_readdirsize
);
2715 *tl
= txdr_unsigned(nmp
->nm_rsize
);
2716 nfsm_request(dnp
, NFSPROC_READDIRPLUS
, curlwp
, cred
);
2717 nfsm_postop_attr(vp
, attrflag
, 0);
2723 nfsm_dissect(tl
, u_int32_t
*, 3 * NFSX_UNSIGNED
);
2724 dnp
->n_cookieverf
.nfsuquad
[0] = *tl
++;
2725 dnp
->n_cookieverf
.nfsuquad
[1] = *tl
++;
2726 more_dirs
= fxdr_unsigned(int, *tl
);
2728 /* loop thru the dir entries, doctoring them to 4bsd form */
2729 while (more_dirs
&& bigenough
) {
2730 nfsm_dissect(tl
, u_int32_t
*, 3 * NFSX_UNSIGNED
);
2731 fileno
= fxdr_hyper(tl
);
2732 len
= fxdr_unsigned(int, *(tl
+ 2));
2733 if (len
<= 0 || len
> NFS_MAXNAMLEN
) {
2738 /* for cookie stashing */
2739 reclen
= _DIRENT_RECLEN(dp
, len
) + 2 * sizeof(off_t
);
2740 left
= NFS_DIRFRAGSIZ
- blksiz
;
2741 if (reclen
> left
) {
2743 * DIRFRAGSIZ is aligned, no need to align
2746 memset(uiop
->uio_iov
->iov_base
, 0, left
);
2747 dp
->d_reclen
+= left
;
2748 UIO_ADVANCE(uiop
, left
);
2749 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2752 if (reclen
> uiop
->uio_resid
)
2757 dp
= (struct dirent
*)uiop
->uio_iov
->iov_base
;
2758 dp
->d_fileno
= fileno
;
2760 dp
->d_reclen
= reclen
;
2761 dp
->d_type
= DT_UNKNOWN
;
2763 if (blksiz
== NFS_DIRFRAGSIZ
)
2765 UIO_ADVANCE(uiop
, DIRHDSIZ
);
2766 nfsm_mtouio(uiop
, len
);
2767 tlen
= reclen
- (DIRHDSIZ
+ len
);
2768 (void)memset(uiop
->uio_iov
->iov_base
, 0, tlen
);
2769 UIO_ADVANCE(uiop
, tlen
);
2770 cnp
->cn_nameptr
= dp
->d_name
;
2771 cnp
->cn_namelen
= dp
->d_namlen
;
2773 nfsm_adv(nfsm_rndup(len
));
2774 nfsm_dissect(tl
, u_int32_t
*, 3 * NFSX_UNSIGNED
);
2776 if (nmp
->nm_iflag
& NFSMNT_SWAPCOOKIE
)
2778 fxdr_swapcookie3(tl
);
2782 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2787 * Since the attributes are before the file handle
2788 * (sigh), we must skip over the attributes and then
2789 * come back and get them.
2791 attrflag
= fxdr_unsigned(int, *tl
);
2793 nfsm_dissect(fp
, struct nfs_fattr
*, NFSX_V3FATTR
);
2794 memcpy(&fattr
, fp
, NFSX_V3FATTR
);
2795 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2796 doit
= fxdr_unsigned(int, *tl
);
2798 nfsm_getfh(fhp
, fhsize
, 1);
2799 if (NFS_CMPFH(dnp
, fhp
, fhsize
)) {
2804 error
= nfs_nget1(vp
->v_mount
, fhp
,
2805 fhsize
, &np
, LK_NOWAIT
);
2812 nfs_loadattrcache(&newvp
, &fattr
, 0, 0);
2815 IFTODT(VTTOIF(np
->n_vattr
->va_type
));
2816 if (cnp
->cn_namelen
<= NCHNAMLEN
) {
2818 xcp
= cnp
->cn_nameptr
+
2821 namei_hash(cnp
->cn_nameptr
, &xcp
);
2822 nfs_cache_enter(ndp
->ni_dvp
,
2830 /* Just skip over the file handle */
2831 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2832 i
= fxdr_unsigned(int, *tl
);
2833 nfsm_adv(nfsm_rndup(i
));
2835 if (newvp
!= NULLVP
) {
2842 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2843 more_dirs
= fxdr_unsigned(int, *tl
);
2846 * If at end of rpc data, get the eof boolean
2849 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2850 more_dirs
= (fxdr_unsigned(int, *tl
) == 0);
2853 * kludge: see a comment in nfs_readdirrpc.
2856 if (uiop
->uio_resid
>= NFS_DIRBLKSIZ
)
2862 * Fill last record, iff any, out to a multiple of NFS_DIRFRAGSIZ
2863 * by increasing d_reclen for the last record.
2866 left
= NFS_DIRFRAGSIZ
- blksiz
;
2867 memset(uiop
->uio_iov
->iov_base
, 0, left
);
2868 dp
->d_reclen
+= left
;
2869 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2870 UIO_ADVANCE(uiop
, left
);
2874 * We are now either at the end of the directory or have filled the
2878 dnp
->n_direofoffset
= uiop
->uio_offset
;
2879 dnp
->n_flag
|= NEOFVALID
;
2882 if (newvp
!= NULLVP
) {
2893 * Silly rename. To make the NFS filesystem that is stateless look a little
2894 * more like the "ufs" a remove of an active vnode is translated to a rename
2895 * to a funny looking filename that is removed by nfs_inactive on the
2896 * nfsnode. There is the potential for another process on a different client
2897 * to create the same funny name between the nfs_lookitup() fails and the
2898 * nfs_rename() completes, but...
2901 nfs_sillyrename(struct vnode
*dvp
, struct vnode
*vp
, struct componentname
*cnp
, bool dolink
)
2903 struct sillyrename
*sp
;
2911 if (vp
->v_type
== VDIR
)
2912 panic("nfs: sillyrename dir");
2914 sp
= kmem_alloc(sizeof(*sp
), KM_SLEEP
);
2915 sp
->s_cred
= kauth_cred_dup(cnp
->cn_cred
);
2919 /* Fudge together a funny name */
2920 pid
= curlwp
->l_proc
->p_pid
;
2921 memcpy(sp
->s_name
, ".nfsAxxxx4.4", 13);
2923 sp
->s_name
[8] = hexdigits
[pid
& 0xf];
2924 sp
->s_name
[7] = hexdigits
[(pid
>> 4) & 0xf];
2925 sp
->s_name
[6] = hexdigits
[(pid
>> 8) & 0xf];
2926 sp
->s_name
[5] = hexdigits
[(pid
>> 12) & 0xf];
2928 /* Try lookitups until we get one that isn't there */
2929 while (nfs_lookitup(dvp
, sp
->s_name
, sp
->s_namlen
, sp
->s_cred
,
2930 curlwp
, (struct nfsnode
**)0) == 0) {
2932 if (sp
->s_name
[4] > 'z') {
2938 error
= nfs_linkrpc(dvp
, vp
, sp
->s_name
, sp
->s_namlen
,
2939 sp
->s_cred
, curlwp
);
2941 * nfs_request maps NFSERR_NOTSUPP to ENOTSUP.
2943 if (error
== ENOTSUP
) {
2944 error
= nfs_renameit(dvp
, cnp
, sp
);
2947 error
= nfs_renameit(dvp
, cnp
, sp
);
2951 error
= nfs_lookitup(dvp
, sp
->s_name
, sp
->s_namlen
, sp
->s_cred
,
2953 np
->n_sillyrename
= sp
;
2957 kauth_cred_free(sp
->s_cred
);
2958 kmem_free(sp
, sizeof(*sp
));
2963 * Look up a file name and optionally either update the file handle or
2964 * allocate an nfsnode, depending on the value of npp.
2965 * npp == NULL --> just do the lookup
2966 * *npp == NULL --> allocate a new nfsnode and make sure attributes are
2968 * *npp != NULL --> update the file handle in the vnode
2971 nfs_lookitup(struct vnode
*dvp
, const char *name
, int len
, kauth_cred_t cred
, struct lwp
*l
, struct nfsnode
**npp
)
2976 struct vnode
*newvp
= (struct vnode
*)0;
2977 struct nfsnode
*np
, *dnp
= VTONFS(dvp
);
2978 char *bpos
, *dpos
, *cp2
;
2979 int error
= 0, fhlen
;
2983 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2985 const int v3
= NFS_ISV3(dvp
);
2987 nfsstats
.rpccnt
[NFSPROC_LOOKUP
]++;
2988 nfsm_reqhead(dnp
, NFSPROC_LOOKUP
,
2989 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(len
));
2990 nfsm_fhtom(dnp
, v3
);
2991 nfsm_strtom(name
, len
, NFS_MAXNAMLEN
);
2992 nfsm_request(dnp
, NFSPROC_LOOKUP
, l
, cred
);
2993 if (npp
&& !error
) {
2994 nfsm_getfh(nfhp
, fhlen
, v3
);
2997 if (np
->n_fhsize
> NFS_SMALLFH
&& fhlen
<= NFS_SMALLFH
) {
2998 kmem_free(np
->n_fhp
, np
->n_fhsize
);
2999 np
->n_fhp
= &np
->n_fh
;
3001 #if NFS_SMALLFH < NFSX_V3FHMAX
3002 else if (np
->n_fhsize
<= NFS_SMALLFH
&& fhlen
> NFS_SMALLFH
)
3003 np
->n_fhp
= kmem_alloc(fhlen
, KM_SLEEP
);
3005 memcpy(np
->n_fhp
, nfhp
, fhlen
);
3006 np
->n_fhsize
= fhlen
;
3008 } else if (NFS_CMPFH(dnp
, nfhp
, fhlen
)) {
3013 error
= nfs_nget(dvp
->v_mount
, nfhp
, fhlen
, &np
);
3022 nfsm_postop_attr(newvp
, attrflag
, 0);
3023 if (!attrflag
&& *npp
== NULL
) {
3030 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
3033 if (npp
&& *npp
== NULL
) {
3045 * Nfs Version 3 commit rpc
3048 nfs_commit(struct vnode
*vp
, off_t offset
, uint32_t cnt
, struct lwp
*l
)
3053 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
3054 char *bpos
, *dpos
, *cp2
;
3055 int error
= 0, wccflag
= NFSV3_WCCRATTR
;
3056 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
3059 KASSERT(NFS_ISV3(vp
));
3061 #ifdef NFS_DEBUG_COMMIT
3062 printf("commit %lu - %lu\n", (unsigned long)offset
,
3063 (unsigned long)(offset
+ cnt
));
3066 mutex_enter(&nmp
->nm_lock
);
3067 if ((nmp
->nm_iflag
& NFSMNT_HASWRITEVERF
) == 0) {
3068 mutex_exit(&nmp
->nm_lock
);
3071 mutex_exit(&nmp
->nm_lock
);
3072 nfsstats
.rpccnt
[NFSPROC_COMMIT
]++;
3074 nfsm_reqhead(np
, NFSPROC_COMMIT
, NFSX_FH(1));
3076 nfsm_build(tl
, u_int32_t
*, 3 * NFSX_UNSIGNED
);
3077 txdr_hyper(offset
, tl
);
3079 *tl
= txdr_unsigned(cnt
);
3080 nfsm_request(np
, NFSPROC_COMMIT
, l
, np
->n_wcred
);
3081 nfsm_wcc_data(vp
, wccflag
, NAC_NOTRUNC
, false);
3083 nfsm_dissect(tl
, u_int32_t
*, NFSX_V3WRITEVERF
);
3084 mutex_enter(&nmp
->nm_lock
);
3085 if ((nmp
->nm_iflag
& NFSMNT_STALEWRITEVERF
) ||
3086 memcmp(nmp
->nm_writeverf
, tl
, NFSX_V3WRITEVERF
)) {
3087 memcpy(nmp
->nm_writeverf
, tl
, NFSX_V3WRITEVERF
);
3088 error
= NFSERR_STALEWRITEVERF
;
3089 nmp
->nm_iflag
|= NFSMNT_STALEWRITEVERF
;
3091 mutex_exit(&nmp
->nm_lock
);
3100 * - make nfs_bmap() essentially a no-op that does no translation
3101 * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc
3102 * (Maybe I could use the process's page mapping, but I was concerned that
3103 * Kernel Write might not be enabled and also figured copyout() would do
3104 * a lot more work than memcpy() and also it currently happens in the
3105 * context of the swapper process (2).
3110 struct vop_bmap_args
/* {
3113 struct vnode **a_vpp;
3117 struct vnode
*vp
= ap
->a_vp
;
3118 int bshift
= vp
->v_mount
->mnt_fs_bshift
- vp
->v_mount
->mnt_dev_bshift
;
3120 if (ap
->a_vpp
!= NULL
)
3122 if (ap
->a_bnp
!= NULL
)
3123 *ap
->a_bnp
= ap
->a_bn
<< bshift
;
3124 if (ap
->a_runp
!= NULL
)
3125 *ap
->a_runp
= 1024 * 1024; /* XXX */
3131 * For async requests when nfsiod(s) are running, queue the request by
3132 * calling nfs_asyncio(), otherwise just all nfs_doio() to do the
3136 nfs_strategy(void *v
)
3138 struct vop_strategy_args
*ap
= v
;
3139 struct buf
*bp
= ap
->a_bp
;
3142 if ((bp
->b_flags
& (B_PHYS
|B_ASYNC
)) == (B_PHYS
|B_ASYNC
))
3143 panic("nfs physio/async");
3146 * If the op is asynchronous and an i/o daemon is waiting
3147 * queue the request, wake it up and wait for completion
3148 * otherwise just do it ourselves.
3150 if ((bp
->b_flags
& B_ASYNC
) == 0 || nfs_asyncio(bp
))
3151 error
= nfs_doio(bp
);
3156 * fsync vnode op. Just call nfs_flush() with commit == 1.
3162 struct vop_fsync_args
/* {
3163 struct vnodeop_desc *a_desc;
3164 struct vnode * a_vp;
3165 kauth_cred_t a_cred;
3172 struct vnode
*vp
= ap
->a_vp
;
3174 if (vp
->v_type
!= VREG
)
3177 return (nfs_flush(vp
, ap
->a_cred
,
3178 (ap
->a_flags
& FSYNC_WAIT
) != 0 ? MNT_WAIT
: 0, curlwp
, 1));
3182 * Flush all the data associated with a vnode.
3185 nfs_flush(struct vnode
*vp
, kauth_cred_t cred
, int waitfor
, struct lwp
*l
,
3188 struct nfsnode
*np
= VTONFS(vp
);
3190 int flushflags
= PGO_ALLPAGES
|PGO_CLEANIT
|PGO_SYNCIO
;
3191 UVMHIST_FUNC("nfs_flush"); UVMHIST_CALLED(ubchist
);
3193 mutex_enter(&vp
->v_interlock
);
3194 error
= VOP_PUTPAGES(vp
, 0, 0, flushflags
);
3195 if (np
->n_flag
& NWRITEERR
) {
3196 error
= np
->n_error
;
3197 np
->n_flag
&= ~NWRITEERR
;
3199 UVMHIST_LOG(ubchist
, "returning %d", error
,0,0,0);
3204 * Return POSIX pathconf information applicable to nfs.
3206 * N.B. The NFS V2 protocol doesn't support this RPC.
3210 nfs_pathconf(void *v
)
3212 struct vop_pathconf_args
/* {
3215 register_t *a_retval;
3217 struct nfsv3_pathconf
*pcp
;
3218 struct vnode
*vp
= ap
->a_vp
;
3219 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
3222 char *bpos
, *dpos
, *cp
, *cp2
;
3223 int error
= 0, attrflag
;
3225 struct nfsmount
*nmp
;
3229 const int v3
= NFS_ISV3(vp
);
3230 struct nfsnode
*np
= VTONFS(vp
);
3232 switch (ap
->a_name
) {
3233 /* Names that can be resolved locally. */
3235 *ap
->a_retval
= PIPE_BUF
;
3240 /* Names that cannot be resolved locally; do an RPC, if possible. */
3243 case _PC_CHOWN_RESTRICTED
:
3249 nfsstats
.rpccnt
[NFSPROC_PATHCONF
]++;
3250 nfsm_reqhead(np
, NFSPROC_PATHCONF
, NFSX_FH(1));
3252 nfsm_request(np
, NFSPROC_PATHCONF
,
3253 curlwp
, curlwp
->l_cred
); /* XXX */
3254 nfsm_postop_attr(vp
, attrflag
, 0);
3256 nfsm_dissect(pcp
, struct nfsv3_pathconf
*,
3258 switch (ap
->a_name
) {
3261 fxdr_unsigned(register_t
, pcp
->pc_linkmax
);
3265 fxdr_unsigned(register_t
, pcp
->pc_namemax
);
3267 case _PC_CHOWN_RESTRICTED
:
3269 (pcp
->pc_chownrestricted
== nfs_true
);
3273 (pcp
->pc_notrunc
== nfs_true
);
3279 case _PC_FILESIZEBITS
:
3282 nmp
= VFSTONFS(vp
->v_mount
);
3283 if ((nmp
->nm_iflag
& NFSMNT_GOTFSINFO
) == 0)
3284 if ((error
= nfs_fsinfo(nmp
, vp
,
3285 curlwp
->l_cred
, curlwp
)) != 0) /* XXX */
3287 for (l
= 0, maxsize
= nmp
->nm_maxfilesize
;
3288 (maxsize
>> l
) > 0; l
++)
3290 *ap
->a_retval
= l
+ 1;
3294 *ap
->a_retval
= 32; /* NFS V2 limitation */
3306 * NFS advisory byte-level locks.
3309 nfs_advlock(void *v
)
3311 struct vop_advlock_args
/* {
3318 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3320 return lf_advlock(ap
, &np
->n_lockf
, np
->n_size
);
3324 * Print out the contents of an nfsnode.
3329 struct vop_print_args
/* {
3332 struct vnode
*vp
= ap
->a_vp
;
3333 struct nfsnode
*np
= VTONFS(vp
);
3335 printf("tag VT_NFS, fileid %lld fsid 0x%llx",
3336 (unsigned long long)np
->n_vattr
->va_fileid
,
3337 (unsigned long long)np
->n_vattr
->va_fsid
);
3338 if (vp
->v_type
== VFIFO
)
3345 * nfs unlock wrapper.
3350 struct vop_unlock_args
/* {
3354 struct vnode
*vp
= ap
->a_vp
;
3357 * VOP_UNLOCK can be called by nfs_loadattrcache
3361 nfs_delayedtruncate(vp
);
3364 return genfs_unlock(v
);
3368 * nfs special file access vnode op.
3369 * Essentially just get vattr and then imitate iaccess() since the device is
3370 * local to the client.
3373 nfsspec_access(void *v
)
3375 struct vop_access_args
/* {
3378 kauth_cred_t a_cred;
3382 struct vnode
*vp
= ap
->a_vp
;
3385 error
= VOP_GETATTR(vp
, &va
, ap
->a_cred
);
3390 * Disallow write attempts on filesystems mounted read-only;
3391 * unless the file is a socket, fifo, or a block or character
3392 * device resident on the filesystem.
3394 if ((ap
->a_mode
& VWRITE
) && (vp
->v_mount
->mnt_flag
& MNT_RDONLY
)) {
3395 switch (vp
->v_type
) {
3405 return (genfs_can_access(va
.va_type
, va
.va_mode
,
3406 va
.va_uid
, va
.va_gid
, ap
->a_mode
, ap
->a_cred
));
3410 * Read wrapper for special devices.
3413 nfsspec_read(void *v
)
3415 struct vop_read_args
/* {
3419 kauth_cred_t a_cred;
3421 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3427 getnanotime(&np
->n_atim
);
3428 return (VOCALL(spec_vnodeop_p
, VOFFSET(vop_read
), ap
));
3432 * Write wrapper for special devices.
3435 nfsspec_write(void *v
)
3437 struct vop_write_args
/* {
3441 kauth_cred_t a_cred;
3443 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3449 getnanotime(&np
->n_mtim
);
3450 return (VOCALL(spec_vnodeop_p
, VOFFSET(vop_write
), ap
));
3454 * Close wrapper for special devices.
3456 * Update the times on the nfsnode then do device close.
3459 nfsspec_close(void *v
)
3461 struct vop_close_args
/* {
3464 kauth_cred_t a_cred;
3467 struct vnode
*vp
= ap
->a_vp
;
3468 struct nfsnode
*np
= VTONFS(vp
);
3471 if (np
->n_flag
& (NACC
| NUPD
)) {
3473 if (vp
->v_usecount
== 1 &&
3474 (vp
->v_mount
->mnt_flag
& MNT_RDONLY
) == 0) {
3476 if (np
->n_flag
& NACC
)
3477 vattr
.va_atime
= np
->n_atim
;
3478 if (np
->n_flag
& NUPD
)
3479 vattr
.va_mtime
= np
->n_mtim
;
3480 (void)VOP_SETATTR(vp
, &vattr
, ap
->a_cred
);
3483 return (VOCALL(spec_vnodeop_p
, VOFFSET(vop_close
), ap
));
3487 * Read wrapper for fifos.
3490 nfsfifo_read(void *v
)
3492 struct vop_read_args
/* {
3496 kauth_cred_t a_cred;
3498 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3504 getnanotime(&np
->n_atim
);
3505 return (VOCALL(fifo_vnodeop_p
, VOFFSET(vop_read
), ap
));
3509 * Write wrapper for fifos.
3512 nfsfifo_write(void *v
)
3514 struct vop_write_args
/* {
3518 kauth_cred_t a_cred;
3520 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3526 getnanotime(&np
->n_mtim
);
3527 return (VOCALL(fifo_vnodeop_p
, VOFFSET(vop_write
), ap
));
3531 * Close wrapper for fifos.
3533 * Update the times on the nfsnode then do fifo close.
3536 nfsfifo_close(void *v
)
3538 struct vop_close_args
/* {
3541 kauth_cred_t a_cred;
3544 struct vnode
*vp
= ap
->a_vp
;
3545 struct nfsnode
*np
= VTONFS(vp
);
3548 if (np
->n_flag
& (NACC
| NUPD
)) {
3552 if (np
->n_flag
& NACC
)
3554 if (np
->n_flag
& NUPD
)
3557 if (vp
->v_usecount
== 1 &&
3558 (vp
->v_mount
->mnt_flag
& MNT_RDONLY
) == 0) {
3560 if (np
->n_flag
& NACC
)
3561 vattr
.va_atime
= np
->n_atim
;
3562 if (np
->n_flag
& NUPD
)
3563 vattr
.va_mtime
= np
->n_mtim
;
3564 (void)VOP_SETATTR(vp
, &vattr
, ap
->a_cred
);
3567 return (VOCALL(fifo_vnodeop_p
, VOFFSET(vop_close
), ap
));