1 /* $NetBSD: nfs_vnops.c,v 1.264 2008/01/02 19:26:47 yamt 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.264 2008/01/02 19:26:47 yamt Exp $");
46 #include "opt_uvmhist.h"
48 #include <sys/param.h>
50 #include <sys/kernel.h>
51 #include <sys/systm.h>
52 #include <sys/resourcevar.h>
53 #include <sys/mount.h>
55 #include <sys/condvar.h>
57 #include <sys/malloc.h>
60 #include <sys/mutex.h>
61 #include <sys/namei.h>
62 #include <sys/vnode.h>
63 #include <sys/dirent.h>
64 #include <sys/fcntl.h>
66 #include <sys/lockf.h>
68 #include <sys/unistd.h>
69 #include <sys/kauth.h>
71 #include <uvm/uvm_extern.h>
74 #include <miscfs/fifofs/fifo.h>
75 #include <miscfs/genfs/genfs.h>
76 #include <miscfs/genfs/genfs_node.h>
77 #include <miscfs/specfs/specdev.h>
79 #include <nfs/rpcv2.h>
80 #include <nfs/nfsproto.h>
82 #include <nfs/nfsnode.h>
83 #include <nfs/nfsmount.h>
84 #include <nfs/xdr_subs.h>
85 #include <nfs/nfsm_subs.h>
86 #include <nfs/nfs_var.h>
89 #include <netinet/in.h>
90 #include <netinet/in_var.h>
93 * Global vfs data structures for nfs
95 int (**nfsv2_vnodeop_p
) __P((void *));
96 const struct vnodeopv_entry_desc nfsv2_vnodeop_entries
[] = {
97 { &vop_default_desc
, vn_default_error
},
98 { &vop_lookup_desc
, nfs_lookup
}, /* lookup */
99 { &vop_create_desc
, nfs_create
}, /* create */
100 { &vop_mknod_desc
, nfs_mknod
}, /* mknod */
101 { &vop_open_desc
, nfs_open
}, /* open */
102 { &vop_close_desc
, nfs_close
}, /* close */
103 { &vop_access_desc
, nfs_access
}, /* access */
104 { &vop_getattr_desc
, nfs_getattr
}, /* getattr */
105 { &vop_setattr_desc
, nfs_setattr
}, /* setattr */
106 { &vop_read_desc
, nfs_read
}, /* read */
107 { &vop_write_desc
, nfs_write
}, /* write */
108 { &vop_fcntl_desc
, genfs_fcntl
}, /* fcntl */
109 { &vop_ioctl_desc
, nfs_ioctl
}, /* ioctl */
110 { &vop_poll_desc
, nfs_poll
}, /* poll */
111 { &vop_kqfilter_desc
, nfs_kqfilter
}, /* kqfilter */
112 { &vop_revoke_desc
, nfs_revoke
}, /* revoke */
113 { &vop_mmap_desc
, nfs_mmap
}, /* mmap */
114 { &vop_fsync_desc
, nfs_fsync
}, /* fsync */
115 { &vop_seek_desc
, nfs_seek
}, /* seek */
116 { &vop_remove_desc
, nfs_remove
}, /* remove */
117 { &vop_link_desc
, nfs_link
}, /* link */
118 { &vop_rename_desc
, nfs_rename
}, /* rename */
119 { &vop_mkdir_desc
, nfs_mkdir
}, /* mkdir */
120 { &vop_rmdir_desc
, nfs_rmdir
}, /* rmdir */
121 { &vop_symlink_desc
, nfs_symlink
}, /* symlink */
122 { &vop_readdir_desc
, nfs_readdir
}, /* readdir */
123 { &vop_readlink_desc
, nfs_readlink
}, /* readlink */
124 { &vop_abortop_desc
, nfs_abortop
}, /* abortop */
125 { &vop_inactive_desc
, nfs_inactive
}, /* inactive */
126 { &vop_reclaim_desc
, nfs_reclaim
}, /* reclaim */
127 { &vop_lock_desc
, nfs_lock
}, /* lock */
128 { &vop_unlock_desc
, nfs_unlock
}, /* unlock */
129 { &vop_bmap_desc
, nfs_bmap
}, /* bmap */
130 { &vop_strategy_desc
, nfs_strategy
}, /* strategy */
131 { &vop_print_desc
, nfs_print
}, /* print */
132 { &vop_islocked_desc
, nfs_islocked
}, /* islocked */
133 { &vop_pathconf_desc
, nfs_pathconf
}, /* pathconf */
134 { &vop_advlock_desc
, nfs_advlock
}, /* advlock */
135 { &vop_bwrite_desc
, genfs_badop
}, /* bwrite */
136 { &vop_getpages_desc
, nfs_getpages
}, /* getpages */
137 { &vop_putpages_desc
, genfs_putpages
}, /* putpages */
140 const struct vnodeopv_desc nfsv2_vnodeop_opv_desc
=
141 { &nfsv2_vnodeop_p
, nfsv2_vnodeop_entries
};
144 * Special device vnode ops
146 int (**spec_nfsv2nodeop_p
) __P((void *));
147 const struct vnodeopv_entry_desc spec_nfsv2nodeop_entries
[] = {
148 { &vop_default_desc
, vn_default_error
},
149 { &vop_lookup_desc
, spec_lookup
}, /* lookup */
150 { &vop_create_desc
, spec_create
}, /* create */
151 { &vop_mknod_desc
, spec_mknod
}, /* mknod */
152 { &vop_open_desc
, spec_open
}, /* open */
153 { &vop_close_desc
, nfsspec_close
}, /* close */
154 { &vop_access_desc
, nfsspec_access
}, /* access */
155 { &vop_getattr_desc
, nfs_getattr
}, /* getattr */
156 { &vop_setattr_desc
, nfs_setattr
}, /* setattr */
157 { &vop_read_desc
, nfsspec_read
}, /* read */
158 { &vop_write_desc
, nfsspec_write
}, /* write */
159 { &vop_fcntl_desc
, genfs_fcntl
}, /* fcntl */
160 { &vop_ioctl_desc
, spec_ioctl
}, /* ioctl */
161 { &vop_poll_desc
, spec_poll
}, /* poll */
162 { &vop_kqfilter_desc
, spec_kqfilter
}, /* kqfilter */
163 { &vop_revoke_desc
, spec_revoke
}, /* revoke */
164 { &vop_mmap_desc
, spec_mmap
}, /* mmap */
165 { &vop_fsync_desc
, spec_fsync
}, /* fsync */
166 { &vop_seek_desc
, spec_seek
}, /* seek */
167 { &vop_remove_desc
, spec_remove
}, /* remove */
168 { &vop_link_desc
, spec_link
}, /* link */
169 { &vop_rename_desc
, spec_rename
}, /* rename */
170 { &vop_mkdir_desc
, spec_mkdir
}, /* mkdir */
171 { &vop_rmdir_desc
, spec_rmdir
}, /* rmdir */
172 { &vop_symlink_desc
, spec_symlink
}, /* symlink */
173 { &vop_readdir_desc
, spec_readdir
}, /* readdir */
174 { &vop_readlink_desc
, spec_readlink
}, /* readlink */
175 { &vop_abortop_desc
, spec_abortop
}, /* abortop */
176 { &vop_inactive_desc
, nfs_inactive
}, /* inactive */
177 { &vop_reclaim_desc
, nfs_reclaim
}, /* reclaim */
178 { &vop_lock_desc
, nfs_lock
}, /* lock */
179 { &vop_unlock_desc
, nfs_unlock
}, /* unlock */
180 { &vop_bmap_desc
, spec_bmap
}, /* bmap */
181 { &vop_strategy_desc
, spec_strategy
}, /* strategy */
182 { &vop_print_desc
, nfs_print
}, /* print */
183 { &vop_islocked_desc
, nfs_islocked
}, /* islocked */
184 { &vop_pathconf_desc
, spec_pathconf
}, /* pathconf */
185 { &vop_advlock_desc
, spec_advlock
}, /* advlock */
186 { &vop_bwrite_desc
, spec_bwrite
}, /* bwrite */
187 { &vop_getpages_desc
, spec_getpages
}, /* getpages */
188 { &vop_putpages_desc
, spec_putpages
}, /* putpages */
191 const struct vnodeopv_desc spec_nfsv2nodeop_opv_desc
=
192 { &spec_nfsv2nodeop_p
, spec_nfsv2nodeop_entries
};
194 int (**fifo_nfsv2nodeop_p
) __P((void *));
195 const struct vnodeopv_entry_desc fifo_nfsv2nodeop_entries
[] = {
196 { &vop_default_desc
, vn_default_error
},
197 { &vop_lookup_desc
, fifo_lookup
}, /* lookup */
198 { &vop_create_desc
, fifo_create
}, /* create */
199 { &vop_mknod_desc
, fifo_mknod
}, /* mknod */
200 { &vop_open_desc
, fifo_open
}, /* open */
201 { &vop_close_desc
, nfsfifo_close
}, /* close */
202 { &vop_access_desc
, nfsspec_access
}, /* access */
203 { &vop_getattr_desc
, nfs_getattr
}, /* getattr */
204 { &vop_setattr_desc
, nfs_setattr
}, /* setattr */
205 { &vop_read_desc
, nfsfifo_read
}, /* read */
206 { &vop_write_desc
, nfsfifo_write
}, /* write */
207 { &vop_fcntl_desc
, genfs_fcntl
}, /* fcntl */
208 { &vop_ioctl_desc
, fifo_ioctl
}, /* ioctl */
209 { &vop_poll_desc
, fifo_poll
}, /* poll */
210 { &vop_kqfilter_desc
, fifo_kqfilter
}, /* kqfilter */
211 { &vop_revoke_desc
, fifo_revoke
}, /* revoke */
212 { &vop_mmap_desc
, fifo_mmap
}, /* mmap */
213 { &vop_fsync_desc
, nfs_fsync
}, /* fsync */
214 { &vop_seek_desc
, fifo_seek
}, /* seek */
215 { &vop_remove_desc
, fifo_remove
}, /* remove */
216 { &vop_link_desc
, fifo_link
}, /* link */
217 { &vop_rename_desc
, fifo_rename
}, /* rename */
218 { &vop_mkdir_desc
, fifo_mkdir
}, /* mkdir */
219 { &vop_rmdir_desc
, fifo_rmdir
}, /* rmdir */
220 { &vop_symlink_desc
, fifo_symlink
}, /* symlink */
221 { &vop_readdir_desc
, fifo_readdir
}, /* readdir */
222 { &vop_readlink_desc
, fifo_readlink
}, /* readlink */
223 { &vop_abortop_desc
, fifo_abortop
}, /* abortop */
224 { &vop_inactive_desc
, nfs_inactive
}, /* inactive */
225 { &vop_reclaim_desc
, nfs_reclaim
}, /* reclaim */
226 { &vop_lock_desc
, nfs_lock
}, /* lock */
227 { &vop_unlock_desc
, nfs_unlock
}, /* unlock */
228 { &vop_bmap_desc
, fifo_bmap
}, /* bmap */
229 { &vop_strategy_desc
, genfs_badop
}, /* strategy */
230 { &vop_print_desc
, nfs_print
}, /* print */
231 { &vop_islocked_desc
, nfs_islocked
}, /* islocked */
232 { &vop_pathconf_desc
, fifo_pathconf
}, /* pathconf */
233 { &vop_advlock_desc
, fifo_advlock
}, /* advlock */
234 { &vop_bwrite_desc
, genfs_badop
}, /* bwrite */
235 { &vop_putpages_desc
, fifo_putpages
}, /* putpages */
238 const struct vnodeopv_desc fifo_nfsv2nodeop_opv_desc
=
239 { &fifo_nfsv2nodeop_p
, fifo_nfsv2nodeop_entries
};
241 static int nfs_linkrpc(struct vnode
*, struct vnode
*, const char *,
242 size_t, kauth_cred_t
, struct lwp
*);
243 static void nfs_writerpc_extfree(struct mbuf
*, void *, size_t, void *);
248 extern u_int32_t nfs_true
, nfs_false
;
249 extern u_int32_t nfs_xdrneg1
;
250 extern const nfstype nfsv3_type
[9];
252 int nfs_numasync
= 0;
253 #define DIRHDSIZ _DIRENT_NAMEOFF(dp)
254 #define UIO_ADVANCE(uio, siz) \
255 (void)((uio)->uio_resid -= (siz), \
256 (uio)->uio_iov->iov_base = (char *)(uio)->uio_iov->iov_base + (siz), \
257 (uio)->uio_iov->iov_len -= (siz))
259 static void nfs_cache_enter(struct vnode
*, struct vnode
*,
260 struct componentname
*);
263 nfs_cache_enter(struct vnode
*dvp
, struct vnode
*vp
,
264 struct componentname
*cnp
)
266 struct nfsnode
*dnp
= VTONFS(dvp
);
269 struct nfsnode
*np
= VTONFS(vp
);
271 np
->n_ctime
= np
->n_vattr
->va_ctime
.tv_sec
;
274 if (!timespecisset(&dnp
->n_nctime
))
275 dnp
->n_nctime
= dnp
->n_vattr
->va_mtime
;
277 cache_enter(dvp
, vp
, cnp
);
281 * nfs null call from vfs.
284 nfs_null(vp
, cred
, l
)
291 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
292 struct nfsnode
*np
= VTONFS(vp
);
294 nfsm_reqhead(np
, NFSPROC_NULL
, 0);
295 nfsm_request(np
, NFSPROC_NULL
, l
, cred
);
301 * nfs access vnode op.
302 * For nfs version 2, just return ok. File accesses may fail later.
303 * For nfs version 3, use the access rpc to check accessibility. If file modes
304 * are changed on the server, accesses might still fail later.
310 struct vop_access_args
/* {
315 struct vnode
*vp
= ap
->a_vp
;
320 char *bpos
, *dpos
, *cp2
;
321 int error
= 0, attrflag
;
322 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
323 u_int32_t mode
, rmode
;
324 const int v3
= NFS_ISV3(vp
);
327 struct nfsnode
*np
= VTONFS(vp
);
328 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
330 cachevalid
= (np
->n_accstamp
!= -1 &&
331 (time_uptime
- np
->n_accstamp
) < nfs_attrtimeo(nmp
, np
) &&
332 np
->n_accuid
== kauth_cred_geteuid(ap
->a_cred
));
335 * Check access cache first. If this request has been made for this
336 * uid shortly before, use the cached result.
339 if (!np
->n_accerror
) {
340 if ((np
->n_accmode
& ap
->a_mode
) == ap
->a_mode
)
341 return np
->n_accerror
;
342 } else if ((np
->n_accmode
& ap
->a_mode
) == np
->n_accmode
)
343 return np
->n_accerror
;
348 * For nfs v3, do an access rpc, otherwise you are stuck emulating
349 * ufs_access() locally using the vattr. This may not be correct,
350 * since the server may apply other access criteria such as
351 * client uid-->server uid mapping that we do not know about, but
352 * this is better than just returning anything that is lying about
356 nfsstats
.rpccnt
[NFSPROC_ACCESS
]++;
357 nfsm_reqhead(np
, NFSPROC_ACCESS
, NFSX_FH(v3
) + NFSX_UNSIGNED
);
359 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
);
360 if (ap
->a_mode
& VREAD
)
361 mode
= NFSV3ACCESS_READ
;
364 if (vp
->v_type
!= VDIR
) {
365 if (ap
->a_mode
& VWRITE
)
366 mode
|= (NFSV3ACCESS_MODIFY
| NFSV3ACCESS_EXTEND
);
367 if (ap
->a_mode
& VEXEC
)
368 mode
|= NFSV3ACCESS_EXECUTE
;
370 if (ap
->a_mode
& VWRITE
)
371 mode
|= (NFSV3ACCESS_MODIFY
| NFSV3ACCESS_EXTEND
|
373 if (ap
->a_mode
& VEXEC
)
374 mode
|= NFSV3ACCESS_LOOKUP
;
376 *tl
= txdr_unsigned(mode
);
377 nfsm_request(np
, NFSPROC_ACCESS
, curlwp
, ap
->a_cred
);
378 nfsm_postop_attr(vp
, attrflag
, 0);
380 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
381 rmode
= fxdr_unsigned(u_int32_t
, *tl
);
383 * The NFS V3 spec does not clarify whether or not
384 * the returned access bits can be a superset of
385 * the ones requested, so...
387 if ((rmode
& mode
) != mode
)
393 return (nfsspec_access(ap
));
396 * Disallow write attempts on filesystems mounted read-only;
397 * unless the file is a socket, fifo, or a block or character
398 * device resident on the filesystem.
400 if (!error
&& (ap
->a_mode
& VWRITE
) &&
401 (vp
->v_mount
->mnt_flag
& MNT_RDONLY
)) {
402 switch (vp
->v_type
) {
412 if (!error
|| error
== EACCES
) {
414 * If we got the same result as for a previous,
415 * different request, OR it in. Don't update
416 * the timestamp in that case.
418 if (cachevalid
&& np
->n_accstamp
!= -1 &&
419 error
== np
->n_accerror
) {
421 np
->n_accmode
|= ap
->a_mode
;
422 else if ((np
->n_accmode
& ap
->a_mode
) == ap
->a_mode
)
423 np
->n_accmode
= ap
->a_mode
;
425 np
->n_accstamp
= time_uptime
;
426 np
->n_accuid
= kauth_cred_geteuid(ap
->a_cred
);
427 np
->n_accmode
= ap
->a_mode
;
428 np
->n_accerror
= error
;
438 * Check to see if the type is ok
439 * and that deletion is not in progress.
440 * For paged in text files, you will need to flush the page cache
441 * if consistency is lost.
448 struct vop_open_args
/* {
453 struct vnode
*vp
= ap
->a_vp
;
454 struct nfsnode
*np
= VTONFS(vp
);
457 if (vp
->v_type
!= VREG
&& vp
->v_type
!= VDIR
&& vp
->v_type
!= VLNK
) {
461 if (ap
->a_mode
& FREAD
) {
462 if (np
->n_rcred
!= NULL
)
463 kauth_cred_free(np
->n_rcred
);
464 np
->n_rcred
= ap
->a_cred
;
465 kauth_cred_hold(np
->n_rcred
);
467 if (ap
->a_mode
& FWRITE
) {
468 if (np
->n_wcred
!= NULL
)
469 kauth_cred_free(np
->n_wcred
);
470 np
->n_wcred
= ap
->a_cred
;
471 kauth_cred_hold(np
->n_wcred
);
474 error
= nfs_flushstalebuf(vp
, ap
->a_cred
, curlwp
, 0);
478 NFS_INVALIDATE_ATTRCACHE(np
); /* For Open/Close consistency */
485 * What an NFS client should do upon close after writing is a debatable issue.
486 * Most NFS clients push delayed writes to the server upon close, basically for
488 * 1 - So that any write errors may be reported back to the client process
489 * doing the close system call. By far the two most likely errors are
490 * NFSERR_NOSPC and NFSERR_DQUOT to indicate space allocation failure.
491 * 2 - To put a worst case upper bound on cache inconsistency between
492 * multiple clients for the file.
493 * There is also a consistency problem for Version 2 of the protocol w.r.t.
494 * not being able to tell if other clients are writing a file concurrently,
495 * since there is no way of knowing if the changed modify time in the reply
496 * is only due to the write for this client.
497 * (NFS Version 3 provides weak cache consistency data in the reply that
498 * should be sufficient to detect and handle this case.)
500 * The current code does the following:
501 * for NFS Version 2 - play it safe and flush/invalidate all dirty buffers
502 * for NFS Version 3 - flush dirty buffers to the server but don't invalidate
503 * or commit them (this satisfies 1 and 2 except for the
504 * case where the server crashes after this close but
505 * before the commit RPC, which is felt to be "good
506 * enough". Changing the last argument to nfs_flush() to
507 * a 1 would force a commit operation, if it is felt a
508 * commit is necessary now.
515 struct vop_close_args
/* {
516 struct vnodeop_desc *a_desc;
521 struct vnode
*vp
= ap
->a_vp
;
522 struct nfsnode
*np
= VTONFS(vp
);
524 UVMHIST_FUNC("nfs_close"); UVMHIST_CALLED(ubchist
);
526 if (vp
->v_type
== VREG
) {
527 if (np
->n_flag
& NMODIFIED
) {
530 error
= nfs_flush(vp
, ap
->a_cred
, MNT_WAIT
, curlwp
, 0);
531 np
->n_flag
&= ~NMODIFIED
;
534 error
= nfs_vinvalbuf(vp
, V_SAVE
, ap
->a_cred
, curlwp
, 1);
535 NFS_INVALIDATE_ATTRCACHE(np
);
537 if (np
->n_flag
& NWRITEERR
) {
538 np
->n_flag
&= ~NWRITEERR
;
542 UVMHIST_LOG(ubchist
, "returning %d", error
,0,0,0);
547 * nfs getattr call from vfs.
553 struct vop_getattr_args
/* {
558 struct vnode
*vp
= ap
->a_vp
;
559 struct nfsnode
*np
= VTONFS(vp
);
565 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
566 const int v3
= NFS_ISV3(vp
);
569 * Update local times for special files.
571 if (np
->n_flag
& (NACC
| NUPD
))
575 * if we have delayed truncation, do it now.
577 nfs_delayedtruncate(vp
);
580 * First look in the cache.
582 if (nfs_getattrcache(vp
, ap
->a_vap
) == 0)
584 nfsstats
.rpccnt
[NFSPROC_GETATTR
]++;
585 nfsm_reqhead(np
, NFSPROC_GETATTR
, NFSX_FH(v3
));
587 nfsm_request(np
, NFSPROC_GETATTR
, curlwp
, ap
->a_cred
);
589 nfsm_loadattr(vp
, ap
->a_vap
, 0);
590 if (vp
->v_type
== VDIR
&&
591 ap
->a_vap
->va_blocksize
< NFS_DIRFRAGSIZ
)
592 ap
->a_vap
->va_blocksize
= NFS_DIRFRAGSIZ
;
605 struct vop_setattr_args
/* {
606 struct vnodeop_desc *a_desc;
611 struct vnode
*vp
= ap
->a_vp
;
612 struct nfsnode
*np
= VTONFS(vp
);
613 struct vattr
*vap
= ap
->a_vap
;
618 * Setting of flags is not supported.
620 if (vap
->va_flags
!= VNOVAL
)
624 * Disallow write attempts if the filesystem is mounted read-only.
626 if ((vap
->va_uid
!= (uid_t
)VNOVAL
||
627 vap
->va_gid
!= (gid_t
)VNOVAL
|| vap
->va_atime
.tv_sec
!= VNOVAL
||
628 vap
->va_mtime
.tv_sec
!= VNOVAL
|| vap
->va_mode
!= (mode_t
)VNOVAL
) &&
629 (vp
->v_mount
->mnt_flag
& MNT_RDONLY
))
631 if (vap
->va_size
!= VNOVAL
) {
632 switch (vp
->v_type
) {
639 if (vap
->va_mtime
.tv_sec
== VNOVAL
&&
640 vap
->va_atime
.tv_sec
== VNOVAL
&&
641 vap
->va_mode
== (mode_t
)VNOVAL
&&
642 vap
->va_uid
== (uid_t
)VNOVAL
&&
643 vap
->va_gid
== (gid_t
)VNOVAL
)
645 vap
->va_size
= VNOVAL
;
649 * Disallow write attempts if the filesystem is
652 if (vp
->v_mount
->mnt_flag
& MNT_RDONLY
)
654 genfs_node_wrlock(vp
);
655 uvm_vnp_setsize(vp
, vap
->va_size
);
657 np
->n_size
= vap
->va_size
;
658 if (vap
->va_size
== 0)
659 error
= nfs_vinvalbuf(vp
, 0,
660 ap
->a_cred
, curlwp
, 1);
662 error
= nfs_vinvalbuf(vp
, V_SAVE
,
663 ap
->a_cred
, curlwp
, 1);
665 uvm_vnp_setsize(vp
, tsize
);
666 genfs_node_unlock(vp
);
669 np
->n_vattr
->va_size
= vap
->va_size
;
673 * flush files before setattr because a later write of
674 * cached data might change timestamps or reset sugid bits
676 if ((vap
->va_mtime
.tv_sec
!= VNOVAL
||
677 vap
->va_atime
.tv_sec
!= VNOVAL
||
678 vap
->va_mode
!= VNOVAL
) &&
679 vp
->v_type
== VREG
&&
680 (error
= nfs_vinvalbuf(vp
, V_SAVE
, ap
->a_cred
,
681 curlwp
, 1)) == EINTR
)
684 error
= nfs_setattrrpc(vp
, vap
, ap
->a_cred
, curlwp
);
685 if (vap
->va_size
!= VNOVAL
) {
687 np
->n_size
= np
->n_vattr
->va_size
= tsize
;
688 uvm_vnp_setsize(vp
, np
->n_size
);
690 genfs_node_unlock(vp
);
692 VN_KNOTE(vp
, NOTE_ATTRIB
);
697 * Do an nfs setattr rpc.
700 nfs_setattrrpc(vp
, vap
, cred
, l
)
706 struct nfsv2_sattr
*sp
;
712 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
713 const int v3
= NFS_ISV3(vp
);
714 struct nfsnode
*np
= VTONFS(vp
);
716 int wccflag
= NFSV3_WCCRATTR
;
720 nfsstats
.rpccnt
[NFSPROC_SETATTR
]++;
721 nfsm_reqhead(np
, NFSPROC_SETATTR
, NFSX_FH(v3
) + NFSX_SATTR(v3
));
725 nfsm_v3attrbuild(vap
, true);
726 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
);
730 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
731 if (vap
->va_mode
== (mode_t
)VNOVAL
)
732 sp
->sa_mode
= nfs_xdrneg1
;
734 sp
->sa_mode
= vtonfsv2_mode(vp
->v_type
, vap
->va_mode
);
735 if (vap
->va_uid
== (uid_t
)VNOVAL
)
736 sp
->sa_uid
= nfs_xdrneg1
;
738 sp
->sa_uid
= txdr_unsigned(vap
->va_uid
);
739 if (vap
->va_gid
== (gid_t
)VNOVAL
)
740 sp
->sa_gid
= nfs_xdrneg1
;
742 sp
->sa_gid
= txdr_unsigned(vap
->va_gid
);
743 sp
->sa_size
= txdr_unsigned(vap
->va_size
);
744 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
745 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
749 nfsm_request(np
, NFSPROC_SETATTR
, l
, cred
);
752 nfsm_wcc_data(vp
, wccflag
, NAC_NOTRUNC
, false);
755 nfsm_loadattr(vp
, (struct vattr
*)0, NAC_NOTRUNC
);
761 * nfs lookup call, one step at a time...
762 * First look in cache
763 * If not found, unlock the directory nfsnode and do the rpc
765 * This code is full of lock/unlock statements and checks, because
766 * we continue after cache_lookup has finished (we need to check
767 * with the attr cache and do an rpc if it has timed out). This means
768 * that the locking effects of cache_lookup have to be taken into
775 struct vop_lookup_args
/* {
776 struct vnodeop_desc *a_desc;
778 struct vnode **a_vpp;
779 struct componentname *a_cnp;
781 struct componentname
*cnp
= ap
->a_cnp
;
782 struct vnode
*dvp
= ap
->a_dvp
;
783 struct vnode
**vpp
= ap
->a_vpp
;
789 char *bpos
, *dpos
, *cp2
;
790 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
794 int error
= 0, attrflag
, fhsize
;
795 const int v3
= NFS_ISV3(dvp
);
797 flags
= cnp
->cn_flags
;
801 if ((flags
& ISLASTCN
) && (dvp
->v_mount
->mnt_flag
& MNT_RDONLY
) &&
802 (cnp
->cn_nameiop
== DELETE
|| cnp
->cn_nameiop
== RENAME
))
804 if (dvp
->v_type
!= VDIR
)
808 * RFC1813(nfsv3) 3.2 says clients should handle "." by themselves.
810 if (cnp
->cn_namelen
== 1 && cnp
->cn_nameptr
[0] == '.') {
811 error
= VOP_ACCESS(dvp
, VEXEC
, cnp
->cn_cred
);
814 if (cnp
->cn_nameiop
== RENAME
&& (flags
& ISLASTCN
))
818 if (cnp
->cn_nameiop
!= LOOKUP
&& (flags
& ISLASTCN
))
819 cnp
->cn_flags
|= SAVENAME
;
826 * Before tediously performing a linear scan of the directory,
827 * check the name cache to see if the directory/name pair
828 * we are looking for is known already.
829 * If the directory/name pair is found in the name cache,
830 * we have to ensure the directory has not changed from
831 * the time the cache entry has been created. If it has,
832 * the cache entry has to be ignored.
834 error
= cache_lookup_raw(dvp
, vpp
, cnp
);
835 KASSERT(dvp
!= *vpp
);
840 if (error
&& error
!= ENOENT
) {
845 err2
= VOP_ACCESS(dvp
, VEXEC
, cnp
->cn_cred
);
853 if (VOP_GETATTR(dvp
, &vattr
, cnp
->cn_cred
)
854 || timespeccmp(&vattr
.va_mtime
,
855 &VTONFS(dvp
)->n_nctime
, !=)) {
860 cache_purge1(dvp
, NULL
, PURGE_CHILDREN
);
861 timespecclear(&np
->n_nctime
);
865 if (error
== ENOENT
) {
870 if (!VOP_GETATTR(newvp
, &vattr
, cnp
->cn_cred
)
871 && vattr
.va_ctime
.tv_sec
== VTONFS(newvp
)->n_ctime
) {
872 nfsstats
.lookupcache_hits
++;
873 if ((flags
& ISDOTDOT
) != 0) {
876 error
= vn_lock(newvp
, LK_EXCLUSIVE
);
877 if ((flags
& ISDOTDOT
) != 0) {
878 vn_lock(dvp
, LK_EXCLUSIVE
| LK_RETRY
);
881 /* newvp has been revoked. */
886 if (cnp
->cn_nameiop
!= LOOKUP
&& (flags
& ISLASTCN
))
887 cnp
->cn_flags
|= SAVENAME
;
888 KASSERT(newvp
->v_type
!= VNON
);
891 cache_purge1(newvp
, NULL
, PURGE_PARENTS
);
898 * because nfsv3 has the same CREATE semantics as ours,
899 * we don't have to perform LOOKUPs beforehand.
901 * XXX ideally we can do the same for nfsv2 in the case of !O_EXCL.
902 * XXX although we have no way to know if O_EXCL is requested or not.
905 if (v3
&& cnp
->cn_nameiop
== CREATE
&&
906 (flags
& (ISLASTCN
|ISDOTDOT
)) == ISLASTCN
&&
907 (dvp
->v_mount
->mnt_flag
& MNT_RDONLY
) == 0) {
908 cnp
->cn_flags
|= SAVENAME
;
909 return (EJUSTRETURN
);
915 nfsstats
.lookupcache_misses
++;
916 nfsstats
.rpccnt
[NFSPROC_LOOKUP
]++;
917 len
= cnp
->cn_namelen
;
918 nfsm_reqhead(np
, NFSPROC_LOOKUP
,
919 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(len
));
921 nfsm_strtom(cnp
->cn_nameptr
, len
, NFS_MAXNAMLEN
);
922 nfsm_request(np
, NFSPROC_LOOKUP
, curlwp
, cnp
->cn_cred
);
924 nfsm_postop_attr(dvp
, attrflag
, 0);
928 nfsm_getfh(fhp
, fhsize
, v3
);
931 * Handle RENAME case...
933 if (cnp
->cn_nameiop
== RENAME
&& (flags
& ISLASTCN
)) {
934 if (NFS_CMPFH(np
, fhp
, fhsize
)) {
938 error
= nfs_nget(dvp
->v_mount
, fhp
, fhsize
, &np
);
946 nfsm_postop_attr(newvp
, attrflag
, 0);
947 nfsm_postop_attr(dvp
, attrflag
, 0);
950 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
953 cnp
->cn_flags
|= SAVENAME
;
958 * The postop attr handling is duplicated for each if case,
959 * because it should be done while dvp is locked (unlocking
960 * dvp is different for each case).
963 if (NFS_CMPFH(np
, fhp
, fhsize
)) {
971 nfsm_postop_attr(newvp
, attrflag
, 0);
972 nfsm_postop_attr(dvp
, attrflag
, 0);
975 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
976 } else if (flags
& ISDOTDOT
) {
981 error
= nfs_nget(dvp
->v_mount
, fhp
, fhsize
, &np
);
982 vn_lock(dvp
, LK_EXCLUSIVE
| LK_RETRY
);
991 nfsm_postop_attr(newvp
, attrflag
, 0);
992 nfsm_postop_attr(dvp
, attrflag
, 0);
995 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
1000 error
= nfs_nget(dvp
->v_mount
, fhp
, fhsize
, &np
);
1008 nfsm_postop_attr(newvp
, attrflag
, 0);
1009 nfsm_postop_attr(dvp
, attrflag
, 0);
1012 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
1014 if (cnp
->cn_nameiop
!= LOOKUP
&& (flags
& ISLASTCN
))
1015 cnp
->cn_flags
|= SAVENAME
;
1016 if ((cnp
->cn_flags
& MAKEENTRY
) &&
1017 (cnp
->cn_nameiop
!= DELETE
|| !(flags
& ISLASTCN
))) {
1018 nfs_cache_enter(dvp
, newvp
, cnp
);
1024 * We get here only because of errors returned by
1025 * the RPC. Otherwise we'll have returned above
1026 * (the nfsm_* macros will jump to nfsm_reqdone
1029 if (error
== ENOENT
&& (cnp
->cn_flags
& MAKEENTRY
) &&
1030 cnp
->cn_nameiop
!= CREATE
) {
1031 nfs_cache_enter(dvp
, NULL
, cnp
);
1033 if (newvp
!= NULLVP
) {
1041 if ((cnp
->cn_nameiop
== CREATE
|| cnp
->cn_nameiop
== RENAME
) &&
1042 (flags
& ISLASTCN
) && error
== ENOENT
) {
1043 if (dvp
->v_mount
->mnt_flag
& MNT_RDONLY
) {
1046 error
= EJUSTRETURN
;
1047 cnp
->cn_flags
|= SAVENAME
;
1056 * make sure we have valid type and size.
1060 if (newvp
->v_type
== VNON
) {
1061 struct vattr vattr
; /* dummy */
1063 KASSERT(VTONFS(newvp
)->n_attrstamp
== 0);
1064 error
= VOP_GETATTR(newvp
, &vattr
, cnp
->cn_cred
);
1076 * Just call nfs_bioread() to do the work.
1082 struct vop_read_args
/* {
1086 kauth_cred_t a_cred;
1088 struct vnode
*vp
= ap
->a_vp
;
1090 if (vp
->v_type
!= VREG
)
1092 return (nfs_bioread(vp
, ap
->a_uio
, ap
->a_ioflag
, ap
->a_cred
, 0));
1102 struct vop_readlink_args
/* {
1105 kauth_cred_t a_cred;
1107 struct vnode
*vp
= ap
->a_vp
;
1108 struct nfsnode
*np
= VTONFS(vp
);
1110 if (vp
->v_type
!= VLNK
)
1113 if (np
->n_rcred
!= NULL
) {
1114 kauth_cred_free(np
->n_rcred
);
1116 np
->n_rcred
= ap
->a_cred
;
1117 kauth_cred_hold(np
->n_rcred
);
1119 return (nfs_bioread(vp
, ap
->a_uio
, 0, ap
->a_cred
, 0));
1123 * Do a readlink rpc.
1124 * Called by nfs_doio() from below the buffer cache.
1127 nfs_readlinkrpc(vp
, uiop
, cred
)
1135 char *bpos
, *dpos
, *cp2
;
1138 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1139 const int v3
= NFS_ISV3(vp
);
1140 struct nfsnode
*np
= VTONFS(vp
);
1145 nfsstats
.rpccnt
[NFSPROC_READLINK
]++;
1146 nfsm_reqhead(np
, NFSPROC_READLINK
, NFSX_FH(v3
));
1148 nfsm_request(np
, NFSPROC_READLINK
, curlwp
, cred
);
1151 nfsm_postop_attr(vp
, attrflag
, 0);
1156 nfsm_dissect(tl
, uint32_t *, NFSX_UNSIGNED
);
1157 len
= fxdr_unsigned(uint32_t, *tl
);
1158 if (len
> MAXPATHLEN
) {
1160 * this pathname is too long for us.
1163 /* Solaris returns EINVAL. should we follow? */
1164 error
= ENAMETOOLONG
;
1170 nfsm_strsiz(len
, NFS_MAXPATHLEN
);
1172 nfsm_mtouio(uiop
, len
);
1183 nfs_readrpc(vp
, uiop
)
1190 char *bpos
, *dpos
, *cp2
;
1191 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1192 struct nfsmount
*nmp
;
1193 int error
= 0, len
, retlen
, tsiz
, eof
, byte_count
;
1194 const int v3
= NFS_ISV3(vp
);
1195 struct nfsnode
*np
= VTONFS(vp
);
1203 nmp
= VFSTONFS(vp
->v_mount
);
1204 tsiz
= uiop
->uio_resid
;
1205 if (uiop
->uio_offset
+ tsiz
> nmp
->nm_maxfilesize
)
1207 iostat_busy(nmp
->nm_stats
);
1208 byte_count
= 0; /* count bytes actually transferred */
1210 nfsstats
.rpccnt
[NFSPROC_READ
]++;
1211 len
= (tsiz
> nmp
->nm_rsize
) ? nmp
->nm_rsize
: tsiz
;
1212 nfsm_reqhead(np
, NFSPROC_READ
, NFSX_FH(v3
) + NFSX_UNSIGNED
* 3);
1214 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
* 3);
1217 txdr_hyper(uiop
->uio_offset
, tl
);
1218 *(tl
+ 2) = txdr_unsigned(len
);
1222 *tl
++ = txdr_unsigned(uiop
->uio_offset
);
1223 *tl
++ = txdr_unsigned(len
);
1226 nfsm_request(np
, NFSPROC_READ
, curlwp
, np
->n_rcred
);
1229 nfsm_postop_attr(vp
, attrflag
, NAC_NOTRUNC
);
1234 nfsm_dissect(tl
, u_int32_t
*, 2 * NFSX_UNSIGNED
);
1235 eof
= fxdr_unsigned(int, *(tl
+ 1));
1238 nfsm_loadattr(vp
, (struct vattr
*)0, NAC_NOTRUNC
);
1239 nfsm_strsiz(retlen
, nmp
->nm_rsize
);
1240 nfsm_mtouio(uiop
, retlen
);
1243 byte_count
+= retlen
;
1246 if (eof
|| retlen
== 0)
1254 iostat_unbusy(nmp
->nm_stats
, byte_count
, 1);
1258 struct nfs_writerpc_context
{
1265 * free mbuf used to refer protected pages while write rpc call.
1269 nfs_writerpc_extfree(struct mbuf
*m
, void *tbuf
, size_t size
, void *arg
)
1271 struct nfs_writerpc_context
*ctx
= arg
;
1274 KASSERT(ctx
!= NULL
);
1275 pool_cache_put(mb_cache
, m
);
1276 mutex_enter(&ctx
->nwc_lock
);
1277 if (--ctx
->nwc_mbufcount
== 0) {
1278 cv_signal(&ctx
->nwc_cv
);
1280 mutex_exit(&ctx
->nwc_lock
);
1287 nfs_writerpc(vp
, uiop
, iomode
, pageprotected
, stalewriteverfp
)
1292 bool *stalewriteverfp
;
1298 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1299 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
1300 int error
= 0, len
, tsiz
, wccflag
= NFSV3_WCCRATTR
;
1301 const int v3
= NFS_ISV3(vp
);
1302 int committed
= NFSV3WRITE_FILESYNC
;
1303 struct nfsnode
*np
= VTONFS(vp
);
1304 struct nfs_writerpc_context ctx
;
1306 struct lwp
*l
= NULL
;
1313 mutex_init(&ctx
.nwc_lock
, MUTEX_DRIVER
, IPL_VM
);
1314 cv_init(&ctx
.nwc_cv
, "nfsmblk");
1315 ctx
.nwc_mbufcount
= 1;
1317 if (vp
->v_mount
->mnt_flag
& MNT_RDONLY
) {
1318 panic("writerpc readonly vp %p", vp
);
1322 if (uiop
->uio_iovcnt
!= 1)
1323 panic("nfs: writerpc iovcnt > 1");
1325 tsiz
= uiop
->uio_resid
;
1326 if (uiop
->uio_offset
+ tsiz
> nmp
->nm_maxfilesize
)
1328 if (pageprotected
) {
1333 origresid
= uiop
->uio_resid
;
1334 KASSERT(origresid
== uiop
->uio_iov
->iov_len
);
1335 iostat_busy(nmp
->nm_stats
);
1336 byte_count
= 0; /* count of bytes actually written */
1338 uint32_t datalen
; /* data bytes need to be allocated in mbuf */
1340 bool stalewriteverf
= false;
1342 nfsstats
.rpccnt
[NFSPROC_WRITE
]++;
1343 len
= min(tsiz
, nmp
->nm_wsize
);
1344 datalen
= pageprotected
? 0 : nfsm_rndup(len
);
1345 nfsm_reqhead(np
, NFSPROC_WRITE
,
1346 NFSX_FH(v3
) + 5 * NFSX_UNSIGNED
+ datalen
);
1350 nfsm_build(tl
, u_int32_t
*, 5 * NFSX_UNSIGNED
);
1351 txdr_hyper(uiop
->uio_offset
, tl
);
1353 *tl
++ = txdr_unsigned(len
);
1354 *tl
++ = txdr_unsigned(*iomode
);
1355 *tl
= txdr_unsigned(len
);
1361 nfsm_build(tl
, u_int32_t
*, 4 * NFSX_UNSIGNED
);
1362 /* Set both "begin" and "current" to non-garbage. */
1363 x
= txdr_unsigned((u_int32_t
)uiop
->uio_offset
);
1364 *tl
++ = x
; /* "begin offset" */
1365 *tl
++ = x
; /* "current offset" */
1366 x
= txdr_unsigned(len
);
1367 *tl
++ = x
; /* total to this offset */
1368 *tl
= x
; /* size of this write */
1371 if (pageprotected
) {
1373 * since we know pages can't be modified during i/o,
1374 * no need to copy them for us.
1377 struct iovec
*iovp
= uiop
->uio_iov
;
1379 m
= m_get(M_WAIT
, MT_DATA
);
1380 MCLAIM(m
, &nfs_mowner
);
1381 MEXTADD(m
, iovp
->iov_base
, len
, M_MBUF
,
1382 nfs_writerpc_extfree
, &ctx
);
1383 m
->m_flags
|= M_EXT_ROMAP
;
1387 * no need to maintain mb and bpos here
1388 * because no one care them later.
1392 bpos
= mtod(void *, mb
) + mb
->m_len
;
1394 UIO_ADVANCE(uiop
, len
);
1395 uiop
->uio_offset
+= len
;
1396 mutex_enter(&ctx
.nwc_lock
);
1397 ctx
.nwc_mbufcount
++;
1398 mutex_exit(&ctx
.nwc_lock
);
1399 nfs_zeropad(mb
, 0, nfsm_padlen(len
));
1401 nfsm_uiotom(uiop
, len
);
1403 nfsm_request(np
, NFSPROC_WRITE
, curlwp
, np
->n_wcred
);
1406 wccflag
= NFSV3_WCCCHK
;
1407 nfsm_wcc_data(vp
, wccflag
, NAC_NOTRUNC
, !error
);
1409 nfsm_dissect(tl
, u_int32_t
*, 2 * NFSX_UNSIGNED
1410 + NFSX_V3WRITEVERF
);
1411 rlen
= fxdr_unsigned(int, *tl
++);
1416 } else if (rlen
< len
) {
1417 backup
= len
- rlen
;
1418 UIO_ADVANCE(uiop
, -backup
);
1419 uiop
->uio_offset
-= backup
;
1422 commit
= fxdr_unsigned(int, *tl
++);
1425 * Return the lowest committment level
1426 * obtained by any of the RPCs.
1428 if (committed
== NFSV3WRITE_FILESYNC
)
1430 else if (committed
== NFSV3WRITE_DATASYNC
&&
1431 commit
== NFSV3WRITE_UNSTABLE
)
1433 mutex_enter(&nmp
->nm_lock
);
1434 if ((nmp
->nm_iflag
& NFSMNT_HASWRITEVERF
) == 0){
1435 memcpy(nmp
->nm_writeverf
, tl
,
1437 nmp
->nm_iflag
|= NFSMNT_HASWRITEVERF
;
1438 } else if ((nmp
->nm_iflag
&
1439 NFSMNT_STALEWRITEVERF
) ||
1440 memcmp(tl
, nmp
->nm_writeverf
,
1441 NFSX_V3WRITEVERF
)) {
1442 memcpy(nmp
->nm_writeverf
, tl
,
1445 * note NFSMNT_STALEWRITEVERF
1446 * if we're the first thread to
1449 if ((nmp
->nm_iflag
&
1450 NFSMNT_STALEWRITEVERF
) == 0) {
1451 stalewriteverf
= true;
1453 NFSMNT_STALEWRITEVERF
;
1456 mutex_exit(&nmp
->nm_lock
);
1460 nfsm_loadattr(vp
, (struct vattr
*)0, NAC_NOTRUNC
);
1462 VTONFS(vp
)->n_mtime
= VTONFS(vp
)->n_vattr
->va_mtime
;
1468 if (stalewriteverf
) {
1469 *stalewriteverfp
= true;
1470 stalewriteverf
= false;
1471 if (committed
== NFSV3WRITE_UNSTABLE
&&
1474 * if our write requests weren't atomic but
1475 * unstable, datas in previous iterations
1476 * might have already been lost now.
1477 * then, we should resend them to nfsd.
1479 backup
= origresid
- tsiz
;
1480 UIO_ADVANCE(uiop
, -backup
);
1481 uiop
->uio_offset
-= backup
;
1488 iostat_unbusy(nmp
->nm_stats
, byte_count
, 0);
1489 if (pageprotected
) {
1491 * wait until mbufs go away.
1492 * retransmitted mbufs can survive longer than rpc requests
1495 mutex_enter(&ctx
.nwc_lock
);
1496 ctx
.nwc_mbufcount
--;
1497 while (ctx
.nwc_mbufcount
> 0) {
1498 cv_wait(&ctx
.nwc_cv
, &ctx
.nwc_lock
);
1500 mutex_exit(&ctx
.nwc_lock
);
1503 mutex_destroy(&ctx
.nwc_lock
);
1504 cv_destroy(&ctx
.nwc_cv
);
1505 *iomode
= committed
;
1507 uiop
->uio_resid
= tsiz
;
1513 * For NFS v2 this is a kludge. Use a create rpc but with the IFMT bits of the
1514 * mode set to specify the file type and the size field for rdev.
1517 nfs_mknodrpc(dvp
, vpp
, cnp
, vap
)
1520 struct componentname
*cnp
;
1523 struct nfsv2_sattr
*sp
;
1527 struct vnode
*newvp
= (struct vnode
*)0;
1528 struct nfsnode
*dnp
, *np
;
1531 int error
= 0, wccflag
= NFSV3_WCCRATTR
, gotvp
= 0;
1532 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1534 const int v3
= NFS_ISV3(dvp
);
1536 if (vap
->va_type
== VCHR
|| vap
->va_type
== VBLK
)
1537 rdev
= txdr_unsigned(vap
->va_rdev
);
1538 else if (vap
->va_type
== VFIFO
|| vap
->va_type
== VSOCK
)
1541 VOP_ABORTOP(dvp
, cnp
);
1543 return (EOPNOTSUPP
);
1545 nfsstats
.rpccnt
[NFSPROC_MKNOD
]++;
1547 nfsm_reqhead(dnp
, NFSPROC_MKNOD
, NFSX_FH(v3
) + 4 * NFSX_UNSIGNED
+
1548 + nfsm_rndup(cnp
->cn_namelen
) + NFSX_SATTR(v3
));
1549 nfsm_fhtom(dnp
, v3
);
1550 nfsm_strtom(cnp
->cn_nameptr
, cnp
->cn_namelen
, NFS_MAXNAMLEN
);
1553 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
);
1554 *tl
++ = vtonfsv3_type(vap
->va_type
);
1555 nfsm_v3attrbuild(vap
, false);
1556 if (vap
->va_type
== VCHR
|| vap
->va_type
== VBLK
) {
1557 nfsm_build(tl
, u_int32_t
*, 2 * NFSX_UNSIGNED
);
1558 *tl
++ = txdr_unsigned(major(vap
->va_rdev
));
1559 *tl
= txdr_unsigned(minor(vap
->va_rdev
));
1564 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
1565 sp
->sa_mode
= vtonfsv2_mode(vap
->va_type
, vap
->va_mode
);
1566 sp
->sa_uid
= nfs_xdrneg1
;
1567 sp
->sa_gid
= nfs_xdrneg1
;
1569 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
1570 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
1572 nfsm_request(dnp
, NFSPROC_MKNOD
, curlwp
, cnp
->cn_cred
);
1574 nfsm_mtofh(dvp
, newvp
, v3
, gotvp
);
1576 error
= nfs_lookitup(dvp
, cnp
->cn_nameptr
,
1577 cnp
->cn_namelen
, cnp
->cn_cred
, curlwp
, &np
);
1584 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
1591 if (cnp
->cn_flags
& MAKEENTRY
)
1592 nfs_cache_enter(dvp
, newvp
, cnp
);
1595 PNBUF_PUT(cnp
->cn_pnbuf
);
1596 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
1598 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
1605 * just call nfs_mknodrpc() to do the work.
1612 struct vop_mknod_args
/* {
1613 struct vnode *a_dvp;
1614 struct vnode **a_vpp;
1615 struct componentname *a_cnp;
1616 struct vattr *a_vap;
1618 struct vnode
*dvp
= ap
->a_dvp
;
1619 struct componentname
*cnp
= ap
->a_cnp
;
1622 error
= nfs_mknodrpc(dvp
, ap
->a_vpp
, cnp
, ap
->a_vap
);
1623 VN_KNOTE(dvp
, NOTE_WRITE
);
1624 if (error
== 0 || error
== EEXIST
)
1625 cache_purge1(dvp
, cnp
, 0);
1630 static u_long create_verf
;
1633 * nfs file create call
1639 struct vop_create_args
/* {
1640 struct vnode *a_dvp;
1641 struct vnode **a_vpp;
1642 struct componentname *a_cnp;
1643 struct vattr *a_vap;
1645 struct vnode
*dvp
= ap
->a_dvp
;
1646 struct vattr
*vap
= ap
->a_vap
;
1647 struct componentname
*cnp
= ap
->a_cnp
;
1648 struct nfsv2_sattr
*sp
;
1652 struct nfsnode
*dnp
, *np
= (struct nfsnode
*)0;
1653 struct vnode
*newvp
= (struct vnode
*)0;
1654 char *bpos
, *dpos
, *cp2
;
1655 int error
, wccflag
= NFSV3_WCCRATTR
, gotvp
= 0;
1656 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1657 const int v3
= NFS_ISV3(dvp
);
1658 u_int32_t excl_mode
= NFSV3CREATE_UNCHECKED
;
1661 * Oops, not for me..
1663 if (vap
->va_type
== VSOCK
)
1664 return (nfs_mknodrpc(dvp
, ap
->a_vpp
, cnp
, vap
));
1666 KASSERT(vap
->va_type
== VREG
);
1669 if (vap
->va_vaflags
& VA_EXCLUSIVE
) {
1670 excl_mode
= NFSV3CREATE_EXCLUSIVE
;
1675 nfsstats
.rpccnt
[NFSPROC_CREATE
]++;
1677 nfsm_reqhead(dnp
, NFSPROC_CREATE
, NFSX_FH(v3
) + 2 * NFSX_UNSIGNED
+
1678 nfsm_rndup(cnp
->cn_namelen
) + NFSX_SATTR(v3
));
1679 nfsm_fhtom(dnp
, v3
);
1680 nfsm_strtom(cnp
->cn_nameptr
, cnp
->cn_namelen
, NFS_MAXNAMLEN
);
1683 nfsm_build(tl
, u_int32_t
*, NFSX_UNSIGNED
);
1684 if (excl_mode
== NFSV3CREATE_EXCLUSIVE
) {
1685 *tl
= txdr_unsigned(NFSV3CREATE_EXCLUSIVE
);
1686 nfsm_build(tl
, u_int32_t
*, NFSX_V3CREATEVERF
);
1688 if (TAILQ_FIRST(&in_ifaddrhead
))
1689 *tl
++ = TAILQ_FIRST(&in_ifaddrhead
)->
1690 ia_addr
.sin_addr
.s_addr
;
1692 *tl
++ = create_verf
;
1694 *tl
++ = create_verf
;
1696 *tl
= ++create_verf
;
1698 *tl
= txdr_unsigned(excl_mode
);
1699 nfsm_v3attrbuild(vap
, false);
1704 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
1705 sp
->sa_mode
= vtonfsv2_mode(vap
->va_type
, vap
->va_mode
);
1706 sp
->sa_uid
= nfs_xdrneg1
;
1707 sp
->sa_gid
= nfs_xdrneg1
;
1709 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
1710 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
1712 nfsm_request(dnp
, NFSPROC_CREATE
, curlwp
, cnp
->cn_cred
);
1714 nfsm_mtofh(dvp
, newvp
, v3
, gotvp
);
1716 error
= nfs_lookitup(dvp
, cnp
->cn_nameptr
,
1717 cnp
->cn_namelen
, cnp
->cn_cred
, curlwp
, &np
);
1724 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
1729 * nfs_request maps NFSERR_NOTSUPP to ENOTSUP.
1731 if (v3
&& error
== ENOTSUP
) {
1732 if (excl_mode
== NFSV3CREATE_EXCLUSIVE
) {
1733 excl_mode
= NFSV3CREATE_GUARDED
;
1735 } else if (excl_mode
== NFSV3CREATE_GUARDED
) {
1736 excl_mode
= NFSV3CREATE_UNCHECKED
;
1740 } else if (v3
&& (excl_mode
== NFSV3CREATE_EXCLUSIVE
)) {
1746 * make sure that we'll update timestamps as
1747 * most server implementations use them to store
1748 * the create verifier.
1750 * XXX it's better to use TOSERVER always.
1753 if (vap
->va_atime
.tv_sec
== VNOVAL
)
1755 if (vap
->va_mtime
.tv_sec
== VNOVAL
)
1758 error
= nfs_setattrrpc(newvp
, vap
, cnp
->cn_cred
, curlwp
);
1761 if (cnp
->cn_flags
& MAKEENTRY
)
1762 nfs_cache_enter(dvp
, newvp
, cnp
);
1764 cache_purge1(dvp
, cnp
, 0);
1769 if (error
== EEXIST
)
1770 cache_purge1(dvp
, cnp
, 0);
1772 PNBUF_PUT(cnp
->cn_pnbuf
);
1773 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
1775 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
1776 VN_KNOTE(ap
->a_dvp
, NOTE_WRITE
);
1782 * nfs file remove call
1783 * To try and make nfs semantics closer to ufs semantics, a file that has
1784 * other processes using the vnode is renamed instead of removed and then
1785 * removed later on the last close.
1786 * - If v_usecount > 1
1787 * If a rename is not already in the works
1788 * call nfs_sillyrename() to set it up
1796 struct vop_remove_args
/* {
1797 struct vnodeop_desc *a_desc;
1798 struct vnode * a_dvp;
1799 struct vnode * a_vp;
1800 struct componentname * a_cnp;
1802 struct vnode
*vp
= ap
->a_vp
;
1803 struct vnode
*dvp
= ap
->a_dvp
;
1804 struct componentname
*cnp
= ap
->a_cnp
;
1805 struct nfsnode
*np
= VTONFS(vp
);
1810 if ((cnp
->cn_flags
& HASBUF
) == 0)
1811 panic("nfs_remove: no name");
1812 if (vp
->v_usecount
< 1)
1813 panic("nfs_remove: bad v_usecount");
1815 if (vp
->v_type
== VDIR
)
1817 else if (vp
->v_usecount
== 1 || (np
->n_sillyrename
&&
1818 VOP_GETATTR(vp
, &vattr
, cnp
->cn_cred
) == 0 &&
1819 vattr
.va_nlink
> 1)) {
1821 * Purge the name cache so that the chance of a lookup for
1822 * the name succeeding while the remove is in progress is
1823 * minimized. Without node locking it can still happen, such
1824 * that an I/O op returns ESTALE, but since you get this if
1825 * another host removes the file..
1829 * throw away biocache buffers, mainly to avoid
1830 * unnecessary delayed writes later.
1832 error
= nfs_vinvalbuf(vp
, 0, cnp
->cn_cred
, curlwp
, 1);
1835 error
= nfs_removerpc(dvp
, cnp
->cn_nameptr
,
1836 cnp
->cn_namelen
, cnp
->cn_cred
, curlwp
);
1837 } else if (!np
->n_sillyrename
)
1838 error
= nfs_sillyrename(dvp
, vp
, cnp
, false);
1839 PNBUF_PUT(cnp
->cn_pnbuf
);
1840 if (!error
&& nfs_getattrcache(vp
, &vattr
) == 0 &&
1841 vattr
.va_nlink
== 1) {
1842 np
->n_flag
|= NREMOVED
;
1844 NFS_INVALIDATE_ATTRCACHE(np
);
1845 VN_KNOTE(vp
, NOTE_DELETE
);
1846 VN_KNOTE(dvp
, NOTE_WRITE
);
1856 * nfs file remove rpc called from nfs_inactive
1860 struct sillyrename
*sp
;
1863 return (nfs_removerpc(sp
->s_dvp
, sp
->s_name
, sp
->s_namlen
, sp
->s_cred
,
1868 * Nfs remove rpc, called from nfs_remove() and nfs_removeit().
1871 nfs_removerpc(dvp
, name
, namelen
, cred
, l
)
1886 int error
= 0, wccflag
= NFSV3_WCCRATTR
;
1887 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
1888 const int v3
= NFS_ISV3(dvp
);
1890 struct nfsnode
*dnp
= VTONFS(dvp
);
1892 nfsstats
.rpccnt
[NFSPROC_REMOVE
]++;
1893 nfsm_reqhead(dnp
, NFSPROC_REMOVE
,
1894 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(namelen
));
1895 nfsm_fhtom(dnp
, v3
);
1896 nfsm_strtom(name
, namelen
, NFS_MAXNAMLEN
);
1897 nfsm_request1(dnp
, NFSPROC_REMOVE
, l
, cred
, &rexmit
);
1900 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
1903 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
1905 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
1907 * Kludge City: If the first reply to the remove rpc is lost..
1908 * the reply to the retransmitted request will be ENOENT
1909 * since the file was in fact removed
1910 * Therefore, we cheat and return success.
1912 if (rexmit
&& error
== ENOENT
)
1918 * nfs file rename call
1924 struct vop_rename_args
/* {
1925 struct vnode *a_fdvp;
1926 struct vnode *a_fvp;
1927 struct componentname *a_fcnp;
1928 struct vnode *a_tdvp;
1929 struct vnode *a_tvp;
1930 struct componentname *a_tcnp;
1932 struct vnode
*fvp
= ap
->a_fvp
;
1933 struct vnode
*tvp
= ap
->a_tvp
;
1934 struct vnode
*fdvp
= ap
->a_fdvp
;
1935 struct vnode
*tdvp
= ap
->a_tdvp
;
1936 struct componentname
*tcnp
= ap
->a_tcnp
;
1937 struct componentname
*fcnp
= ap
->a_fcnp
;
1941 if ((tcnp
->cn_flags
& HASBUF
) == 0 ||
1942 (fcnp
->cn_flags
& HASBUF
) == 0)
1943 panic("nfs_rename: no name");
1945 /* Check for cross-device rename */
1946 if ((fvp
->v_mount
!= tdvp
->v_mount
) ||
1947 (tvp
&& (fvp
->v_mount
!= tvp
->v_mount
))) {
1953 * If the tvp exists and is in use, sillyrename it before doing the
1954 * rename of the new file over it.
1956 * Have sillyrename use link instead of rename if possible,
1957 * so that we don't lose the file if the rename fails, and so
1958 * that there's no window when the "to" file doesn't exist.
1960 if (tvp
&& tvp
->v_usecount
> 1 && !VTONFS(tvp
)->n_sillyrename
&&
1961 tvp
->v_type
!= VDIR
&& !nfs_sillyrename(tdvp
, tvp
, tcnp
, true)) {
1962 VN_KNOTE(tvp
, NOTE_DELETE
);
1967 error
= nfs_renamerpc(fdvp
, fcnp
->cn_nameptr
, fcnp
->cn_namelen
,
1968 tdvp
, tcnp
->cn_nameptr
, tcnp
->cn_namelen
, tcnp
->cn_cred
,
1971 VN_KNOTE(fdvp
, NOTE_WRITE
);
1972 VN_KNOTE(tdvp
, NOTE_WRITE
);
1973 if (error
== 0 || error
== EEXIST
) {
1974 if (fvp
->v_type
== VDIR
)
1977 cache_purge1(fdvp
, fcnp
, 0);
1978 if (tvp
!= NULL
&& tvp
->v_type
== VDIR
)
1981 cache_purge1(tdvp
, tcnp
, 0);
1996 * nfs file rename rpc called from nfs_remove() above
1999 nfs_renameit(sdvp
, scnp
, sp
)
2001 struct componentname
*scnp
;
2002 struct sillyrename
*sp
;
2004 return (nfs_renamerpc(sdvp
, scnp
->cn_nameptr
, scnp
->cn_namelen
,
2005 sdvp
, sp
->s_name
, sp
->s_namlen
, scnp
->cn_cred
, curlwp
));
2009 * Do an nfs rename rpc. Called from nfs_rename() and nfs_renameit().
2012 nfs_renamerpc(fdvp
, fnameptr
, fnamelen
, tdvp
, tnameptr
, tnamelen
, cred
, l
)
2014 const char *fnameptr
;
2017 const char *tnameptr
;
2030 int error
= 0, fwccflag
= NFSV3_WCCRATTR
, twccflag
= NFSV3_WCCRATTR
;
2031 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2032 const int v3
= NFS_ISV3(fdvp
);
2034 struct nfsnode
*fdnp
= VTONFS(fdvp
);
2036 nfsstats
.rpccnt
[NFSPROC_RENAME
]++;
2037 nfsm_reqhead(fdnp
, NFSPROC_RENAME
,
2038 (NFSX_FH(v3
) + NFSX_UNSIGNED
)*2 + nfsm_rndup(fnamelen
) +
2039 nfsm_rndup(tnamelen
));
2040 nfsm_fhtom(fdnp
, v3
);
2041 nfsm_strtom(fnameptr
, fnamelen
, NFS_MAXNAMLEN
);
2042 nfsm_fhtom(VTONFS(tdvp
), v3
);
2043 nfsm_strtom(tnameptr
, tnamelen
, NFS_MAXNAMLEN
);
2044 nfsm_request1(fdnp
, NFSPROC_RENAME
, l
, cred
, &rexmit
);
2047 nfsm_wcc_data(fdvp
, fwccflag
, 0, !error
);
2048 nfsm_wcc_data(tdvp
, twccflag
, 0, !error
);
2052 VTONFS(fdvp
)->n_flag
|= NMODIFIED
;
2053 VTONFS(tdvp
)->n_flag
|= NMODIFIED
;
2055 NFS_INVALIDATE_ATTRCACHE(VTONFS(fdvp
));
2057 NFS_INVALIDATE_ATTRCACHE(VTONFS(tdvp
));
2059 * Kludge: Map ENOENT => 0 assuming that it is a reply to a retry.
2061 if (rexmit
&& error
== ENOENT
)
2067 * NFS link RPC, called from nfs_link.
2068 * Assumes dvp and vp locked, and leaves them that way.
2072 nfs_linkrpc(struct vnode
*dvp
, struct vnode
*vp
, const char *name
,
2073 size_t namelen
, kauth_cred_t cred
, struct lwp
*l
)
2083 int error
= 0, wccflag
= NFSV3_WCCRATTR
, attrflag
= 0;
2084 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2085 const int v3
= NFS_ISV3(dvp
);
2087 struct nfsnode
*np
= VTONFS(vp
);
2089 nfsstats
.rpccnt
[NFSPROC_LINK
]++;
2090 nfsm_reqhead(np
, NFSPROC_LINK
,
2091 NFSX_FH(v3
)*2 + NFSX_UNSIGNED
+ nfsm_rndup(namelen
));
2093 nfsm_fhtom(VTONFS(dvp
), v3
);
2094 nfsm_strtom(name
, namelen
, NFS_MAXNAMLEN
);
2095 nfsm_request1(np
, NFSPROC_LINK
, l
, cred
, &rexmit
);
2098 nfsm_postop_attr(vp
, attrflag
, 0);
2099 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
2104 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
2106 NFS_INVALIDATE_ATTRCACHE(VTONFS(vp
));
2108 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
2111 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
2113 if (rexmit
&& error
== EEXIST
)
2120 * nfs hard link create call
2126 struct vop_link_args
/* {
2127 struct vnode *a_dvp;
2129 struct componentname *a_cnp;
2131 struct vnode
*vp
= ap
->a_vp
;
2132 struct vnode
*dvp
= ap
->a_dvp
;
2133 struct componentname
*cnp
= ap
->a_cnp
;
2136 if (dvp
->v_mount
!= vp
->v_mount
) {
2137 VOP_ABORTOP(dvp
, cnp
);
2142 error
= vn_lock(vp
, LK_EXCLUSIVE
);
2144 VOP_ABORTOP(dvp
, cnp
);
2151 * Push all writes to the server, so that the attribute cache
2152 * doesn't get "out of sync" with the server.
2153 * XXX There should be a better way!
2155 VOP_FSYNC(vp
, cnp
->cn_cred
, FSYNC_WAIT
, 0, 0);
2157 error
= nfs_linkrpc(dvp
, vp
, cnp
->cn_nameptr
, cnp
->cn_namelen
,
2158 cnp
->cn_cred
, curlwp
);
2161 cache_purge1(dvp
, cnp
, 0);
2162 PNBUF_PUT(cnp
->cn_pnbuf
);
2165 VN_KNOTE(vp
, NOTE_LINK
);
2166 VN_KNOTE(dvp
, NOTE_WRITE
);
2172 * nfs symbolic link create call
2178 struct vop_symlink_args
/* {
2179 struct vnode *a_dvp;
2180 struct vnode **a_vpp;
2181 struct componentname *a_cnp;
2182 struct vattr *a_vap;
2185 struct vnode
*dvp
= ap
->a_dvp
;
2186 struct vattr
*vap
= ap
->a_vap
;
2187 struct componentname
*cnp
= ap
->a_cnp
;
2188 struct nfsv2_sattr
*sp
;
2192 char *bpos
, *dpos
, *cp2
;
2193 int slen
, error
= 0, wccflag
= NFSV3_WCCRATTR
, gotvp
;
2194 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2195 struct vnode
*newvp
= (struct vnode
*)0;
2196 const int v3
= NFS_ISV3(dvp
);
2198 struct nfsnode
*dnp
= VTONFS(dvp
);
2201 nfsstats
.rpccnt
[NFSPROC_SYMLINK
]++;
2202 slen
= strlen(ap
->a_target
);
2203 nfsm_reqhead(dnp
, NFSPROC_SYMLINK
, NFSX_FH(v3
) + 2*NFSX_UNSIGNED
+
2204 nfsm_rndup(cnp
->cn_namelen
) + nfsm_rndup(slen
) + NFSX_SATTR(v3
));
2205 nfsm_fhtom(dnp
, v3
);
2206 nfsm_strtom(cnp
->cn_nameptr
, cnp
->cn_namelen
, NFS_MAXNAMLEN
);
2209 nfsm_v3attrbuild(vap
, false);
2211 nfsm_strtom(ap
->a_target
, slen
, NFS_MAXPATHLEN
);
2214 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
2215 sp
->sa_mode
= vtonfsv2_mode(VLNK
, vap
->va_mode
);
2216 sp
->sa_uid
= nfs_xdrneg1
;
2217 sp
->sa_gid
= nfs_xdrneg1
;
2218 sp
->sa_size
= nfs_xdrneg1
;
2219 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
2220 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
2223 nfsm_request1(dnp
, NFSPROC_SYMLINK
, curlwp
, cnp
->cn_cred
,
2228 nfsm_mtofh(dvp
, newvp
, v3
, gotvp
);
2229 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
2234 * Kludge: Map EEXIST => 0 assuming that it is a reply to a retry.
2236 if (rexmit
&& error
== EEXIST
)
2238 if (error
== 0 || error
== EEXIST
)
2239 cache_purge1(dvp
, cnp
, 0);
2240 if (error
== 0 && newvp
== NULL
) {
2241 struct nfsnode
*np
= NULL
;
2243 error
= nfs_lookitup(dvp
, cnp
->cn_nameptr
, cnp
->cn_namelen
,
2244 cnp
->cn_cred
, curlwp
, &np
);
2254 PNBUF_PUT(cnp
->cn_pnbuf
);
2255 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
2257 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
2258 VN_KNOTE(dvp
, NOTE_WRITE
);
2270 struct vop_mkdir_args
/* {
2271 struct vnode *a_dvp;
2272 struct vnode **a_vpp;
2273 struct componentname *a_cnp;
2274 struct vattr *a_vap;
2276 struct vnode
*dvp
= ap
->a_dvp
;
2277 struct vattr
*vap
= ap
->a_vap
;
2278 struct componentname
*cnp
= ap
->a_cnp
;
2279 struct nfsv2_sattr
*sp
;
2284 struct nfsnode
*dnp
= VTONFS(dvp
), *np
= (struct nfsnode
*)0;
2285 struct vnode
*newvp
= (struct vnode
*)0;
2286 char *bpos
, *dpos
, *cp2
;
2287 int error
= 0, wccflag
= NFSV3_WCCRATTR
;
2290 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2291 const int v3
= NFS_ISV3(dvp
);
2293 len
= cnp
->cn_namelen
;
2294 nfsstats
.rpccnt
[NFSPROC_MKDIR
]++;
2295 nfsm_reqhead(dnp
, NFSPROC_MKDIR
,
2296 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(len
) + NFSX_SATTR(v3
));
2297 nfsm_fhtom(dnp
, v3
);
2298 nfsm_strtom(cnp
->cn_nameptr
, len
, NFS_MAXNAMLEN
);
2301 nfsm_v3attrbuild(vap
, false);
2305 nfsm_build(sp
, struct nfsv2_sattr
*, NFSX_V2SATTR
);
2306 sp
->sa_mode
= vtonfsv2_mode(VDIR
, vap
->va_mode
);
2307 sp
->sa_uid
= nfs_xdrneg1
;
2308 sp
->sa_gid
= nfs_xdrneg1
;
2309 sp
->sa_size
= nfs_xdrneg1
;
2310 txdr_nfsv2time(&vap
->va_atime
, &sp
->sa_atime
);
2311 txdr_nfsv2time(&vap
->va_mtime
, &sp
->sa_mtime
);
2313 nfsm_request1(dnp
, NFSPROC_MKDIR
, curlwp
, cnp
->cn_cred
, &rexmit
);
2315 nfsm_mtofh(dvp
, newvp
, v3
, gotvp
);
2317 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
2319 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
2321 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
2323 * Kludge: Map EEXIST => 0 assuming that you have a reply to a retry
2324 * if we can succeed in looking up the directory.
2326 if ((rexmit
&& error
== EEXIST
) || (!error
&& !gotvp
)) {
2329 newvp
= (struct vnode
*)0;
2331 error
= nfs_lookitup(dvp
, cnp
->cn_nameptr
, len
, cnp
->cn_cred
,
2335 if (newvp
->v_type
!= VDIR
|| newvp
== dvp
)
2347 VN_KNOTE(dvp
, NOTE_WRITE
| NOTE_LINK
);
2348 if (cnp
->cn_flags
& MAKEENTRY
)
2349 nfs_cache_enter(dvp
, newvp
, cnp
);
2352 PNBUF_PUT(cnp
->cn_pnbuf
);
2358 * nfs remove directory call
2364 struct vop_rmdir_args
/* {
2365 struct vnode *a_dvp;
2367 struct componentname *a_cnp;
2369 struct vnode
*vp
= ap
->a_vp
;
2370 struct vnode
*dvp
= ap
->a_dvp
;
2371 struct componentname
*cnp
= ap
->a_cnp
;
2380 int error
= 0, wccflag
= NFSV3_WCCRATTR
;
2382 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2383 const int v3
= NFS_ISV3(dvp
);
2384 struct nfsnode
*dnp
;
2389 PNBUF_PUT(cnp
->cn_pnbuf
);
2392 nfsstats
.rpccnt
[NFSPROC_RMDIR
]++;
2394 nfsm_reqhead(dnp
, NFSPROC_RMDIR
,
2395 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(cnp
->cn_namelen
));
2396 nfsm_fhtom(dnp
, v3
);
2397 nfsm_strtom(cnp
->cn_nameptr
, cnp
->cn_namelen
, NFS_MAXNAMLEN
);
2398 nfsm_request1(dnp
, NFSPROC_RMDIR
, curlwp
, cnp
->cn_cred
, &rexmit
);
2401 nfsm_wcc_data(dvp
, wccflag
, 0, !error
);
2404 PNBUF_PUT(cnp
->cn_pnbuf
);
2405 VTONFS(dvp
)->n_flag
|= NMODIFIED
;
2407 NFS_INVALIDATE_ATTRCACHE(VTONFS(dvp
));
2408 VN_KNOTE(dvp
, NOTE_WRITE
| NOTE_LINK
);
2409 VN_KNOTE(vp
, NOTE_DELETE
);
2414 * Kludge: Map ENOENT => 0 assuming that you have a reply to a retry.
2416 if (rexmit
&& error
== ENOENT
)
2428 struct vop_readdir_args
/* {
2431 kauth_cred_t a_cred;
2436 struct vnode
*vp
= ap
->a_vp
;
2437 struct uio
*uio
= ap
->a_uio
;
2438 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
2439 char *base
= uio
->uio_iov
->iov_base
;
2443 off_t
*cookies
= NULL
;
2444 int ncookies
= 0, nc
;
2446 if (vp
->v_type
!= VDIR
)
2449 lost
= uio
->uio_resid
& (NFS_DIRFRAGSIZ
- 1);
2450 count
= uio
->uio_resid
- lost
;
2455 * Call nfs_bioread() to do the real work.
2457 tresid
= uio
->uio_resid
= count
;
2458 error
= nfs_bioread(vp
, uio
, 0, ap
->a_cred
,
2459 ap
->a_cookies
? NFSBIO_CACHECOOKIES
: 0);
2461 if (!error
&& ap
->a_cookies
) {
2462 ncookies
= count
/ 16;
2463 cookies
= malloc(sizeof (off_t
) * ncookies
, M_TEMP
, M_WAITOK
);
2464 *ap
->a_cookies
= cookies
;
2467 if (!error
&& uio
->uio_resid
== tresid
) {
2468 uio
->uio_resid
+= lost
;
2469 nfsstats
.direofcache_misses
++;
2471 *ap
->a_ncookies
= 0;
2476 if (!error
&& ap
->a_cookies
) {
2478 * Only the NFS server and emulations use cookies, and they
2479 * load the directory block into system space, so we can
2480 * just look at it directly.
2482 if (!VMSPACE_IS_KERNEL_P(uio
->uio_vmspace
) ||
2483 uio
->uio_iovcnt
!= 1)
2484 panic("nfs_readdir: lost in space");
2485 for (nc
= 0; ncookies
-- &&
2486 base
< (char *)uio
->uio_iov
->iov_base
; nc
++){
2487 dp
= (struct dirent
*) base
;
2488 if (dp
->d_reclen
== 0)
2490 if (nmp
->nm_flag
& NFSMNT_XLATECOOKIE
)
2491 *(cookies
++) = (off_t
)NFS_GETCOOKIE32(dp
);
2493 *(cookies
++) = NFS_GETCOOKIE(dp
);
2494 base
+= dp
->d_reclen
;
2497 ((char *)uio
->uio_iov
->iov_base
- base
);
2498 uio
->uio_iov
->iov_len
+=
2499 ((char *)uio
->uio_iov
->iov_base
- base
);
2500 uio
->uio_iov
->iov_base
= base
;
2501 *ap
->a_ncookies
= nc
;
2504 uio
->uio_resid
+= lost
;
2511 * Called from below the buffer cache by nfs_doio().
2514 nfs_readdirrpc(vp
, uiop
, cred
)
2520 struct dirent
*dp
= NULL
;
2524 char *bpos
, *dpos
, *cp2
;
2525 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2526 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
2527 struct nfsnode
*dnp
= VTONFS(vp
);
2529 int error
= 0, more_dirs
= 1, blksiz
= 0, bigenough
= 1;
2533 int nrpcs
= 0, reclen
;
2534 const int v3
= NFS_ISV3(vp
);
2538 * Should be called from buffer cache, so only amount of
2539 * NFS_DIRBLKSIZ will be requested.
2541 if (uiop
->uio_iovcnt
!= 1 || uiop
->uio_resid
!= NFS_DIRBLKSIZ
)
2542 panic("nfs readdirrpc bad uio");
2546 * Loop around doing readdir rpc's of size nm_readdirsize
2547 * truncated to a multiple of NFS_DIRFRAGSIZ.
2548 * The stopping criteria is EOF or buffer full.
2550 while (more_dirs
&& bigenough
) {
2552 * Heuristic: don't bother to do another RPC to further
2553 * fill up this block if there is not much room left. (< 50%
2554 * of the readdir RPC size). This wastes some buffer space
2555 * but can save up to 50% in RPC calls.
2557 if (nrpcs
> 0 && uiop
->uio_resid
< (nmp
->nm_readdirsize
/ 2)) {
2561 nfsstats
.rpccnt
[NFSPROC_READDIR
]++;
2562 nfsm_reqhead(dnp
, NFSPROC_READDIR
, NFSX_FH(v3
) +
2564 nfsm_fhtom(dnp
, v3
);
2567 nfsm_build(tl
, u_int32_t
*, 5 * NFSX_UNSIGNED
);
2568 if (nmp
->nm_iflag
& NFSMNT_SWAPCOOKIE
) {
2569 txdr_swapcookie3(uiop
->uio_offset
, tl
);
2571 txdr_cookie3(uiop
->uio_offset
, tl
);
2574 *tl
++ = dnp
->n_cookieverf
.nfsuquad
[0];
2575 *tl
++ = dnp
->n_cookieverf
.nfsuquad
[1];
2579 nfsm_build(tl
, u_int32_t
*, 2 * NFSX_UNSIGNED
);
2580 *tl
++ = txdr_unsigned(uiop
->uio_offset
);
2582 *tl
= txdr_unsigned(nmp
->nm_readdirsize
);
2583 nfsm_request(dnp
, NFSPROC_READDIR
, curlwp
, cred
);
2587 nfsm_postop_attr(vp
, attrflag
, 0);
2589 nfsm_dissect(tl
, u_int32_t
*,
2591 dnp
->n_cookieverf
.nfsuquad
[0] = *tl
++;
2592 dnp
->n_cookieverf
.nfsuquad
[1] = *tl
;
2599 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2600 more_dirs
= fxdr_unsigned(int, *tl
);
2602 /* loop thru the dir entries, doctoring them to 4bsd form */
2603 while (more_dirs
&& bigenough
) {
2606 nfsm_dissect(tl
, u_int32_t
*,
2608 fileno
= fxdr_hyper(tl
);
2609 len
= fxdr_unsigned(int, *(tl
+ 2));
2613 nfsm_dissect(tl
, u_int32_t
*,
2615 fileno
= fxdr_unsigned(u_quad_t
, *tl
++);
2616 len
= fxdr_unsigned(int, *tl
);
2618 if (len
<= 0 || len
> NFS_MAXNAMLEN
) {
2623 /* for cookie stashing */
2624 reclen
= _DIRENT_RECLEN(dp
, len
) + 2 * sizeof(off_t
);
2625 left
= NFS_DIRFRAGSIZ
- blksiz
;
2626 if (reclen
> left
) {
2627 memset(uiop
->uio_iov
->iov_base
, 0, left
);
2628 dp
->d_reclen
+= left
;
2629 UIO_ADVANCE(uiop
, left
);
2631 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2633 if (reclen
> uiop
->uio_resid
)
2638 dp
= (struct dirent
*)uiop
->uio_iov
->iov_base
;
2639 dp
->d_fileno
= fileno
;
2641 dp
->d_reclen
= reclen
;
2642 dp
->d_type
= DT_UNKNOWN
;
2644 if (blksiz
== NFS_DIRFRAGSIZ
)
2646 UIO_ADVANCE(uiop
, DIRHDSIZ
);
2647 nfsm_mtouio(uiop
, len
);
2648 tlen
= reclen
- (DIRHDSIZ
+ len
);
2649 (void)memset(uiop
->uio_iov
->iov_base
, 0, tlen
);
2650 UIO_ADVANCE(uiop
, tlen
);
2652 nfsm_adv(nfsm_rndup(len
));
2655 nfsm_dissect(tl
, u_int32_t
*,
2660 nfsm_dissect(tl
, u_int32_t
*,
2666 if (nmp
->nm_iflag
& NFSMNT_SWAPCOOKIE
)
2668 fxdr_swapcookie3(tl
);
2677 fxdr_unsigned(off_t
, *tl
);
2679 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2685 more_dirs
= fxdr_unsigned(int, *tl
);
2688 * If at end of rpc data, get the eof boolean
2691 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2692 more_dirs
= (fxdr_unsigned(int, *tl
) == 0);
2695 * kludge: if we got no entries, treat it as EOF.
2696 * some server sometimes send a reply without any
2698 * although it might mean the server has very long name,
2699 * we can't handle such entries anyway.
2702 if (uiop
->uio_resid
>= NFS_DIRBLKSIZ
)
2708 * Fill last record, iff any, out to a multiple of NFS_DIRFRAGSIZ
2709 * by increasing d_reclen for the last record.
2712 left
= NFS_DIRFRAGSIZ
- blksiz
;
2713 memset(uiop
->uio_iov
->iov_base
, 0, left
);
2714 dp
->d_reclen
+= left
;
2715 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2716 UIO_ADVANCE(uiop
, left
);
2720 * We are now either at the end of the directory or have filled the
2724 dnp
->n_direofoffset
= uiop
->uio_offset
;
2725 dnp
->n_flag
|= NEOFVALID
;
2733 * NFS V3 readdir plus RPC. Used in place of nfs_readdirrpc().
2736 nfs_readdirplusrpc(vp
, uiop
, cred
)
2742 struct dirent
*dp
= NULL
;
2746 struct vnode
*newvp
;
2747 char *bpos
, *dpos
, *cp2
;
2748 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
2749 struct nameidata nami
, *ndp
= &nami
;
2750 struct componentname
*cnp
= &ndp
->ni_cnd
;
2751 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
2752 struct nfsnode
*dnp
= VTONFS(vp
), *np
;
2755 int error
= 0, more_dirs
= 1, blksiz
= 0, doit
, bigenough
= 1, i
;
2756 int attrflag
, fhsize
, nrpcs
= 0, reclen
;
2757 struct nfs_fattr fattr
, *fp
;
2760 if (uiop
->uio_iovcnt
!= 1 || uiop
->uio_resid
!= NFS_DIRBLKSIZ
)
2761 panic("nfs readdirplusrpc bad uio");
2767 * Loop around doing readdir rpc's of size nm_readdirsize
2768 * truncated to a multiple of NFS_DIRFRAGSIZ.
2769 * The stopping criteria is EOF or buffer full.
2771 while (more_dirs
&& bigenough
) {
2772 if (nrpcs
> 0 && uiop
->uio_resid
< (nmp
->nm_readdirsize
/ 2)) {
2776 nfsstats
.rpccnt
[NFSPROC_READDIRPLUS
]++;
2777 nfsm_reqhead(dnp
, NFSPROC_READDIRPLUS
,
2778 NFSX_FH(1) + 6 * NFSX_UNSIGNED
);
2780 nfsm_build(tl
, u_int32_t
*, 6 * NFSX_UNSIGNED
);
2781 if (nmp
->nm_iflag
& NFSMNT_SWAPCOOKIE
) {
2782 txdr_swapcookie3(uiop
->uio_offset
, tl
);
2784 txdr_cookie3(uiop
->uio_offset
, tl
);
2787 *tl
++ = dnp
->n_cookieverf
.nfsuquad
[0];
2788 *tl
++ = dnp
->n_cookieverf
.nfsuquad
[1];
2789 *tl
++ = txdr_unsigned(nmp
->nm_readdirsize
);
2790 *tl
= txdr_unsigned(nmp
->nm_rsize
);
2791 nfsm_request(dnp
, NFSPROC_READDIRPLUS
, curlwp
, cred
);
2792 nfsm_postop_attr(vp
, attrflag
, 0);
2798 nfsm_dissect(tl
, u_int32_t
*, 3 * NFSX_UNSIGNED
);
2799 dnp
->n_cookieverf
.nfsuquad
[0] = *tl
++;
2800 dnp
->n_cookieverf
.nfsuquad
[1] = *tl
++;
2801 more_dirs
= fxdr_unsigned(int, *tl
);
2803 /* loop thru the dir entries, doctoring them to 4bsd form */
2804 while (more_dirs
&& bigenough
) {
2805 nfsm_dissect(tl
, u_int32_t
*, 3 * NFSX_UNSIGNED
);
2806 fileno
= fxdr_hyper(tl
);
2807 len
= fxdr_unsigned(int, *(tl
+ 2));
2808 if (len
<= 0 || len
> NFS_MAXNAMLEN
) {
2813 /* for cookie stashing */
2814 reclen
= _DIRENT_RECLEN(dp
, len
) + 2 * sizeof(off_t
);
2815 left
= NFS_DIRFRAGSIZ
- blksiz
;
2816 if (reclen
> left
) {
2818 * DIRFRAGSIZ is aligned, no need to align
2821 memset(uiop
->uio_iov
->iov_base
, 0, left
);
2822 dp
->d_reclen
+= left
;
2823 UIO_ADVANCE(uiop
, left
);
2824 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2827 if (reclen
> uiop
->uio_resid
)
2832 dp
= (struct dirent
*)uiop
->uio_iov
->iov_base
;
2833 dp
->d_fileno
= fileno
;
2835 dp
->d_reclen
= reclen
;
2836 dp
->d_type
= DT_UNKNOWN
;
2838 if (blksiz
== NFS_DIRFRAGSIZ
)
2840 UIO_ADVANCE(uiop
, DIRHDSIZ
);
2841 nfsm_mtouio(uiop
, len
);
2842 tlen
= reclen
- (DIRHDSIZ
+ len
);
2843 (void)memset(uiop
->uio_iov
->iov_base
, 0, tlen
);
2844 UIO_ADVANCE(uiop
, tlen
);
2845 cnp
->cn_nameptr
= dp
->d_name
;
2846 cnp
->cn_namelen
= dp
->d_namlen
;
2848 nfsm_adv(nfsm_rndup(len
));
2849 nfsm_dissect(tl
, u_int32_t
*, 3 * NFSX_UNSIGNED
);
2851 if (nmp
->nm_iflag
& NFSMNT_SWAPCOOKIE
)
2853 fxdr_swapcookie3(tl
);
2857 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2862 * Since the attributes are before the file handle
2863 * (sigh), we must skip over the attributes and then
2864 * come back and get them.
2866 attrflag
= fxdr_unsigned(int, *tl
);
2868 nfsm_dissect(fp
, struct nfs_fattr
*, NFSX_V3FATTR
);
2869 memcpy(&fattr
, fp
, NFSX_V3FATTR
);
2870 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2871 doit
= fxdr_unsigned(int, *tl
);
2873 nfsm_getfh(fhp
, fhsize
, 1);
2874 if (NFS_CMPFH(dnp
, fhp
, fhsize
)) {
2879 error
= nfs_nget1(vp
->v_mount
, fhp
,
2880 fhsize
, &np
, LK_NOWAIT
);
2887 nfs_loadattrcache(&newvp
, &fattr
, 0, 0);
2890 IFTODT(VTTOIF(np
->n_vattr
->va_type
));
2891 if (cnp
->cn_namelen
<= NCHNAMLEN
) {
2893 xcp
= cnp
->cn_nameptr
+
2896 namei_hash(cnp
->cn_nameptr
, &xcp
);
2897 nfs_cache_enter(ndp
->ni_dvp
,
2905 /* Just skip over the file handle */
2906 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2907 i
= fxdr_unsigned(int, *tl
);
2908 nfsm_adv(nfsm_rndup(i
));
2910 if (newvp
!= NULLVP
) {
2917 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2918 more_dirs
= fxdr_unsigned(int, *tl
);
2921 * If at end of rpc data, get the eof boolean
2924 nfsm_dissect(tl
, u_int32_t
*, NFSX_UNSIGNED
);
2925 more_dirs
= (fxdr_unsigned(int, *tl
) == 0);
2928 * kludge: see a comment in nfs_readdirrpc.
2931 if (uiop
->uio_resid
>= NFS_DIRBLKSIZ
)
2937 * Fill last record, iff any, out to a multiple of NFS_DIRFRAGSIZ
2938 * by increasing d_reclen for the last record.
2941 left
= NFS_DIRFRAGSIZ
- blksiz
;
2942 memset(uiop
->uio_iov
->iov_base
, 0, left
);
2943 dp
->d_reclen
+= left
;
2944 NFS_STASHCOOKIE(dp
, uiop
->uio_offset
);
2945 UIO_ADVANCE(uiop
, left
);
2949 * We are now either at the end of the directory or have filled the
2953 dnp
->n_direofoffset
= uiop
->uio_offset
;
2954 dnp
->n_flag
|= NEOFVALID
;
2957 if (newvp
!= NULLVP
) {
2968 * Silly rename. To make the NFS filesystem that is stateless look a little
2969 * more like the "ufs" a remove of an active vnode is translated to a rename
2970 * to a funny looking filename that is removed by nfs_inactive on the
2971 * nfsnode. There is the potential for another process on a different client
2972 * to create the same funny name between the nfs_lookitup() fails and the
2973 * nfs_rename() completes, but...
2976 nfs_sillyrename(dvp
, vp
, cnp
, dolink
)
2977 struct vnode
*dvp
, *vp
;
2978 struct componentname
*cnp
;
2981 struct sillyrename
*sp
;
2989 if (vp
->v_type
== VDIR
)
2990 panic("nfs: sillyrename dir");
2992 sp
= kmem_alloc(sizeof(*sp
), KM_SLEEP
);
2993 sp
->s_cred
= kauth_cred_dup(cnp
->cn_cred
);
2997 /* Fudge together a funny name */
2998 pid
= curlwp
->l_proc
->p_pid
;
2999 memcpy(sp
->s_name
, ".nfsAxxxx4.4", 13);
3001 sp
->s_name
[8] = hexdigits
[pid
& 0xf];
3002 sp
->s_name
[7] = hexdigits
[(pid
>> 4) & 0xf];
3003 sp
->s_name
[6] = hexdigits
[(pid
>> 8) & 0xf];
3004 sp
->s_name
[5] = hexdigits
[(pid
>> 12) & 0xf];
3006 /* Try lookitups until we get one that isn't there */
3007 while (nfs_lookitup(dvp
, sp
->s_name
, sp
->s_namlen
, sp
->s_cred
,
3008 curlwp
, (struct nfsnode
**)0) == 0) {
3010 if (sp
->s_name
[4] > 'z') {
3016 error
= nfs_linkrpc(dvp
, vp
, sp
->s_name
, sp
->s_namlen
,
3017 sp
->s_cred
, curlwp
);
3019 * nfs_request maps NFSERR_NOTSUPP to ENOTSUP.
3021 if (error
== ENOTSUP
) {
3022 error
= nfs_renameit(dvp
, cnp
, sp
);
3025 error
= nfs_renameit(dvp
, cnp
, sp
);
3029 error
= nfs_lookitup(dvp
, sp
->s_name
, sp
->s_namlen
, sp
->s_cred
,
3031 np
->n_sillyrename
= sp
;
3035 kauth_cred_free(sp
->s_cred
);
3036 kmem_free(sp
, sizeof(*sp
));
3041 * Look up a file name and optionally either update the file handle or
3042 * allocate an nfsnode, depending on the value of npp.
3043 * npp == NULL --> just do the lookup
3044 * *npp == NULL --> allocate a new nfsnode and make sure attributes are
3046 * *npp != NULL --> update the file handle in the vnode
3049 nfs_lookitup(dvp
, name
, len
, cred
, l
, npp
)
3055 struct nfsnode
**npp
;
3060 struct vnode
*newvp
= (struct vnode
*)0;
3061 struct nfsnode
*np
, *dnp
= VTONFS(dvp
);
3062 char *bpos
, *dpos
, *cp2
;
3063 int error
= 0, fhlen
;
3067 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
3069 const int v3
= NFS_ISV3(dvp
);
3071 nfsstats
.rpccnt
[NFSPROC_LOOKUP
]++;
3072 nfsm_reqhead(dnp
, NFSPROC_LOOKUP
,
3073 NFSX_FH(v3
) + NFSX_UNSIGNED
+ nfsm_rndup(len
));
3074 nfsm_fhtom(dnp
, v3
);
3075 nfsm_strtom(name
, len
, NFS_MAXNAMLEN
);
3076 nfsm_request(dnp
, NFSPROC_LOOKUP
, l
, cred
);
3077 if (npp
&& !error
) {
3078 nfsm_getfh(nfhp
, fhlen
, v3
);
3081 if (np
->n_fhsize
> NFS_SMALLFH
&& fhlen
<= NFS_SMALLFH
) {
3082 kmem_free(np
->n_fhp
, np
->n_fhsize
);
3083 np
->n_fhp
= &np
->n_fh
;
3085 #if NFS_SMALLFH < NFSX_V3FHMAX
3086 else if (np
->n_fhsize
<= NFS_SMALLFH
&& fhlen
> NFS_SMALLFH
)
3087 np
->n_fhp
= kmem_alloc(fhlen
, KM_SLEEP
);
3089 memcpy(np
->n_fhp
, nfhp
, fhlen
);
3090 np
->n_fhsize
= fhlen
;
3092 } else if (NFS_CMPFH(dnp
, nfhp
, fhlen
)) {
3097 error
= nfs_nget(dvp
->v_mount
, nfhp
, fhlen
, &np
);
3106 nfsm_postop_attr(newvp
, attrflag
, 0);
3107 if (!attrflag
&& *npp
== NULL
) {
3114 nfsm_loadattr(newvp
, (struct vattr
*)0, 0);
3117 if (npp
&& *npp
== NULL
) {
3129 * Nfs Version 3 commit rpc
3132 nfs_commit(vp
, offset
, cnt
, l
)
3141 struct nfsmount
*nmp
= VFSTONFS(vp
->v_mount
);
3142 char *bpos
, *dpos
, *cp2
;
3143 int error
= 0, wccflag
= NFSV3_WCCRATTR
;
3144 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
3147 KASSERT(NFS_ISV3(vp
));
3149 #ifdef NFS_DEBUG_COMMIT
3150 printf("commit %lu - %lu\n", (unsigned long)offset
,
3151 (unsigned long)(offset
+ cnt
));
3154 mutex_enter(&nmp
->nm_lock
);
3155 if ((nmp
->nm_iflag
& NFSMNT_HASWRITEVERF
) == 0) {
3156 mutex_exit(&nmp
->nm_lock
);
3159 mutex_exit(&nmp
->nm_lock
);
3160 nfsstats
.rpccnt
[NFSPROC_COMMIT
]++;
3162 nfsm_reqhead(np
, NFSPROC_COMMIT
, NFSX_FH(1));
3164 nfsm_build(tl
, u_int32_t
*, 3 * NFSX_UNSIGNED
);
3165 txdr_hyper(offset
, tl
);
3167 *tl
= txdr_unsigned(cnt
);
3168 nfsm_request(np
, NFSPROC_COMMIT
, l
, np
->n_wcred
);
3169 nfsm_wcc_data(vp
, wccflag
, NAC_NOTRUNC
, false);
3171 nfsm_dissect(tl
, u_int32_t
*, NFSX_V3WRITEVERF
);
3172 mutex_enter(&nmp
->nm_lock
);
3173 if ((nmp
->nm_iflag
& NFSMNT_STALEWRITEVERF
) ||
3174 memcmp(nmp
->nm_writeverf
, tl
, NFSX_V3WRITEVERF
)) {
3175 memcpy(nmp
->nm_writeverf
, tl
, NFSX_V3WRITEVERF
);
3176 error
= NFSERR_STALEWRITEVERF
;
3177 nmp
->nm_iflag
|= NFSMNT_STALEWRITEVERF
;
3179 mutex_exit(&nmp
->nm_lock
);
3188 * - make nfs_bmap() essentially a no-op that does no translation
3189 * - do nfs_strategy() by doing I/O with nfs_readrpc/nfs_writerpc
3190 * (Maybe I could use the process's page mapping, but I was concerned that
3191 * Kernel Write might not be enabled and also figured copyout() would do
3192 * a lot more work than memcpy() and also it currently happens in the
3193 * context of the swapper process (2).
3199 struct vop_bmap_args
/* {
3202 struct vnode **a_vpp;
3206 struct vnode
*vp
= ap
->a_vp
;
3207 int bshift
= vp
->v_mount
->mnt_fs_bshift
- vp
->v_mount
->mnt_dev_bshift
;
3209 if (ap
->a_vpp
!= NULL
)
3211 if (ap
->a_bnp
!= NULL
)
3212 *ap
->a_bnp
= ap
->a_bn
<< bshift
;
3213 if (ap
->a_runp
!= NULL
)
3214 *ap
->a_runp
= 1024 * 1024; /* XXX */
3220 * For async requests when nfsiod(s) are running, queue the request by
3221 * calling nfs_asyncio(), otherwise just all nfs_doio() to do the
3228 struct vop_strategy_args
*ap
= v
;
3229 struct buf
*bp
= ap
->a_bp
;
3232 if ((bp
->b_flags
& (B_PHYS
|B_ASYNC
)) == (B_PHYS
|B_ASYNC
))
3233 panic("nfs physio/async");
3236 * If the op is asynchronous and an i/o daemon is waiting
3237 * queue the request, wake it up and wait for completion
3238 * otherwise just do it ourselves.
3240 if ((bp
->b_flags
& B_ASYNC
) == 0 || nfs_asyncio(bp
))
3241 error
= nfs_doio(bp
);
3246 * fsync vnode op. Just call nfs_flush() with commit == 1.
3253 struct vop_fsync_args
/* {
3254 struct vnodeop_desc *a_desc;
3255 struct vnode * a_vp;
3256 kauth_cred_t a_cred;
3263 struct vnode
*vp
= ap
->a_vp
;
3265 if (vp
->v_type
!= VREG
)
3268 return (nfs_flush(vp
, ap
->a_cred
,
3269 (ap
->a_flags
& FSYNC_WAIT
) != 0 ? MNT_WAIT
: 0, curlwp
, 1));
3273 * Flush all the data associated with a vnode.
3276 nfs_flush(struct vnode
*vp
, kauth_cred_t cred
, int waitfor
, struct lwp
*l
,
3279 struct nfsnode
*np
= VTONFS(vp
);
3281 int flushflags
= PGO_ALLPAGES
|PGO_CLEANIT
|PGO_SYNCIO
;
3282 UVMHIST_FUNC("nfs_flush"); UVMHIST_CALLED(ubchist
);
3284 mutex_enter(&vp
->v_interlock
);
3285 error
= VOP_PUTPAGES(vp
, 0, 0, flushflags
);
3286 if (np
->n_flag
& NWRITEERR
) {
3287 error
= np
->n_error
;
3288 np
->n_flag
&= ~NWRITEERR
;
3290 UVMHIST_LOG(ubchist
, "returning %d", error
,0,0,0);
3295 * Return POSIX pathconf information applicable to nfs.
3297 * N.B. The NFS V2 protocol doesn't support this RPC.
3304 struct vop_pathconf_args
/* {
3307 register_t *a_retval;
3309 struct nfsv3_pathconf
*pcp
;
3310 struct vnode
*vp
= ap
->a_vp
;
3311 struct mbuf
*mreq
, *mrep
, *md
, *mb
;
3314 char *bpos
, *dpos
, *cp
, *cp2
;
3315 int error
= 0, attrflag
;
3317 struct nfsmount
*nmp
;
3321 const int v3
= NFS_ISV3(vp
);
3322 struct nfsnode
*np
= VTONFS(vp
);
3324 switch (ap
->a_name
) {
3325 /* Names that can be resolved locally. */
3327 *ap
->a_retval
= PIPE_BUF
;
3332 /* Names that cannot be resolved locally; do an RPC, if possible. */
3335 case _PC_CHOWN_RESTRICTED
:
3341 nfsstats
.rpccnt
[NFSPROC_PATHCONF
]++;
3342 nfsm_reqhead(np
, NFSPROC_PATHCONF
, NFSX_FH(1));
3344 nfsm_request(np
, NFSPROC_PATHCONF
,
3345 curlwp
, curlwp
->l_cred
); /* XXX */
3346 nfsm_postop_attr(vp
, attrflag
, 0);
3348 nfsm_dissect(pcp
, struct nfsv3_pathconf
*,
3350 switch (ap
->a_name
) {
3353 fxdr_unsigned(register_t
, pcp
->pc_linkmax
);
3357 fxdr_unsigned(register_t
, pcp
->pc_namemax
);
3359 case _PC_CHOWN_RESTRICTED
:
3361 (pcp
->pc_chownrestricted
== nfs_true
);
3365 (pcp
->pc_notrunc
== nfs_true
);
3371 case _PC_FILESIZEBITS
:
3374 nmp
= VFSTONFS(vp
->v_mount
);
3375 if ((nmp
->nm_iflag
& NFSMNT_GOTFSINFO
) == 0)
3376 if ((error
= nfs_fsinfo(nmp
, vp
,
3377 curlwp
->l_cred
, curlwp
)) != 0) /* XXX */
3379 for (l
= 0, maxsize
= nmp
->nm_maxfilesize
;
3380 (maxsize
>> l
) > 0; l
++)
3382 *ap
->a_retval
= l
+ 1;
3386 *ap
->a_retval
= 32; /* NFS V2 limitation */
3398 * NFS advisory byte-level locks.
3404 struct vop_advlock_args
/* {
3411 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3413 return lf_advlock(ap
, &np
->n_lockf
, np
->n_size
);
3417 * Print out the contents of an nfsnode.
3423 struct vop_print_args
/* {
3426 struct vnode
*vp
= ap
->a_vp
;
3427 struct nfsnode
*np
= VTONFS(vp
);
3429 printf("tag VT_NFS, fileid %lld fsid 0x%lx",
3430 (unsigned long long)np
->n_vattr
->va_fileid
, np
->n_vattr
->va_fsid
);
3431 if (vp
->v_type
== VFIFO
)
3438 * nfs unlock wrapper.
3443 struct vop_unlock_args
/* {
3447 struct vnode
*vp
= ap
->a_vp
;
3450 * VOP_UNLOCK can be called by nfs_loadattrcache
3454 nfs_delayedtruncate(vp
);
3457 return genfs_unlock(v
);
3461 * nfs special file access vnode op.
3462 * Essentially just get vattr and then imitate iaccess() since the device is
3463 * local to the client.
3469 struct vop_access_args
/* {
3472 kauth_cred_t a_cred;
3476 struct vnode
*vp
= ap
->a_vp
;
3479 error
= VOP_GETATTR(vp
, &va
, ap
->a_cred
);
3484 * Disallow write attempts on filesystems mounted read-only;
3485 * unless the file is a socket, fifo, or a block or character
3486 * device resident on the filesystem.
3488 if ((ap
->a_mode
& VWRITE
) && (vp
->v_mount
->mnt_flag
& MNT_RDONLY
)) {
3489 switch (vp
->v_type
) {
3499 return (vaccess(va
.va_type
, va
.va_mode
,
3500 va
.va_uid
, va
.va_gid
, ap
->a_mode
, ap
->a_cred
));
3504 * Read wrapper for special devices.
3510 struct vop_read_args
/* {
3514 kauth_cred_t a_cred;
3516 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3522 getnanotime(&np
->n_atim
);
3523 return (VOCALL(spec_vnodeop_p
, VOFFSET(vop_read
), ap
));
3527 * Write wrapper for special devices.
3533 struct vop_write_args
/* {
3537 kauth_cred_t a_cred;
3539 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3545 getnanotime(&np
->n_mtim
);
3546 return (VOCALL(spec_vnodeop_p
, VOFFSET(vop_write
), ap
));
3550 * Close wrapper for special devices.
3552 * Update the times on the nfsnode then do device close.
3558 struct vop_close_args
/* {
3561 kauth_cred_t a_cred;
3564 struct vnode
*vp
= ap
->a_vp
;
3565 struct nfsnode
*np
= VTONFS(vp
);
3568 if (np
->n_flag
& (NACC
| NUPD
)) {
3570 if (vp
->v_usecount
== 1 &&
3571 (vp
->v_mount
->mnt_flag
& MNT_RDONLY
) == 0) {
3573 if (np
->n_flag
& NACC
)
3574 vattr
.va_atime
= np
->n_atim
;
3575 if (np
->n_flag
& NUPD
)
3576 vattr
.va_mtime
= np
->n_mtim
;
3577 (void)VOP_SETATTR(vp
, &vattr
, ap
->a_cred
);
3580 return (VOCALL(spec_vnodeop_p
, VOFFSET(vop_close
), ap
));
3584 * Read wrapper for fifos.
3590 struct vop_read_args
/* {
3594 kauth_cred_t a_cred;
3596 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3602 getnanotime(&np
->n_atim
);
3603 return (VOCALL(fifo_vnodeop_p
, VOFFSET(vop_read
), ap
));
3607 * Write wrapper for fifos.
3613 struct vop_write_args
/* {
3617 kauth_cred_t a_cred;
3619 struct nfsnode
*np
= VTONFS(ap
->a_vp
);
3625 getnanotime(&np
->n_mtim
);
3626 return (VOCALL(fifo_vnodeop_p
, VOFFSET(vop_write
), ap
));
3630 * Close wrapper for fifos.
3632 * Update the times on the nfsnode then do fifo close.
3638 struct vop_close_args
/* {
3641 kauth_cred_t a_cred;
3644 struct vnode
*vp
= ap
->a_vp
;
3645 struct nfsnode
*np
= VTONFS(vp
);
3648 if (np
->n_flag
& (NACC
| NUPD
)) {
3652 if (np
->n_flag
& NACC
)
3654 if (np
->n_flag
& NUPD
)
3657 if (vp
->v_usecount
== 1 &&
3658 (vp
->v_mount
->mnt_flag
& MNT_RDONLY
) == 0) {
3660 if (np
->n_flag
& NACC
)
3661 vattr
.va_atime
= np
->n_atim
;
3662 if (np
->n_flag
& NUPD
)
3663 vattr
.va_mtime
= np
->n_mtim
;
3664 (void)VOP_SETATTR(vp
, &vattr
, ap
->a_cred
);
3667 return (VOCALL(fifo_vnodeop_p
, VOFFSET(vop_close
), ap
));