lfs_vnops.c revision 1.269.2.2 1 /* $NetBSD: lfs_vnops.c,v 1.269.2.2 2016/07/14 18:45:39 martin Exp $ */
2
3 /*-
4 * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Konrad E. Schroder <perseant (at) hhhh.org>.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31 /*
32 * Copyright (c) 1986, 1989, 1991, 1993, 1995
33 * The Regents of the University of California. All rights reserved.
34 *
35 * Redistribution and use in source and binary forms, with or without
36 * modification, are permitted provided that the following conditions
37 * are met:
38 * 1. Redistributions of source code must retain the above copyright
39 * notice, this list of conditions and the following disclaimer.
40 * 2. Redistributions in binary form must reproduce the above copyright
41 * notice, this list of conditions and the following disclaimer in the
42 * documentation and/or other materials provided with the distribution.
43 * 3. Neither the name of the University nor the names of its contributors
44 * may be used to endorse or promote products derived from this software
45 * without specific prior written permission.
46 *
47 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
48 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
49 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
50 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
51 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
52 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
53 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
54 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
55 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
56 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
57 * SUCH DAMAGE.
58 *
59 * @(#)lfs_vnops.c 8.13 (Berkeley) 6/10/95
60 */
61
62 /* from NetBSD: ufs_vnops.c,v 1.213 2013/06/08 05:47:02 kardel Exp */
63 /*-
64 * Copyright (c) 2008 The NetBSD Foundation, Inc.
65 * All rights reserved.
66 *
67 * This code is derived from software contributed to The NetBSD Foundation
68 * by Wasabi Systems, Inc.
69 *
70 * Redistribution and use in source and binary forms, with or without
71 * modification, are permitted provided that the following conditions
72 * are met:
73 * 1. Redistributions of source code must retain the above copyright
74 * notice, this list of conditions and the following disclaimer.
75 * 2. Redistributions in binary form must reproduce the above copyright
76 * notice, this list of conditions and the following disclaimer in the
77 * documentation and/or other materials provided with the distribution.
78 *
79 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
80 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
81 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
82 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
83 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
84 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
85 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
86 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
87 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
88 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
89 * POSSIBILITY OF SUCH DAMAGE.
90 */
91 /*
92 * Copyright (c) 1982, 1986, 1989, 1993, 1995
93 * The Regents of the University of California. All rights reserved.
94 * (c) UNIX System Laboratories, Inc.
95 * All or some portions of this file are derived from material licensed
96 * to the University of California by American Telephone and Telegraph
97 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
98 * the permission of UNIX System Laboratories, Inc.
99 *
100 * Redistribution and use in source and binary forms, with or without
101 * modification, are permitted provided that the following conditions
102 * are met:
103 * 1. Redistributions of source code must retain the above copyright
104 * notice, this list of conditions and the following disclaimer.
105 * 2. Redistributions in binary form must reproduce the above copyright
106 * notice, this list of conditions and the following disclaimer in the
107 * documentation and/or other materials provided with the distribution.
108 * 3. Neither the name of the University nor the names of its contributors
109 * may be used to endorse or promote products derived from this software
110 * without specific prior written permission.
111 *
112 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
113 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
114 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
115 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
116 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
117 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
118 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
119 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
120 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
121 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
122 * SUCH DAMAGE.
123 *
124 * @(#)ufs_vnops.c 8.28 (Berkeley) 7/31/95
125 */
126
127 #include <sys/cdefs.h>
128 __KERNEL_RCSID(0, "$NetBSD: lfs_vnops.c,v 1.269.2.2 2016/07/14 18:45:39 martin Exp $");
129
130 #ifdef _KERNEL_OPT
131 #include "opt_compat_netbsd.h"
132 #include "opt_uvm_page_trkown.h"
133 #endif
134
135 #include <sys/param.h>
136 #include <sys/systm.h>
137 #include <sys/namei.h>
138 #include <sys/resourcevar.h>
139 #include <sys/kernel.h>
140 #include <sys/file.h>
141 #include <sys/stat.h>
142 #include <sys/buf.h>
143 #include <sys/proc.h>
144 #include <sys/mount.h>
145 #include <sys/vnode.h>
146 #include <sys/pool.h>
147 #include <sys/signalvar.h>
148 #include <sys/kauth.h>
149 #include <sys/syslog.h>
150 #include <sys/fstrans.h>
151
152 #include <miscfs/fifofs/fifo.h>
153 #include <miscfs/genfs/genfs.h>
154 #include <miscfs/specfs/specdev.h>
155
156 #include <ufs/lfs/ulfs_inode.h>
157 #include <ufs/lfs/ulfsmount.h>
158 #include <ufs/lfs/ulfs_bswap.h>
159 #include <ufs/lfs/ulfs_extern.h>
160
161 #include <uvm/uvm.h>
162 #include <uvm/uvm_pmap.h>
163 #include <uvm/uvm_stat.h>
164 #include <uvm/uvm_pager.h>
165
166 #include <ufs/lfs/lfs.h>
167 #include <ufs/lfs/lfs_kernel.h>
168 #include <ufs/lfs/lfs_extern.h>
169
170 extern pid_t lfs_writer_daemon;
171 int lfs_ignore_lazy_sync = 1;
172
173 static int lfs_openextattr(void *v);
174 static int lfs_closeextattr(void *v);
175 static int lfs_getextattr(void *v);
176 static int lfs_setextattr(void *v);
177 static int lfs_listextattr(void *v);
178 static int lfs_deleteextattr(void *v);
179
180 /*
181 * A virgin directory (no blushing please).
182 */
183 static const struct lfs_dirtemplate mastertemplate = {
184 0, 12, LFS_DT_DIR, 1, ".",
185 0, LFS_DIRBLKSIZ - 12, LFS_DT_DIR, 2, ".."
186 };
187
188 /* Global vfs data structures for lfs. */
189 int (**lfs_vnodeop_p)(void *);
190 const struct vnodeopv_entry_desc lfs_vnodeop_entries[] = {
191 { &vop_default_desc, vn_default_error },
192 { &vop_lookup_desc, ulfs_lookup }, /* lookup */
193 { &vop_create_desc, lfs_create }, /* create */
194 { &vop_whiteout_desc, ulfs_whiteout }, /* whiteout */
195 { &vop_mknod_desc, lfs_mknod }, /* mknod */
196 { &vop_open_desc, ulfs_open }, /* open */
197 { &vop_close_desc, lfs_close }, /* close */
198 { &vop_access_desc, ulfs_access }, /* access */
199 { &vop_getattr_desc, lfs_getattr }, /* getattr */
200 { &vop_setattr_desc, lfs_setattr }, /* setattr */
201 { &vop_read_desc, lfs_read }, /* read */
202 { &vop_write_desc, lfs_write }, /* write */
203 { &vop_fallocate_desc, genfs_eopnotsupp }, /* fallocate */
204 { &vop_fdiscard_desc, genfs_eopnotsupp }, /* fdiscard */
205 { &vop_ioctl_desc, ulfs_ioctl }, /* ioctl */
206 { &vop_fcntl_desc, lfs_fcntl }, /* fcntl */
207 { &vop_poll_desc, ulfs_poll }, /* poll */
208 { &vop_kqfilter_desc, genfs_kqfilter }, /* kqfilter */
209 { &vop_revoke_desc, ulfs_revoke }, /* revoke */
210 { &vop_mmap_desc, lfs_mmap }, /* mmap */
211 { &vop_fsync_desc, lfs_fsync }, /* fsync */
212 { &vop_seek_desc, ulfs_seek }, /* seek */
213 { &vop_remove_desc, lfs_remove }, /* remove */
214 { &vop_link_desc, lfs_link }, /* link */
215 { &vop_rename_desc, lfs_rename }, /* rename */
216 { &vop_mkdir_desc, lfs_mkdir }, /* mkdir */
217 { &vop_rmdir_desc, lfs_rmdir }, /* rmdir */
218 { &vop_symlink_desc, lfs_symlink }, /* symlink */
219 { &vop_readdir_desc, ulfs_readdir }, /* readdir */
220 { &vop_readlink_desc, ulfs_readlink }, /* readlink */
221 { &vop_abortop_desc, ulfs_abortop }, /* abortop */
222 { &vop_inactive_desc, lfs_inactive }, /* inactive */
223 { &vop_reclaim_desc, lfs_reclaim }, /* reclaim */
224 { &vop_lock_desc, ulfs_lock }, /* lock */
225 { &vop_unlock_desc, ulfs_unlock }, /* unlock */
226 { &vop_bmap_desc, ulfs_bmap }, /* bmap */
227 { &vop_strategy_desc, lfs_strategy }, /* strategy */
228 { &vop_print_desc, ulfs_print }, /* print */
229 { &vop_islocked_desc, ulfs_islocked }, /* islocked */
230 { &vop_pathconf_desc, ulfs_pathconf }, /* pathconf */
231 { &vop_advlock_desc, ulfs_advlock }, /* advlock */
232 { &vop_bwrite_desc, lfs_bwrite }, /* bwrite */
233 { &vop_getpages_desc, lfs_getpages }, /* getpages */
234 { &vop_putpages_desc, lfs_putpages }, /* putpages */
235 { &vop_openextattr_desc, lfs_openextattr }, /* openextattr */
236 { &vop_closeextattr_desc, lfs_closeextattr }, /* closeextattr */
237 { &vop_getextattr_desc, lfs_getextattr }, /* getextattr */
238 { &vop_setextattr_desc, lfs_setextattr }, /* setextattr */
239 { &vop_listextattr_desc, lfs_listextattr }, /* listextattr */
240 { &vop_deleteextattr_desc, lfs_deleteextattr }, /* deleteextattr */
241 { NULL, NULL }
242 };
243 const struct vnodeopv_desc lfs_vnodeop_opv_desc =
244 { &lfs_vnodeop_p, lfs_vnodeop_entries };
245
246 int (**lfs_specop_p)(void *);
247 const struct vnodeopv_entry_desc lfs_specop_entries[] = {
248 { &vop_default_desc, vn_default_error },
249 { &vop_lookup_desc, spec_lookup }, /* lookup */
250 { &vop_create_desc, spec_create }, /* create */
251 { &vop_mknod_desc, spec_mknod }, /* mknod */
252 { &vop_open_desc, spec_open }, /* open */
253 { &vop_close_desc, lfsspec_close }, /* close */
254 { &vop_access_desc, ulfs_access }, /* access */
255 { &vop_getattr_desc, lfs_getattr }, /* getattr */
256 { &vop_setattr_desc, lfs_setattr }, /* setattr */
257 { &vop_read_desc, ulfsspec_read }, /* read */
258 { &vop_write_desc, ulfsspec_write }, /* write */
259 { &vop_fallocate_desc, spec_fallocate }, /* fallocate */
260 { &vop_fdiscard_desc, spec_fdiscard }, /* fdiscard */
261 { &vop_ioctl_desc, spec_ioctl }, /* ioctl */
262 { &vop_fcntl_desc, ulfs_fcntl }, /* fcntl */
263 { &vop_poll_desc, spec_poll }, /* poll */
264 { &vop_kqfilter_desc, spec_kqfilter }, /* kqfilter */
265 { &vop_revoke_desc, spec_revoke }, /* revoke */
266 { &vop_mmap_desc, spec_mmap }, /* mmap */
267 { &vop_fsync_desc, spec_fsync }, /* fsync */
268 { &vop_seek_desc, spec_seek }, /* seek */
269 { &vop_remove_desc, spec_remove }, /* remove */
270 { &vop_link_desc, spec_link }, /* link */
271 { &vop_rename_desc, spec_rename }, /* rename */
272 { &vop_mkdir_desc, spec_mkdir }, /* mkdir */
273 { &vop_rmdir_desc, spec_rmdir }, /* rmdir */
274 { &vop_symlink_desc, spec_symlink }, /* symlink */
275 { &vop_readdir_desc, spec_readdir }, /* readdir */
276 { &vop_readlink_desc, spec_readlink }, /* readlink */
277 { &vop_abortop_desc, spec_abortop }, /* abortop */
278 { &vop_inactive_desc, lfs_inactive }, /* inactive */
279 { &vop_reclaim_desc, lfs_reclaim }, /* reclaim */
280 { &vop_lock_desc, ulfs_lock }, /* lock */
281 { &vop_unlock_desc, ulfs_unlock }, /* unlock */
282 { &vop_bmap_desc, spec_bmap }, /* bmap */
283 { &vop_strategy_desc, spec_strategy }, /* strategy */
284 { &vop_print_desc, ulfs_print }, /* print */
285 { &vop_islocked_desc, ulfs_islocked }, /* islocked */
286 { &vop_pathconf_desc, spec_pathconf }, /* pathconf */
287 { &vop_advlock_desc, spec_advlock }, /* advlock */
288 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */
289 { &vop_getpages_desc, spec_getpages }, /* getpages */
290 { &vop_putpages_desc, spec_putpages }, /* putpages */
291 { &vop_openextattr_desc, lfs_openextattr }, /* openextattr */
292 { &vop_closeextattr_desc, lfs_closeextattr }, /* closeextattr */
293 { &vop_getextattr_desc, lfs_getextattr }, /* getextattr */
294 { &vop_setextattr_desc, lfs_setextattr }, /* setextattr */
295 { &vop_listextattr_desc, lfs_listextattr }, /* listextattr */
296 { &vop_deleteextattr_desc, lfs_deleteextattr }, /* deleteextattr */
297 { NULL, NULL }
298 };
299 const struct vnodeopv_desc lfs_specop_opv_desc =
300 { &lfs_specop_p, lfs_specop_entries };
301
302 int (**lfs_fifoop_p)(void *);
303 const struct vnodeopv_entry_desc lfs_fifoop_entries[] = {
304 { &vop_default_desc, vn_default_error },
305 { &vop_lookup_desc, vn_fifo_bypass }, /* lookup */
306 { &vop_create_desc, vn_fifo_bypass }, /* create */
307 { &vop_mknod_desc, vn_fifo_bypass }, /* mknod */
308 { &vop_open_desc, vn_fifo_bypass }, /* open */
309 { &vop_close_desc, lfsfifo_close }, /* close */
310 { &vop_access_desc, ulfs_access }, /* access */
311 { &vop_getattr_desc, lfs_getattr }, /* getattr */
312 { &vop_setattr_desc, lfs_setattr }, /* setattr */
313 { &vop_read_desc, ulfsfifo_read }, /* read */
314 { &vop_write_desc, ulfsfifo_write }, /* write */
315 { &vop_fallocate_desc, vn_fifo_bypass }, /* fallocate */
316 { &vop_fdiscard_desc, vn_fifo_bypass }, /* fdiscard */
317 { &vop_ioctl_desc, vn_fifo_bypass }, /* ioctl */
318 { &vop_fcntl_desc, ulfs_fcntl }, /* fcntl */
319 { &vop_poll_desc, vn_fifo_bypass }, /* poll */
320 { &vop_kqfilter_desc, vn_fifo_bypass }, /* kqfilter */
321 { &vop_revoke_desc, vn_fifo_bypass }, /* revoke */
322 { &vop_mmap_desc, vn_fifo_bypass }, /* mmap */
323 { &vop_fsync_desc, vn_fifo_bypass }, /* fsync */
324 { &vop_seek_desc, vn_fifo_bypass }, /* seek */
325 { &vop_remove_desc, vn_fifo_bypass }, /* remove */
326 { &vop_link_desc, vn_fifo_bypass }, /* link */
327 { &vop_rename_desc, vn_fifo_bypass }, /* rename */
328 { &vop_mkdir_desc, vn_fifo_bypass }, /* mkdir */
329 { &vop_rmdir_desc, vn_fifo_bypass }, /* rmdir */
330 { &vop_symlink_desc, vn_fifo_bypass }, /* symlink */
331 { &vop_readdir_desc, vn_fifo_bypass }, /* readdir */
332 { &vop_readlink_desc, vn_fifo_bypass }, /* readlink */
333 { &vop_abortop_desc, vn_fifo_bypass }, /* abortop */
334 { &vop_inactive_desc, lfs_inactive }, /* inactive */
335 { &vop_reclaim_desc, lfs_reclaim }, /* reclaim */
336 { &vop_lock_desc, ulfs_lock }, /* lock */
337 { &vop_unlock_desc, ulfs_unlock }, /* unlock */
338 { &vop_bmap_desc, vn_fifo_bypass }, /* bmap */
339 { &vop_strategy_desc, vn_fifo_bypass }, /* strategy */
340 { &vop_print_desc, ulfs_print }, /* print */
341 { &vop_islocked_desc, ulfs_islocked }, /* islocked */
342 { &vop_pathconf_desc, vn_fifo_bypass }, /* pathconf */
343 { &vop_advlock_desc, vn_fifo_bypass }, /* advlock */
344 { &vop_bwrite_desc, lfs_bwrite }, /* bwrite */
345 { &vop_putpages_desc, vn_fifo_bypass }, /* putpages */
346 { &vop_openextattr_desc, lfs_openextattr }, /* openextattr */
347 { &vop_closeextattr_desc, lfs_closeextattr }, /* closeextattr */
348 { &vop_getextattr_desc, lfs_getextattr }, /* getextattr */
349 { &vop_setextattr_desc, lfs_setextattr }, /* setextattr */
350 { &vop_listextattr_desc, lfs_listextattr }, /* listextattr */
351 { &vop_deleteextattr_desc, lfs_deleteextattr }, /* deleteextattr */
352 { NULL, NULL }
353 };
354 const struct vnodeopv_desc lfs_fifoop_opv_desc =
355 { &lfs_fifoop_p, lfs_fifoop_entries };
356
357 #define LFS_READWRITE
358 #include <ufs/lfs/ulfs_readwrite.c>
359 #undef LFS_READWRITE
360
361 /*
362 * Synch an open file.
363 */
364 /* ARGSUSED */
365 int
366 lfs_fsync(void *v)
367 {
368 struct vop_fsync_args /* {
369 struct vnode *a_vp;
370 kauth_cred_t a_cred;
371 int a_flags;
372 off_t offlo;
373 off_t offhi;
374 } */ *ap = v;
375 struct vnode *vp = ap->a_vp;
376 int error, wait;
377 struct inode *ip = VTOI(vp);
378 struct lfs *fs = ip->i_lfs;
379
380 /* If we're mounted read-only, don't try to sync. */
381 if (fs->lfs_ronly)
382 return 0;
383
384 /* If a removed vnode is being cleaned, no need to sync here. */
385 if ((ap->a_flags & FSYNC_RECLAIM) != 0 && ip->i_mode == 0)
386 return 0;
387
388 /*
389 * Trickle sync simply adds this vnode to the pager list, as if
390 * the pagedaemon had requested a pageout.
391 */
392 if (ap->a_flags & FSYNC_LAZY) {
393 if (lfs_ignore_lazy_sync == 0) {
394 mutex_enter(&lfs_lock);
395 if (!(ip->i_flags & IN_PAGING)) {
396 ip->i_flags |= IN_PAGING;
397 TAILQ_INSERT_TAIL(&fs->lfs_pchainhd, ip,
398 i_lfs_pchain);
399 }
400 wakeup(&lfs_writer_daemon);
401 mutex_exit(&lfs_lock);
402 }
403 return 0;
404 }
405
406 /*
407 * If a vnode is bring cleaned, flush it out before we try to
408 * reuse it. This prevents the cleaner from writing files twice
409 * in the same partial segment, causing an accounting underflow.
410 */
411 if (ap->a_flags & FSYNC_RECLAIM && ip->i_flags & IN_CLEANING) {
412 lfs_vflush(vp);
413 }
414
415 wait = (ap->a_flags & FSYNC_WAIT);
416 do {
417 mutex_enter(vp->v_interlock);
418 error = VOP_PUTPAGES(vp, trunc_page(ap->a_offlo),
419 round_page(ap->a_offhi),
420 PGO_CLEANIT | (wait ? PGO_SYNCIO : 0));
421 if (error == EAGAIN) {
422 mutex_enter(&lfs_lock);
423 mtsleep(&fs->lfs_avail, PCATCH | PUSER, "lfs_fsync",
424 hz / 100 + 1, &lfs_lock);
425 mutex_exit(&lfs_lock);
426 }
427 } while (error == EAGAIN);
428 if (error)
429 return error;
430
431 if ((ap->a_flags & FSYNC_DATAONLY) == 0)
432 error = lfs_update(vp, NULL, NULL, wait ? UPDATE_WAIT : 0);
433
434 if (error == 0 && ap->a_flags & FSYNC_CACHE) {
435 int l = 0;
436 error = VOP_IOCTL(ip->i_devvp, DIOCCACHESYNC, &l, FWRITE,
437 curlwp->l_cred);
438 }
439 if (wait && !VPISEMPTY(vp))
440 LFS_SET_UINO(ip, IN_MODIFIED);
441
442 return error;
443 }
444
445 /*
446 * Take IN_ADIROP off, then call ulfs_inactive.
447 */
448 int
449 lfs_inactive(void *v)
450 {
451 struct vop_inactive_args /* {
452 struct vnode *a_vp;
453 } */ *ap = v;
454
455 lfs_unmark_vnode(ap->a_vp);
456
457 /*
458 * The Ifile is only ever inactivated on unmount.
459 * Streamline this process by not giving it more dirty blocks.
460 */
461 if (VTOI(ap->a_vp)->i_number == LFS_IFILE_INUM) {
462 mutex_enter(&lfs_lock);
463 LFS_CLR_UINO(VTOI(ap->a_vp), IN_ALLMOD);
464 mutex_exit(&lfs_lock);
465 VOP_UNLOCK(ap->a_vp);
466 return 0;
467 }
468
469 #ifdef DEBUG
470 /*
471 * This might happen on unmount.
472 * XXX If it happens at any other time, it should be a panic.
473 */
474 if (ap->a_vp->v_uflag & VU_DIROP) {
475 struct inode *ip = VTOI(ap->a_vp);
476 printf("lfs_inactive: inactivating VU_DIROP? ino = %d\n", (int)ip->i_number);
477 }
478 #endif /* DIAGNOSTIC */
479
480 return ulfs_inactive(v);
481 }
482
483 int
484 lfs_set_dirop(struct vnode *dvp, struct vnode *vp)
485 {
486 struct lfs *fs;
487 int error;
488
489 KASSERT(VOP_ISLOCKED(dvp));
490 KASSERT(vp == NULL || VOP_ISLOCKED(vp));
491
492 fs = VTOI(dvp)->i_lfs;
493
494 ASSERT_NO_SEGLOCK(fs);
495 /*
496 * LFS_NRESERVE calculates direct and indirect blocks as well
497 * as an inode block; an overestimate in most cases.
498 */
499 if ((error = lfs_reserve(fs, dvp, vp, LFS_NRESERVE(fs))) != 0)
500 return (error);
501
502 restart:
503 mutex_enter(&lfs_lock);
504 if (fs->lfs_dirops == 0) {
505 mutex_exit(&lfs_lock);
506 lfs_check(dvp, LFS_UNUSED_LBN, 0);
507 mutex_enter(&lfs_lock);
508 }
509 while (fs->lfs_writer) {
510 error = mtsleep(&fs->lfs_dirops, (PRIBIO + 1) | PCATCH,
511 "lfs_sdirop", 0, &lfs_lock);
512 if (error == EINTR) {
513 mutex_exit(&lfs_lock);
514 goto unreserve;
515 }
516 }
517 if (lfs_dirvcount > LFS_MAX_DIROP && fs->lfs_dirops == 0) {
518 wakeup(&lfs_writer_daemon);
519 mutex_exit(&lfs_lock);
520 preempt();
521 goto restart;
522 }
523
524 if (lfs_dirvcount > LFS_MAX_DIROP) {
525 DLOG((DLOG_DIROP, "lfs_set_dirop: sleeping with dirops=%d, "
526 "dirvcount=%d\n", fs->lfs_dirops, lfs_dirvcount));
527 if ((error = mtsleep(&lfs_dirvcount,
528 PCATCH | PUSER | PNORELOCK, "lfs_maxdirop", 0,
529 &lfs_lock)) != 0) {
530 mutex_exit(&lfs_lock);
531 goto unreserve;
532 }
533 mutex_exit(&lfs_lock);
534 goto restart;
535 }
536
537 ++fs->lfs_dirops;
538 /* fs->lfs_doifile = 1; */ /* XXX why? --ks */
539 mutex_exit(&lfs_lock);
540
541 /* Hold a reference so SET_ENDOP will be happy */
542 vref(dvp);
543 if (vp) {
544 vref(vp);
545 MARK_VNODE(vp);
546 }
547
548 MARK_VNODE(dvp);
549 return 0;
550
551 unreserve:
552 lfs_reserve(fs, dvp, vp, -LFS_NRESERVE(fs));
553 return error;
554 }
555
556 /*
557 * Opposite of lfs_set_dirop... mostly. For now at least must call
558 * UNMARK_VNODE(dvp) explicitly first. (XXX: clean that up)
559 */
560 void
561 lfs_unset_dirop(struct lfs *fs, struct vnode *dvp, const char *str)
562 {
563 mutex_enter(&lfs_lock);
564 --fs->lfs_dirops;
565 if (!fs->lfs_dirops) {
566 if (fs->lfs_nadirop) {
567 panic("lfs_unset_dirop: %s: no dirops but "
568 " nadirop=%d", str,
569 fs->lfs_nadirop);
570 }
571 wakeup(&fs->lfs_writer);
572 mutex_exit(&lfs_lock);
573 lfs_check(dvp, LFS_UNUSED_LBN, 0);
574 } else {
575 mutex_exit(&lfs_lock);
576 }
577 lfs_reserve(fs, dvp, NULL, -LFS_NRESERVE(fs));
578 }
579
580 void
581 lfs_mark_vnode(struct vnode *vp)
582 {
583 struct inode *ip = VTOI(vp);
584 struct lfs *fs = ip->i_lfs;
585
586 mutex_enter(&lfs_lock);
587 if (!(ip->i_flag & IN_ADIROP)) {
588 if (!(vp->v_uflag & VU_DIROP)) {
589 mutex_exit(&lfs_lock);
590 mutex_enter(vp->v_interlock);
591 if (lfs_vref(vp) != 0)
592 panic("lfs_mark_vnode: could not vref");
593 mutex_enter(&lfs_lock);
594 ++lfs_dirvcount;
595 ++fs->lfs_dirvcount;
596 TAILQ_INSERT_TAIL(&fs->lfs_dchainhd, ip, i_lfs_dchain);
597 vp->v_uflag |= VU_DIROP;
598 }
599 ++fs->lfs_nadirop;
600 ip->i_flag &= ~IN_CDIROP;
601 ip->i_flag |= IN_ADIROP;
602 } else
603 KASSERT(vp->v_uflag & VU_DIROP);
604 mutex_exit(&lfs_lock);
605 }
606
607 void
608 lfs_unmark_vnode(struct vnode *vp)
609 {
610 struct inode *ip = VTOI(vp);
611
612 mutex_enter(&lfs_lock);
613 if (ip && (ip->i_flag & IN_ADIROP)) {
614 KASSERT(vp->v_uflag & VU_DIROP);
615 --ip->i_lfs->lfs_nadirop;
616 ip->i_flag &= ~IN_ADIROP;
617 }
618 mutex_exit(&lfs_lock);
619 }
620
621 int
622 lfs_symlink(void *v)
623 {
624 struct vop_symlink_v3_args /* {
625 struct vnode *a_dvp;
626 struct vnode **a_vpp;
627 struct componentname *a_cnp;
628 struct vattr *a_vap;
629 char *a_target;
630 } */ *ap = v;
631 struct lfs *fs;
632 struct vnode *dvp, **vpp;
633 struct inode *ip;
634 struct ulfs_lookup_results *ulr;
635 ssize_t len; /* XXX should be size_t */
636 int error;
637
638 dvp = ap->a_dvp;
639 vpp = ap->a_vpp;
640
641 KASSERT(vpp != NULL);
642 KASSERT(*vpp == NULL);
643
644 /* XXX should handle this material another way */
645 ulr = &VTOI(ap->a_dvp)->i_crap;
646 ULFS_CHECK_CRAPCOUNTER(VTOI(ap->a_dvp));
647
648 fs = VFSTOULFS(dvp->v_mount)->um_lfs;
649 ASSERT_NO_SEGLOCK(fs);
650 if (fs->lfs_ronly) {
651 return EROFS;
652 }
653
654 /*
655 * Get a new vnode *before* adjusting the dirop count, to
656 * avoid a deadlock in getnewvnode(), if we have a stacked
657 * filesystem mounted on top of us.
658 *
659 * NB: this means we have to destroy the new vnode on error.
660 */
661
662 error = getnewvnode(VT_LFS, dvp->v_mount, lfs_vnodeop_p, NULL, vpp);
663 if (error) {
664 DLOG((DLOG_ALLOC, "lfs_mkdir: dvp %p error %d\n", dvp, error));
665 return error;
666 }
667 KASSERT(*vpp != NULL);
668
669 error = lfs_set_dirop(dvp, NULL);
670 if (error) {
671 ungetnewvnode(*vpp);
672 *vpp = NULL;
673 return error;
674 }
675
676 fstrans_start(dvp->v_mount, FSTRANS_SHARED);
677 error = ulfs_makeinode(LFS_IFLNK | ap->a_vap->va_mode, dvp, ulr,
678 vpp, ap->a_cnp);
679 if (error) {
680 goto out;
681 }
682
683 VN_KNOTE(ap->a_dvp, NOTE_WRITE);
684 ip = VTOI(*vpp);
685
686 len = strlen(ap->a_target);
687 if (len < ip->i_lfs->um_maxsymlinklen) {
688 memcpy((char *)SHORTLINK(ip), ap->a_target, len);
689 ip->i_size = len;
690 DIP_ASSIGN(ip, size, len);
691 uvm_vnp_setsize(*vpp, ip->i_size);
692 ip->i_flag |= IN_CHANGE | IN_UPDATE;
693 if ((*vpp)->v_mount->mnt_flag & MNT_RELATIME)
694 ip->i_flag |= IN_ACCESS;
695 } else {
696 error = vn_rdwr(UIO_WRITE, *vpp, ap->a_target, len, (off_t)0,
697 UIO_SYSSPACE, IO_NODELOCKED | IO_JOURNALLOCKED,
698 ap->a_cnp->cn_cred, NULL, NULL);
699 }
700
701 VOP_UNLOCK(*vpp);
702 if (error)
703 vrele(*vpp);
704
705 out:
706 fstrans_done(dvp->v_mount);
707
708 UNMARK_VNODE(dvp);
709 /* XXX: is it even possible for the symlink to get MARK'd? */
710 UNMARK_VNODE(*vpp);
711 if (!((*vpp)->v_uflag & VU_DIROP)) {
712 KASSERT(error != 0);
713 ungetnewvnode(*vpp);
714 *vpp = NULL;
715 }
716 else {
717 /*KASSERT(error == 0);*/
718 }
719 lfs_unset_dirop(fs, dvp, "symlink");
720
721 vrele(dvp);
722 return (error);
723 }
724
725 int
726 lfs_mknod(void *v)
727 {
728 struct vop_mknod_v3_args /* {
729 struct vnode *a_dvp;
730 struct vnode **a_vpp;
731 struct componentname *a_cnp;
732 struct vattr *a_vap;
733 } */ *ap = v;
734 struct lfs *fs;
735 struct vnode *dvp, **vpp;
736 struct vattr *vap;
737 struct inode *ip;
738 int error;
739 struct mount *mp;
740 ino_t ino;
741 struct ulfs_lookup_results *ulr;
742
743 dvp = ap->a_dvp;
744 vpp = ap->a_vpp;
745 vap = ap->a_vap;
746
747 KASSERT(vpp != NULL);
748 KASSERT(*vpp == NULL);
749
750 /* XXX should handle this material another way */
751 ulr = &VTOI(dvp)->i_crap;
752 ULFS_CHECK_CRAPCOUNTER(VTOI(dvp));
753
754 fs = VFSTOULFS(dvp->v_mount)->um_lfs;
755 ASSERT_NO_SEGLOCK(fs);
756 if (fs->lfs_ronly) {
757 return EROFS;
758 }
759
760 /*
761 * Get a new vnode *before* adjusting the dirop count, to
762 * avoid a deadlock in getnewvnode(), if we have a stacked
763 * filesystem mounted on top of us.
764 *
765 * NB: this means we have to destroy the new vnode on error.
766 */
767
768 error = getnewvnode(VT_LFS, dvp->v_mount, lfs_vnodeop_p, NULL, vpp);
769 if (error) {
770 DLOG((DLOG_ALLOC, "lfs_mknod: dvp %p error %d\n", dvp, error));
771 return error;
772 }
773 KASSERT(*vpp != NULL);
774
775 error = lfs_set_dirop(dvp, NULL);
776 if (error) {
777 ungetnewvnode(*vpp);
778 *vpp = NULL;
779 return error;
780 }
781
782 fstrans_start(ap->a_dvp->v_mount, FSTRANS_SHARED);
783 error = ulfs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
784 dvp, ulr, vpp, ap->a_cnp);
785
786 /* Either way we're done with the dirop at this point */
787 UNMARK_VNODE(dvp);
788 UNMARK_VNODE(*vpp);
789 if (!((*vpp)->v_uflag & VU_DIROP)) {
790 KASSERT(error != 0);
791 ungetnewvnode(*vpp);
792 *vpp = NULL;
793 }
794 else {
795 /*KASSERT(error == 0);*/
796 }
797 lfs_unset_dirop(fs, dvp, "mknod");
798 /*
799 * XXX this is where this used to be (though inside some evil
800 * macros) but it clearly should be moved further down.
801 * - dholland 20140515
802 */
803 vrele(dvp);
804
805 if (error) {
806 fstrans_done(ap->a_dvp->v_mount);
807 *vpp = NULL;
808 return (error);
809 }
810
811 VN_KNOTE(dvp, NOTE_WRITE);
812 ip = VTOI(*vpp);
813 mp = (*vpp)->v_mount;
814 ino = ip->i_number;
815 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
816 if (vap->va_rdev != VNOVAL) {
817 struct ulfsmount *ump = ip->i_ump;
818 KASSERT(fs == ip->i_lfs);
819 /*
820 * Want to be able to use this to make badblock
821 * inodes, so don't truncate the dev number.
822 */
823 if (ump->um_fstype == ULFS1)
824 ip->i_ffs1_rdev = ulfs_rw32(vap->va_rdev,
825 ULFS_MPNEEDSWAP(fs));
826 else
827 ip->i_ffs2_rdev = ulfs_rw64(vap->va_rdev,
828 ULFS_MPNEEDSWAP(fs));
829 }
830
831 /*
832 * Call fsync to write the vnode so that we don't have to deal with
833 * flushing it when it's marked VU_DIROP or reclaiming.
834 *
835 * XXX KS - If we can't flush we also can't call vgone(), so must
836 * return. But, that leaves this vnode in limbo, also not good.
837 * Can this ever happen (barring hardware failure)?
838 */
839 if ((error = VOP_FSYNC(*vpp, NOCRED, FSYNC_WAIT, 0, 0)) != 0) {
840 panic("lfs_mknod: couldn't fsync (ino %llu)",
841 (unsigned long long)ino);
842 /* return (error); */
843 }
844 /*
845 * Remove vnode so that it will be reloaded by VFS_VGET and
846 * checked to see if it is an alias of an existing entry in
847 * the inode cache.
848 */
849 /* Used to be vput, but that causes us to call VOP_INACTIVE twice. */
850
851 (*vpp)->v_type = VNON;
852 VOP_UNLOCK(*vpp);
853 vgone(*vpp);
854 error = VFS_VGET(mp, ino, vpp);
855
856 fstrans_done(ap->a_dvp->v_mount);
857 if (error != 0) {
858 *vpp = NULL;
859 return (error);
860 }
861 VOP_UNLOCK(*vpp);
862 return (0);
863 }
864
865 /*
866 * Create a regular file
867 */
868 int
869 lfs_create(void *v)
870 {
871 struct vop_create_v3_args /* {
872 struct vnode *a_dvp;
873 struct vnode **a_vpp;
874 struct componentname *a_cnp;
875 struct vattr *a_vap;
876 } */ *ap = v;
877 struct lfs *fs;
878 struct vnode *dvp, **vpp;
879 struct vattr *vap;
880 struct ulfs_lookup_results *ulr;
881 int error;
882
883 dvp = ap->a_dvp;
884 vpp = ap->a_vpp;
885 vap = ap->a_vap;
886
887 KASSERT(vpp != NULL);
888 KASSERT(*vpp == NULL);
889
890 /* XXX should handle this material another way */
891 ulr = &VTOI(dvp)->i_crap;
892 ULFS_CHECK_CRAPCOUNTER(VTOI(dvp));
893
894 fs = VFSTOULFS(dvp->v_mount)->um_lfs;
895 ASSERT_NO_SEGLOCK(fs);
896 if (fs->lfs_ronly) {
897 return EROFS;
898 }
899
900 /*
901 * Get a new vnode *before* adjusting the dirop count, to
902 * avoid a deadlock in getnewvnode(), if we have a stacked
903 * filesystem mounted on top of us.
904 *
905 * NB: this means we have to destroy the new vnode on error.
906 */
907
908 error = getnewvnode(VT_LFS, dvp->v_mount, lfs_vnodeop_p, NULL, vpp);
909 if (error) {
910 DLOG((DLOG_ALLOC, "lfs_create: dvp %p error %d\n", dvp,error));
911 return error;
912 }
913 error = lfs_set_dirop(dvp, NULL);
914 if (error) {
915 ungetnewvnode(*vpp);
916 *vpp = NULL;
917 return error;
918 }
919
920 fstrans_start(dvp->v_mount, FSTRANS_SHARED);
921 error = ulfs_makeinode(MAKEIMODE(vap->va_type, vap->va_mode),
922 dvp, ulr, vpp, ap->a_cnp);
923 if (error) {
924 fstrans_done(dvp->v_mount);
925 goto out;
926 }
927 fstrans_done(dvp->v_mount);
928 VN_KNOTE(dvp, NOTE_WRITE);
929 VOP_UNLOCK(*vpp);
930
931 out:
932
933 UNMARK_VNODE(dvp);
934 UNMARK_VNODE(*vpp);
935 if (!((*vpp)->v_uflag & VU_DIROP)) {
936 KASSERT(error != 0);
937 ungetnewvnode(*vpp);
938 *vpp = NULL;
939 }
940 else {
941 /*KASSERT(error == 0);*/
942 }
943 lfs_unset_dirop(fs, dvp, "create");
944
945 vrele(dvp);
946 return (error);
947 }
948
949 int
950 lfs_mkdir(void *v)
951 {
952 struct vop_mkdir_v3_args /* {
953 struct vnode *a_dvp;
954 struct vnode **a_vpp;
955 struct componentname *a_cnp;
956 struct vattr *a_vap;
957 } */ *ap = v;
958 struct lfs *fs;
959 struct vnode *dvp, *tvp, **vpp;
960 struct inode *dp, *ip;
961 struct componentname *cnp;
962 struct vattr *vap;
963 struct ulfs_lookup_results *ulr;
964 struct buf *bp;
965 struct lfs_dirtemplate dirtemplate;
966 struct lfs_direct *newdir;
967 int dirblksiz;
968 int dmode;
969 int error;
970
971 dvp = ap->a_dvp;
972 tvp = NULL;
973 vpp = ap->a_vpp;
974 cnp = ap->a_cnp;
975 vap = ap->a_vap;
976
977 dp = VTOI(dvp);
978 ip = NULL;
979
980 KASSERT(vpp != NULL);
981 KASSERT(*vpp == NULL);
982
983 /* XXX should handle this material another way */
984 ulr = &dp->i_crap;
985 ULFS_CHECK_CRAPCOUNTER(dp);
986
987 fs = VFSTOULFS(dvp->v_mount)->um_lfs;
988 ASSERT_NO_SEGLOCK(fs);
989 if (fs->lfs_ronly) {
990 return EROFS;
991 }
992 dirblksiz = fs->um_dirblksiz;
993
994 /*
995 * Get a new vnode *before* adjusting the dirop count, to
996 * avoid a deadlock in getnewvnode(), if we have a stacked
997 * filesystem mounted on top of us.
998 *
999 * NB: this means we have to destroy the new vnode on error.
1000 */
1001
1002 error = getnewvnode(VT_LFS, dvp->v_mount, lfs_vnodeop_p, NULL, vpp);
1003 if (error) {
1004 DLOG((DLOG_ALLOC, "lfs_mkdir: dvp %p error %d\n", dvp, error));
1005 return error;
1006 }
1007 error = lfs_set_dirop(dvp, NULL);
1008 if (error) {
1009 ungetnewvnode(*vpp);
1010 *vpp = NULL;
1011 return error;
1012 }
1013
1014 fstrans_start(dvp->v_mount, FSTRANS_SHARED);
1015
1016 if ((nlink_t)dp->i_nlink >= LINK_MAX) {
1017 error = EMLINK;
1018 goto out;
1019 }
1020
1021 dmode = vap->va_mode & ACCESSPERMS;
1022 dmode |= LFS_IFDIR;
1023 /*
1024 * Must simulate part of ulfs_makeinode here to acquire the inode,
1025 * but not have it entered in the parent directory. The entry is
1026 * made later after writing "." and ".." entries.
1027 */
1028 if ((error = lfs_valloc(dvp, dmode, cnp->cn_cred, vpp)) != 0)
1029 goto out;
1030
1031 tvp = *vpp;
1032 ip = VTOI(tvp);
1033
1034 ip->i_uid = kauth_cred_geteuid(cnp->cn_cred);
1035 DIP_ASSIGN(ip, uid, ip->i_uid);
1036 ip->i_gid = dp->i_gid;
1037 DIP_ASSIGN(ip, gid, ip->i_gid);
1038 #if defined(LFS_QUOTA) || defined(LFS_QUOTA2)
1039 if ((error = lfs_chkiq(ip, 1, cnp->cn_cred, 0))) {
1040 lfs_vfree(tvp, ip->i_number, dmode);
1041 fstrans_done(dvp->v_mount);
1042 vput(tvp);
1043 goto out2;
1044 }
1045 #endif
1046 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
1047 ip->i_mode = dmode;
1048 DIP_ASSIGN(ip, mode, dmode);
1049 tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */
1050 ip->i_nlink = 2;
1051 DIP_ASSIGN(ip, nlink, 2);
1052 if (cnp->cn_flags & ISWHITEOUT) {
1053 ip->i_flags |= UF_OPAQUE;
1054 DIP_ASSIGN(ip, flags, ip->i_flags);
1055 }
1056
1057 /*
1058 * Bump link count in parent directory to reflect work done below.
1059 */
1060 dp->i_nlink++;
1061 DIP_ASSIGN(dp, nlink, dp->i_nlink);
1062 dp->i_flag |= IN_CHANGE;
1063 if ((error = lfs_update(dvp, NULL, NULL, UPDATE_DIROP)) != 0)
1064 goto bad;
1065
1066 /*
1067 * Initialize directory with "." and ".." from static template.
1068 */
1069 dirtemplate = mastertemplate;
1070 dirtemplate.dotdot_reclen = dirblksiz - dirtemplate.dot_reclen;
1071 dirtemplate.dot_ino = ulfs_rw32(ip->i_number, ULFS_MPNEEDSWAP(fs));
1072 dirtemplate.dotdot_ino = ulfs_rw32(dp->i_number, ULFS_MPNEEDSWAP(fs));
1073 dirtemplate.dot_reclen = ulfs_rw16(dirtemplate.dot_reclen,
1074 ULFS_MPNEEDSWAP(fs));
1075 dirtemplate.dotdot_reclen = ulfs_rw16(dirtemplate.dotdot_reclen,
1076 ULFS_MPNEEDSWAP(fs));
1077 if (fs->um_maxsymlinklen <= 0) {
1078 #if BYTE_ORDER == LITTLE_ENDIAN
1079 if (ULFS_MPNEEDSWAP(fs) == 0)
1080 #else
1081 if (ULFS_MPNEEDSWAP(fs) != 0)
1082 #endif
1083 {
1084 dirtemplate.dot_type = dirtemplate.dot_namlen;
1085 dirtemplate.dotdot_type = dirtemplate.dotdot_namlen;
1086 dirtemplate.dot_namlen = dirtemplate.dotdot_namlen = 0;
1087 } else
1088 dirtemplate.dot_type = dirtemplate.dotdot_type = 0;
1089 }
1090 if ((error = lfs_balloc(tvp, (off_t)0, dirblksiz, cnp->cn_cred,
1091 B_CLRBUF, &bp)) != 0)
1092 goto bad;
1093 ip->i_size = dirblksiz;
1094 DIP_ASSIGN(ip, size, dirblksiz);
1095 ip->i_flag |= IN_ACCESS | IN_CHANGE | IN_UPDATE;
1096 uvm_vnp_setsize(tvp, ip->i_size);
1097 memcpy((void *)bp->b_data, (void *)&dirtemplate, sizeof dirtemplate);
1098
1099 /*
1100 * Directory set up; now install its entry in the parent directory.
1101 */
1102 if ((error = VOP_BWRITE(bp->b_vp, bp)) != 0)
1103 goto bad;
1104 if ((error = lfs_update(tvp, NULL, NULL, UPDATE_DIROP)) != 0) {
1105 goto bad;
1106 }
1107 newdir = pool_cache_get(ulfs_direct_cache, PR_WAITOK);
1108 ulfs_makedirentry(ip, cnp, newdir);
1109 error = ulfs_direnter(dvp, ulr, tvp, newdir, cnp, bp);
1110 pool_cache_put(ulfs_direct_cache, newdir);
1111 bad:
1112 if (error == 0) {
1113 VN_KNOTE(dvp, NOTE_WRITE | NOTE_LINK);
1114 VOP_UNLOCK(tvp);
1115 } else {
1116 dp->i_nlink--;
1117 DIP_ASSIGN(dp, nlink, dp->i_nlink);
1118 dp->i_flag |= IN_CHANGE;
1119 /*
1120 * No need to do an explicit lfs_truncate here, vrele will
1121 * do this for us because we set the link count to 0.
1122 */
1123 ip->i_nlink = 0;
1124 DIP_ASSIGN(ip, nlink, 0);
1125 ip->i_flag |= IN_CHANGE;
1126 /* If IN_ADIROP, account for it */
1127 lfs_unmark_vnode(tvp);
1128 vput(tvp);
1129 }
1130
1131 out:
1132 fstrans_done(dvp->v_mount);
1133 #if defined(LFS_QUOTA) || defined(LFS_QUOTA2)
1134 out2:
1135 #endif
1136
1137 UNMARK_VNODE(dvp);
1138 UNMARK_VNODE(*vpp);
1139 if (!((*vpp)->v_uflag & VU_DIROP)) {
1140 KASSERT(error != 0);
1141 ungetnewvnode(*vpp);
1142 *vpp = NULL;
1143 }
1144 else {
1145 /*KASSERT(error == 0);*/
1146 }
1147 lfs_unset_dirop(fs, dvp, "mkdir");
1148
1149 vrele(dvp);
1150 return (error);
1151 }
1152
1153 int
1154 lfs_remove(void *v)
1155 {
1156 struct vop_remove_args /* {
1157 struct vnode *a_dvp;
1158 struct vnode *a_vp;
1159 struct componentname *a_cnp;
1160 } */ *ap = v;
1161 struct vnode *dvp, *vp;
1162 struct inode *ip;
1163 int error;
1164
1165 dvp = ap->a_dvp;
1166 vp = ap->a_vp;
1167 ip = VTOI(vp);
1168 if ((error = lfs_set_dirop(dvp, vp)) != 0) {
1169 if (dvp == vp)
1170 vrele(vp);
1171 else
1172 vput(vp);
1173 vput(dvp);
1174 return error;
1175 }
1176 error = ulfs_remove(ap);
1177 if (ip->i_nlink == 0)
1178 lfs_orphan(ip->i_lfs, ip->i_number);
1179
1180 UNMARK_VNODE(dvp);
1181 if (ap->a_vp) {
1182 UNMARK_VNODE(ap->a_vp);
1183 }
1184 lfs_unset_dirop(ip->i_lfs, dvp, "remove");
1185 vrele(dvp);
1186 if (ap->a_vp) {
1187 vrele(ap->a_vp);
1188 }
1189
1190 return (error);
1191 }
1192
1193 int
1194 lfs_rmdir(void *v)
1195 {
1196 struct vop_rmdir_args /* {
1197 struct vnodeop_desc *a_desc;
1198 struct vnode *a_dvp;
1199 struct vnode *a_vp;
1200 struct componentname *a_cnp;
1201 } */ *ap = v;
1202 struct vnode *vp;
1203 struct inode *ip;
1204 int error;
1205
1206 vp = ap->a_vp;
1207 ip = VTOI(vp);
1208 if ((error = lfs_set_dirop(ap->a_dvp, ap->a_vp)) != 0) {
1209 if (ap->a_dvp == vp)
1210 vrele(ap->a_dvp);
1211 else
1212 vput(ap->a_dvp);
1213 vput(vp);
1214 return error;
1215 }
1216 error = ulfs_rmdir(ap);
1217 if (ip->i_nlink == 0)
1218 lfs_orphan(ip->i_lfs, ip->i_number);
1219
1220 UNMARK_VNODE(ap->a_dvp);
1221 if (ap->a_vp) {
1222 UNMARK_VNODE(ap->a_vp);
1223 }
1224 lfs_unset_dirop(ip->i_lfs, ap->a_dvp, "rmdir");
1225 vrele(ap->a_dvp);
1226 if (ap->a_vp) {
1227 vrele(ap->a_vp);
1228 }
1229
1230 return (error);
1231 }
1232
1233 int
1234 lfs_link(void *v)
1235 {
1236 struct vop_link_args /* {
1237 struct vnode *a_dvp;
1238 struct vnode *a_vp;
1239 struct componentname *a_cnp;
1240 } */ *ap = v;
1241 struct lfs *fs;
1242 struct vnode *dvp;
1243 int error;
1244
1245 dvp = ap->a_dvp;
1246
1247 fs = VFSTOULFS(dvp->v_mount)->um_lfs;
1248 ASSERT_NO_SEGLOCK(fs);
1249 if (fs->lfs_ronly) {
1250 return EROFS;
1251 }
1252
1253 error = lfs_set_dirop(dvp, NULL);
1254 if (error) {
1255 /*
1256 * XXX dholland 20140515 this was here before but must
1257 * be wrong.
1258 */
1259 vput(dvp);
1260
1261 return error;
1262 }
1263
1264 error = ulfs_link(ap);
1265
1266 UNMARK_VNODE(dvp);
1267 lfs_unset_dirop(fs, dvp, "link");
1268 vrele(dvp);
1269
1270 return (error);
1271 }
1272
1273 /* XXX hack to avoid calling ITIMES in getattr */
1274 int
1275 lfs_getattr(void *v)
1276 {
1277 struct vop_getattr_args /* {
1278 struct vnode *a_vp;
1279 struct vattr *a_vap;
1280 kauth_cred_t a_cred;
1281 } */ *ap = v;
1282 struct vnode *vp = ap->a_vp;
1283 struct inode *ip = VTOI(vp);
1284 struct vattr *vap = ap->a_vap;
1285 struct lfs *fs = ip->i_lfs;
1286
1287 fstrans_start(vp->v_mount, FSTRANS_SHARED);
1288 /*
1289 * Copy from inode table
1290 */
1291 vap->va_fsid = ip->i_dev;
1292 vap->va_fileid = ip->i_number;
1293 vap->va_mode = ip->i_mode & ~LFS_IFMT;
1294 vap->va_nlink = ip->i_nlink;
1295 vap->va_uid = ip->i_uid;
1296 vap->va_gid = ip->i_gid;
1297 vap->va_rdev = (dev_t)ip->i_ffs1_rdev;
1298 vap->va_size = vp->v_size;
1299 vap->va_atime.tv_sec = ip->i_ffs1_atime;
1300 vap->va_atime.tv_nsec = ip->i_ffs1_atimensec;
1301 vap->va_mtime.tv_sec = ip->i_ffs1_mtime;
1302 vap->va_mtime.tv_nsec = ip->i_ffs1_mtimensec;
1303 vap->va_ctime.tv_sec = ip->i_ffs1_ctime;
1304 vap->va_ctime.tv_nsec = ip->i_ffs1_ctimensec;
1305 vap->va_flags = ip->i_flags;
1306 vap->va_gen = ip->i_gen;
1307 /* this doesn't belong here */
1308 if (vp->v_type == VBLK)
1309 vap->va_blocksize = BLKDEV_IOSIZE;
1310 else if (vp->v_type == VCHR)
1311 vap->va_blocksize = MAXBSIZE;
1312 else
1313 vap->va_blocksize = vp->v_mount->mnt_stat.f_iosize;
1314 vap->va_bytes = lfs_fsbtob(fs, (u_quad_t)ip->i_lfs_effnblks);
1315 vap->va_type = vp->v_type;
1316 vap->va_filerev = ip->i_modrev;
1317 fstrans_done(vp->v_mount);
1318 return (0);
1319 }
1320
1321 /*
1322 * Check to make sure the inode blocks won't choke the buffer
1323 * cache, then call ulfs_setattr as usual.
1324 */
1325 int
1326 lfs_setattr(void *v)
1327 {
1328 struct vop_setattr_args /* {
1329 struct vnode *a_vp;
1330 struct vattr *a_vap;
1331 kauth_cred_t a_cred;
1332 } */ *ap = v;
1333 struct vnode *vp = ap->a_vp;
1334
1335 lfs_check(vp, LFS_UNUSED_LBN, 0);
1336 return ulfs_setattr(v);
1337 }
1338
1339 /*
1340 * Release the block we hold on lfs_newseg wrapping. Called on file close,
1341 * or explicitly from LFCNWRAPGO. Called with the interlock held.
1342 */
1343 static int
1344 lfs_wrapgo(struct lfs *fs, struct inode *ip, int waitfor)
1345 {
1346 if (fs->lfs_stoplwp != curlwp)
1347 return EBUSY;
1348
1349 fs->lfs_stoplwp = NULL;
1350 cv_signal(&fs->lfs_stopcv);
1351
1352 KASSERT(fs->lfs_nowrap > 0);
1353 if (fs->lfs_nowrap <= 0) {
1354 return 0;
1355 }
1356
1357 if (--fs->lfs_nowrap == 0) {
1358 log(LOG_NOTICE, "%s: re-enabled log wrap\n", fs->lfs_fsmnt);
1359 wakeup(&fs->lfs_wrappass);
1360 lfs_wakeup_cleaner(fs);
1361 }
1362 if (waitfor) {
1363 mtsleep(&fs->lfs_nextseg, PCATCH | PUSER, "segment",
1364 0, &lfs_lock);
1365 }
1366
1367 return 0;
1368 }
1369
1370 /*
1371 * Close called.
1372 *
1373 * Update the times on the inode.
1374 */
1375 /* ARGSUSED */
1376 int
1377 lfs_close(void *v)
1378 {
1379 struct vop_close_args /* {
1380 struct vnode *a_vp;
1381 int a_fflag;
1382 kauth_cred_t a_cred;
1383 } */ *ap = v;
1384 struct vnode *vp = ap->a_vp;
1385 struct inode *ip = VTOI(vp);
1386 struct lfs *fs = ip->i_lfs;
1387
1388 if ((ip->i_number == ULFS_ROOTINO || ip->i_number == LFS_IFILE_INUM) &&
1389 fs->lfs_stoplwp == curlwp) {
1390 mutex_enter(&lfs_lock);
1391 log(LOG_NOTICE, "lfs_close: releasing log wrap control\n");
1392 lfs_wrapgo(fs, ip, 0);
1393 mutex_exit(&lfs_lock);
1394 }
1395
1396 if (vp == ip->i_lfs->lfs_ivnode &&
1397 vp->v_mount->mnt_iflag & IMNT_UNMOUNT)
1398 return 0;
1399
1400 fstrans_start(vp->v_mount, FSTRANS_SHARED);
1401 if (vp->v_usecount > 1 && vp != ip->i_lfs->lfs_ivnode) {
1402 LFS_ITIMES(ip, NULL, NULL, NULL);
1403 }
1404 fstrans_done(vp->v_mount);
1405 return (0);
1406 }
1407
1408 /*
1409 * Close wrapper for special devices.
1410 *
1411 * Update the times on the inode then do device close.
1412 */
1413 int
1414 lfsspec_close(void *v)
1415 {
1416 struct vop_close_args /* {
1417 struct vnode *a_vp;
1418 int a_fflag;
1419 kauth_cred_t a_cred;
1420 } */ *ap = v;
1421 struct vnode *vp;
1422 struct inode *ip;
1423
1424 vp = ap->a_vp;
1425 ip = VTOI(vp);
1426 if (vp->v_usecount > 1) {
1427 LFS_ITIMES(ip, NULL, NULL, NULL);
1428 }
1429 return (VOCALL (spec_vnodeop_p, VOFFSET(vop_close), ap));
1430 }
1431
1432 /*
1433 * Close wrapper for fifo's.
1434 *
1435 * Update the times on the inode then do device close.
1436 */
1437 int
1438 lfsfifo_close(void *v)
1439 {
1440 struct vop_close_args /* {
1441 struct vnode *a_vp;
1442 int a_fflag;
1443 kauth_cred_ a_cred;
1444 } */ *ap = v;
1445 struct vnode *vp;
1446 struct inode *ip;
1447
1448 vp = ap->a_vp;
1449 ip = VTOI(vp);
1450 if (ap->a_vp->v_usecount > 1) {
1451 LFS_ITIMES(ip, NULL, NULL, NULL);
1452 }
1453 return (VOCALL (fifo_vnodeop_p, VOFFSET(vop_close), ap));
1454 }
1455
1456 /*
1457 * Reclaim an inode so that it can be used for other purposes.
1458 */
1459
1460 int
1461 lfs_reclaim(void *v)
1462 {
1463 struct vop_reclaim_args /* {
1464 struct vnode *a_vp;
1465 } */ *ap = v;
1466 struct vnode *vp = ap->a_vp;
1467 struct inode *ip = VTOI(vp);
1468 struct lfs *fs = ip->i_lfs;
1469 int error;
1470
1471 /*
1472 * The inode must be freed and updated before being removed
1473 * from its hash chain. Other threads trying to gain a hold
1474 * or lock on the inode will be stalled.
1475 */
1476 if (ip->i_nlink <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0)
1477 lfs_vfree(vp, ip->i_number, ip->i_omode);
1478
1479 mutex_enter(&lfs_lock);
1480 LFS_CLR_UINO(ip, IN_ALLMOD);
1481 mutex_exit(&lfs_lock);
1482 if ((error = ulfs_reclaim(vp)))
1483 return (error);
1484
1485 /*
1486 * Take us off the paging and/or dirop queues if we were on them.
1487 * We shouldn't be on them.
1488 */
1489 mutex_enter(&lfs_lock);
1490 if (ip->i_flags & IN_PAGING) {
1491 log(LOG_WARNING, "%s: reclaimed vnode is IN_PAGING\n",
1492 fs->lfs_fsmnt);
1493 ip->i_flags &= ~IN_PAGING;
1494 TAILQ_REMOVE(&fs->lfs_pchainhd, ip, i_lfs_pchain);
1495 }
1496 if (vp->v_uflag & VU_DIROP) {
1497 panic("reclaimed vnode is VU_DIROP");
1498 vp->v_uflag &= ~VU_DIROP;
1499 TAILQ_REMOVE(&fs->lfs_dchainhd, ip, i_lfs_dchain);
1500 }
1501 mutex_exit(&lfs_lock);
1502
1503 pool_put(&lfs_dinode_pool, ip->i_din.ffs1_din);
1504 lfs_deregister_all(vp);
1505 pool_put(&lfs_inoext_pool, ip->inode_ext.lfs);
1506 ip->inode_ext.lfs = NULL;
1507 genfs_node_destroy(vp);
1508 pool_put(&lfs_inode_pool, vp->v_data);
1509 vp->v_data = NULL;
1510 return (0);
1511 }
1512
1513 /*
1514 * Read a block from a storage device.
1515 *
1516 * Calculate the logical to physical mapping if not done already,
1517 * then call the device strategy routine.
1518 *
1519 * In order to avoid reading blocks that are in the process of being
1520 * written by the cleaner---and hence are not mutexed by the normal
1521 * buffer cache / page cache mechanisms---check for collisions before
1522 * reading.
1523 *
1524 * We inline ulfs_strategy to make sure that the VOP_BMAP occurs *before*
1525 * the active cleaner test.
1526 *
1527 * XXX This code assumes that lfs_markv makes synchronous checkpoints.
1528 */
1529 int
1530 lfs_strategy(void *v)
1531 {
1532 struct vop_strategy_args /* {
1533 struct vnode *a_vp;
1534 struct buf *a_bp;
1535 } */ *ap = v;
1536 struct buf *bp;
1537 struct lfs *fs;
1538 struct vnode *vp;
1539 struct inode *ip;
1540 daddr_t tbn;
1541 #define MAXLOOP 25
1542 int i, sn, error, slept, loopcount;
1543
1544 bp = ap->a_bp;
1545 vp = ap->a_vp;
1546 ip = VTOI(vp);
1547 fs = ip->i_lfs;
1548
1549 /* lfs uses its strategy routine only for read */
1550 KASSERT(bp->b_flags & B_READ);
1551
1552 if (vp->v_type == VBLK || vp->v_type == VCHR)
1553 panic("lfs_strategy: spec");
1554 KASSERT(bp->b_bcount != 0);
1555 if (bp->b_blkno == bp->b_lblkno) {
1556 error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno,
1557 NULL);
1558 if (error) {
1559 bp->b_error = error;
1560 bp->b_resid = bp->b_bcount;
1561 biodone(bp);
1562 return (error);
1563 }
1564 if ((long)bp->b_blkno == -1) /* no valid data */
1565 clrbuf(bp);
1566 }
1567 if ((long)bp->b_blkno < 0) { /* block is not on disk */
1568 bp->b_resid = bp->b_bcount;
1569 biodone(bp);
1570 return (0);
1571 }
1572
1573 slept = 1;
1574 loopcount = 0;
1575 mutex_enter(&lfs_lock);
1576 while (slept && fs->lfs_seglock) {
1577 mutex_exit(&lfs_lock);
1578 /*
1579 * Look through list of intervals.
1580 * There will only be intervals to look through
1581 * if the cleaner holds the seglock.
1582 * Since the cleaner is synchronous, we can trust
1583 * the list of intervals to be current.
1584 */
1585 tbn = LFS_DBTOFSB(fs, bp->b_blkno);
1586 sn = lfs_dtosn(fs, tbn);
1587 slept = 0;
1588 for (i = 0; i < fs->lfs_cleanind; i++) {
1589 if (sn == lfs_dtosn(fs, fs->lfs_cleanint[i]) &&
1590 tbn >= fs->lfs_cleanint[i]) {
1591 DLOG((DLOG_CLEAN,
1592 "lfs_strategy: ino %d lbn %" PRId64
1593 " ind %d sn %d fsb %" PRIx32
1594 " given sn %d fsb %" PRIx64 "\n",
1595 ip->i_number, bp->b_lblkno, i,
1596 lfs_dtosn(fs, fs->lfs_cleanint[i]),
1597 fs->lfs_cleanint[i], sn, tbn));
1598 DLOG((DLOG_CLEAN,
1599 "lfs_strategy: sleeping on ino %d lbn %"
1600 PRId64 "\n", ip->i_number, bp->b_lblkno));
1601 mutex_enter(&lfs_lock);
1602 if (LFS_SEGLOCK_HELD(fs) && fs->lfs_iocount) {
1603 /*
1604 * Cleaner can't wait for itself.
1605 * Instead, wait for the blocks
1606 * to be written to disk.
1607 * XXX we need pribio in the test
1608 * XXX here.
1609 */
1610 mtsleep(&fs->lfs_iocount,
1611 (PRIBIO + 1) | PNORELOCK,
1612 "clean2", hz/10 + 1,
1613 &lfs_lock);
1614 slept = 1;
1615 ++loopcount;
1616 break;
1617 } else if (fs->lfs_seglock) {
1618 mtsleep(&fs->lfs_seglock,
1619 (PRIBIO + 1) | PNORELOCK,
1620 "clean1", 0,
1621 &lfs_lock);
1622 slept = 1;
1623 break;
1624 }
1625 mutex_exit(&lfs_lock);
1626 }
1627 }
1628 mutex_enter(&lfs_lock);
1629 if (loopcount > MAXLOOP) {
1630 printf("lfs_strategy: breaking out of clean2 loop\n");
1631 break;
1632 }
1633 }
1634 mutex_exit(&lfs_lock);
1635
1636 vp = ip->i_devvp;
1637 return VOP_STRATEGY(vp, bp);
1638 }
1639
1640 /*
1641 * Inline lfs_segwrite/lfs_writevnodes, but just for dirops.
1642 * Technically this is a checkpoint (the on-disk state is valid)
1643 * even though we are leaving out all the file data.
1644 */
1645 int
1646 lfs_flush_dirops(struct lfs *fs)
1647 {
1648 struct inode *ip, *nip;
1649 struct vnode *vp;
1650 extern int lfs_dostats;
1651 struct segment *sp;
1652 int flags = 0;
1653 int error = 0;
1654
1655 ASSERT_MAYBE_SEGLOCK(fs);
1656 KASSERT(fs->lfs_nadirop == 0);
1657
1658 if (fs->lfs_ronly)
1659 return EROFS;
1660
1661 mutex_enter(&lfs_lock);
1662 if (TAILQ_FIRST(&fs->lfs_dchainhd) == NULL) {
1663 mutex_exit(&lfs_lock);
1664 return 0;
1665 } else
1666 mutex_exit(&lfs_lock);
1667
1668 if (lfs_dostats)
1669 ++lfs_stats.flush_invoked;
1670
1671 lfs_imtime(fs);
1672 lfs_seglock(fs, flags);
1673 sp = fs->lfs_sp;
1674
1675 /*
1676 * lfs_writevnodes, optimized to get dirops out of the way.
1677 * Only write dirops, and don't flush files' pages, only
1678 * blocks from the directories.
1679 *
1680 * We don't need to vref these files because they are
1681 * dirops and so hold an extra reference until the
1682 * segunlock clears them of that status.
1683 *
1684 * We don't need to check for IN_ADIROP because we know that
1685 * no dirops are active.
1686 *
1687 */
1688 mutex_enter(&lfs_lock);
1689 for (ip = TAILQ_FIRST(&fs->lfs_dchainhd); ip != NULL; ip = nip) {
1690 nip = TAILQ_NEXT(ip, i_lfs_dchain);
1691 mutex_exit(&lfs_lock);
1692 vp = ITOV(ip);
1693 mutex_enter(vp->v_interlock);
1694
1695 KASSERT((ip->i_flag & IN_ADIROP) == 0);
1696 KASSERT(vp->v_uflag & VU_DIROP);
1697 KASSERT(vdead_check(vp, VDEAD_NOWAIT) == 0);
1698
1699 /*
1700 * All writes to directories come from dirops; all
1701 * writes to files' direct blocks go through the page
1702 * cache, which we're not touching. Reads to files
1703 * and/or directories will not be affected by writing
1704 * directory blocks inodes and file inodes. So we don't
1705 * really need to lock.
1706 */
1707 if (vdead_check(vp, VDEAD_NOWAIT) != 0) {
1708 mutex_exit(vp->v_interlock);
1709 mutex_enter(&lfs_lock);
1710 continue;
1711 }
1712 mutex_exit(vp->v_interlock);
1713 /* XXX see below
1714 * waslocked = VOP_ISLOCKED(vp);
1715 */
1716 if (vp->v_type != VREG &&
1717 ((ip->i_flag & IN_ALLMOD) || !VPISEMPTY(vp))) {
1718 error = lfs_writefile(fs, sp, vp);
1719 if (!VPISEMPTY(vp) && !WRITEINPROG(vp) &&
1720 !(ip->i_flag & IN_ALLMOD)) {
1721 mutex_enter(&lfs_lock);
1722 LFS_SET_UINO(ip, IN_MODIFIED);
1723 mutex_exit(&lfs_lock);
1724 }
1725 if (error && (sp->seg_flags & SEGM_SINGLE)) {
1726 mutex_enter(&lfs_lock);
1727 error = EAGAIN;
1728 break;
1729 }
1730 }
1731 KDASSERT(ip->i_number != LFS_IFILE_INUM);
1732 error = lfs_writeinode(fs, sp, ip);
1733 mutex_enter(&lfs_lock);
1734 if (error && (sp->seg_flags & SEGM_SINGLE)) {
1735 error = EAGAIN;
1736 break;
1737 }
1738
1739 /*
1740 * We might need to update these inodes again,
1741 * for example, if they have data blocks to write.
1742 * Make sure that after this flush, they are still
1743 * marked IN_MODIFIED so that we don't forget to
1744 * write them.
1745 */
1746 /* XXX only for non-directories? --KS */
1747 LFS_SET_UINO(ip, IN_MODIFIED);
1748 }
1749 mutex_exit(&lfs_lock);
1750 /* We've written all the dirops there are */
1751 ((SEGSUM *)(sp->segsum))->ss_flags &= ~(SS_CONT);
1752 lfs_finalize_fs_seguse(fs);
1753 (void) lfs_writeseg(fs, sp);
1754 lfs_segunlock(fs);
1755
1756 return error;
1757 }
1758
1759 /*
1760 * Flush all vnodes for which the pagedaemon has requested pageouts.
1761 * Skip over any files that are marked VU_DIROP (since lfs_flush_dirop()
1762 * has just run, this would be an error). If we have to skip a vnode
1763 * for any reason, just skip it; if we have to wait for the cleaner,
1764 * abort. The writer daemon will call us again later.
1765 */
1766 int
1767 lfs_flush_pchain(struct lfs *fs)
1768 {
1769 struct inode *ip, *nip;
1770 struct vnode *vp;
1771 extern int lfs_dostats;
1772 struct segment *sp;
1773 int error, error2;
1774
1775 ASSERT_NO_SEGLOCK(fs);
1776
1777 if (fs->lfs_ronly)
1778 return EROFS;
1779
1780 mutex_enter(&lfs_lock);
1781 if (TAILQ_FIRST(&fs->lfs_pchainhd) == NULL) {
1782 mutex_exit(&lfs_lock);
1783 return 0;
1784 } else
1785 mutex_exit(&lfs_lock);
1786
1787 /* Get dirops out of the way */
1788 if ((error = lfs_flush_dirops(fs)) != 0)
1789 return error;
1790
1791 if (lfs_dostats)
1792 ++lfs_stats.flush_invoked;
1793
1794 /*
1795 * Inline lfs_segwrite/lfs_writevnodes, but just for pageouts.
1796 */
1797 lfs_imtime(fs);
1798 lfs_seglock(fs, 0);
1799 sp = fs->lfs_sp;
1800
1801 /*
1802 * lfs_writevnodes, optimized to clear pageout requests.
1803 * Only write non-dirop files that are in the pageout queue.
1804 * We're very conservative about what we write; we want to be
1805 * fast and async.
1806 */
1807 mutex_enter(&lfs_lock);
1808 top:
1809 for (ip = TAILQ_FIRST(&fs->lfs_pchainhd); ip != NULL; ip = nip) {
1810 nip = TAILQ_NEXT(ip, i_lfs_pchain);
1811 vp = ITOV(ip);
1812
1813 if (!(ip->i_flags & IN_PAGING))
1814 goto top;
1815
1816 mutex_enter(vp->v_interlock);
1817 if (vdead_check(vp, VDEAD_NOWAIT) != 0 ||
1818 (vp->v_uflag & VU_DIROP) != 0) {
1819 mutex_exit(vp->v_interlock);
1820 continue;
1821 }
1822 if (vp->v_type != VREG) {
1823 mutex_exit(vp->v_interlock);
1824 continue;
1825 }
1826 if (lfs_vref(vp))
1827 continue;
1828 mutex_exit(&lfs_lock);
1829
1830 if (vn_lock(vp, LK_EXCLUSIVE | LK_NOWAIT | LK_RETRY) != 0) {
1831 lfs_vunref(vp);
1832 mutex_enter(&lfs_lock);
1833 continue;
1834 }
1835
1836 error = lfs_writefile(fs, sp, vp);
1837 if (!VPISEMPTY(vp) && !WRITEINPROG(vp) &&
1838 !(ip->i_flag & IN_ALLMOD)) {
1839 mutex_enter(&lfs_lock);
1840 LFS_SET_UINO(ip, IN_MODIFIED);
1841 mutex_exit(&lfs_lock);
1842 }
1843 KDASSERT(ip->i_number != LFS_IFILE_INUM);
1844 error2 = lfs_writeinode(fs, sp, ip);
1845
1846 VOP_UNLOCK(vp);
1847 lfs_vunref(vp);
1848
1849 if (error == EAGAIN || error2 == EAGAIN) {
1850 lfs_writeseg(fs, sp);
1851 mutex_enter(&lfs_lock);
1852 break;
1853 }
1854 mutex_enter(&lfs_lock);
1855 }
1856 mutex_exit(&lfs_lock);
1857 (void) lfs_writeseg(fs, sp);
1858 lfs_segunlock(fs);
1859
1860 return 0;
1861 }
1862
1863 /*
1864 * Provide a fcntl interface to sys_lfs_{segwait,bmapv,markv}.
1865 */
1866 int
1867 lfs_fcntl(void *v)
1868 {
1869 struct vop_fcntl_args /* {
1870 struct vnode *a_vp;
1871 u_int a_command;
1872 void * a_data;
1873 int a_fflag;
1874 kauth_cred_t a_cred;
1875 } */ *ap = v;
1876 struct timeval tv;
1877 struct timeval *tvp;
1878 BLOCK_INFO *blkiov;
1879 CLEANERINFO *cip;
1880 SEGUSE *sup;
1881 int blkcnt, error;
1882 size_t fh_size;
1883 struct lfs_fcntl_markv blkvp;
1884 struct lwp *l;
1885 fsid_t *fsidp;
1886 struct lfs *fs;
1887 struct buf *bp;
1888 fhandle_t *fhp;
1889 daddr_t off;
1890 int oclean;
1891
1892 /* Only respect LFS fcntls on fs root or Ifile */
1893 if (VTOI(ap->a_vp)->i_number != ULFS_ROOTINO &&
1894 VTOI(ap->a_vp)->i_number != LFS_IFILE_INUM) {
1895 return ulfs_fcntl(v);
1896 }
1897
1898 /* Avoid locking a draining lock */
1899 if (ap->a_vp->v_mount->mnt_iflag & IMNT_UNMOUNT) {
1900 return ESHUTDOWN;
1901 }
1902
1903 /* LFS control and monitoring fcntls are available only to root */
1904 l = curlwp;
1905 if (((ap->a_command & 0xff00) >> 8) == 'L' &&
1906 (error = kauth_authorize_system(l->l_cred, KAUTH_SYSTEM_LFS,
1907 KAUTH_REQ_SYSTEM_LFS_FCNTL, NULL, NULL, NULL)) != 0)
1908 return (error);
1909
1910 fs = VTOI(ap->a_vp)->i_lfs;
1911 fsidp = &ap->a_vp->v_mount->mnt_stat.f_fsidx;
1912
1913 error = 0;
1914 switch ((int)ap->a_command) {
1915 case LFCNSEGWAITALL_COMPAT_50:
1916 case LFCNSEGWAITALL_COMPAT:
1917 fsidp = NULL;
1918 /* FALLSTHROUGH */
1919 case LFCNSEGWAIT_COMPAT_50:
1920 case LFCNSEGWAIT_COMPAT:
1921 {
1922 struct timeval50 *tvp50
1923 = (struct timeval50 *)ap->a_data;
1924 timeval50_to_timeval(tvp50, &tv);
1925 tvp = &tv;
1926 }
1927 goto segwait_common;
1928 case LFCNSEGWAITALL:
1929 fsidp = NULL;
1930 /* FALLSTHROUGH */
1931 case LFCNSEGWAIT:
1932 tvp = (struct timeval *)ap->a_data;
1933 segwait_common:
1934 mutex_enter(&lfs_lock);
1935 ++fs->lfs_sleepers;
1936 mutex_exit(&lfs_lock);
1937
1938 error = lfs_segwait(fsidp, tvp);
1939
1940 mutex_enter(&lfs_lock);
1941 if (--fs->lfs_sleepers == 0)
1942 wakeup(&fs->lfs_sleepers);
1943 mutex_exit(&lfs_lock);
1944 return error;
1945
1946 case LFCNBMAPV:
1947 case LFCNMARKV:
1948 blkvp = *(struct lfs_fcntl_markv *)ap->a_data;
1949
1950 blkcnt = blkvp.blkcnt;
1951 if ((u_int) blkcnt > LFS_MARKV_MAXBLKCNT)
1952 return (EINVAL);
1953 blkiov = lfs_malloc(fs, blkcnt * sizeof(BLOCK_INFO), LFS_NB_BLKIOV);
1954 if ((error = copyin(blkvp.blkiov, blkiov,
1955 blkcnt * sizeof(BLOCK_INFO))) != 0) {
1956 lfs_free(fs, blkiov, LFS_NB_BLKIOV);
1957 return error;
1958 }
1959
1960 mutex_enter(&lfs_lock);
1961 ++fs->lfs_sleepers;
1962 mutex_exit(&lfs_lock);
1963 if (ap->a_command == LFCNBMAPV)
1964 error = lfs_bmapv(l->l_proc, fsidp, blkiov, blkcnt);
1965 else /* LFCNMARKV */
1966 error = lfs_markv(l->l_proc, fsidp, blkiov, blkcnt);
1967 if (error == 0)
1968 error = copyout(blkiov, blkvp.blkiov,
1969 blkcnt * sizeof(BLOCK_INFO));
1970 mutex_enter(&lfs_lock);
1971 if (--fs->lfs_sleepers == 0)
1972 wakeup(&fs->lfs_sleepers);
1973 mutex_exit(&lfs_lock);
1974 lfs_free(fs, blkiov, LFS_NB_BLKIOV);
1975 return error;
1976
1977 case LFCNRECLAIM:
1978 /*
1979 * Flush dirops and write Ifile, allowing empty segments
1980 * to be immediately reclaimed.
1981 */
1982 lfs_writer_enter(fs, "pndirop");
1983 off = fs->lfs_offset;
1984 lfs_seglock(fs, SEGM_FORCE_CKP | SEGM_CKP);
1985 lfs_flush_dirops(fs);
1986 LFS_CLEANERINFO(cip, fs, bp);
1987 oclean = cip->clean;
1988 LFS_SYNC_CLEANERINFO(cip, fs, bp, 1);
1989 lfs_segwrite(ap->a_vp->v_mount, SEGM_FORCE_CKP);
1990 fs->lfs_sp->seg_flags |= SEGM_PROT;
1991 lfs_segunlock(fs);
1992 lfs_writer_leave(fs);
1993
1994 #ifdef DEBUG
1995 LFS_CLEANERINFO(cip, fs, bp);
1996 DLOG((DLOG_CLEAN, "lfs_fcntl: reclaim wrote %" PRId64
1997 " blocks, cleaned %" PRId32 " segments (activesb %d)\n",
1998 fs->lfs_offset - off, cip->clean - oclean,
1999 fs->lfs_activesb));
2000 LFS_SYNC_CLEANERINFO(cip, fs, bp, 0);
2001 #else
2002 __USE(oclean);
2003 __USE(off);
2004 #endif
2005
2006 return 0;
2007
2008 case LFCNIFILEFH_COMPAT:
2009 /* Return the filehandle of the Ifile */
2010 if ((error = kauth_authorize_system(l->l_cred,
2011 KAUTH_SYSTEM_FILEHANDLE, 0, NULL, NULL, NULL)) != 0)
2012 return (error);
2013 fhp = (struct fhandle *)ap->a_data;
2014 fhp->fh_fsid = *fsidp;
2015 fh_size = 16; /* former VFS_MAXFIDSIZ */
2016 return lfs_vptofh(fs->lfs_ivnode, &(fhp->fh_fid), &fh_size);
2017
2018 case LFCNIFILEFH_COMPAT2:
2019 case LFCNIFILEFH:
2020 /* Return the filehandle of the Ifile */
2021 fhp = (struct fhandle *)ap->a_data;
2022 fhp->fh_fsid = *fsidp;
2023 fh_size = sizeof(struct lfs_fhandle) -
2024 offsetof(fhandle_t, fh_fid);
2025 return lfs_vptofh(fs->lfs_ivnode, &(fhp->fh_fid), &fh_size);
2026
2027 case LFCNREWIND:
2028 /* Move lfs_offset to the lowest-numbered segment */
2029 return lfs_rewind(fs, *(int *)ap->a_data);
2030
2031 case LFCNINVAL:
2032 /* Mark a segment SEGUSE_INVAL */
2033 LFS_SEGENTRY(sup, fs, *(int *)ap->a_data, bp);
2034 if (sup->su_nbytes > 0) {
2035 brelse(bp, 0);
2036 lfs_unset_inval_all(fs);
2037 return EBUSY;
2038 }
2039 sup->su_flags |= SEGUSE_INVAL;
2040 VOP_BWRITE(bp->b_vp, bp);
2041 return 0;
2042
2043 case LFCNRESIZE:
2044 /* Resize the filesystem */
2045 return lfs_resize_fs(fs, *(int *)ap->a_data);
2046
2047 case LFCNWRAPSTOP:
2048 case LFCNWRAPSTOP_COMPAT:
2049 /*
2050 * Hold lfs_newseg at segment 0; if requested, sleep until
2051 * the filesystem wraps around. To support external agents
2052 * (dump, fsck-based regression test) that need to look at
2053 * a snapshot of the filesystem, without necessarily
2054 * requiring that all fs activity stops.
2055 */
2056 if (fs->lfs_stoplwp == curlwp)
2057 return EALREADY;
2058
2059 mutex_enter(&lfs_lock);
2060 while (fs->lfs_stoplwp != NULL)
2061 cv_wait(&fs->lfs_stopcv, &lfs_lock);
2062 fs->lfs_stoplwp = curlwp;
2063 if (fs->lfs_nowrap == 0)
2064 log(LOG_NOTICE, "%s: disabled log wrap\n", fs->lfs_fsmnt);
2065 ++fs->lfs_nowrap;
2066 if (*(int *)ap->a_data == 1
2067 || ap->a_command == LFCNWRAPSTOP_COMPAT) {
2068 log(LOG_NOTICE, "LFCNSTOPWRAP waiting for log wrap\n");
2069 error = mtsleep(&fs->lfs_nowrap, PCATCH | PUSER,
2070 "segwrap", 0, &lfs_lock);
2071 log(LOG_NOTICE, "LFCNSTOPWRAP done waiting\n");
2072 if (error) {
2073 lfs_wrapgo(fs, VTOI(ap->a_vp), 0);
2074 }
2075 }
2076 mutex_exit(&lfs_lock);
2077 return 0;
2078
2079 case LFCNWRAPGO:
2080 case LFCNWRAPGO_COMPAT:
2081 /*
2082 * Having done its work, the agent wakes up the writer.
2083 * If the argument is 1, it sleeps until a new segment
2084 * is selected.
2085 */
2086 mutex_enter(&lfs_lock);
2087 error = lfs_wrapgo(fs, VTOI(ap->a_vp),
2088 ap->a_command == LFCNWRAPGO_COMPAT ? 1 :
2089 *((int *)ap->a_data));
2090 mutex_exit(&lfs_lock);
2091 return error;
2092
2093 case LFCNWRAPPASS:
2094 if ((VTOI(ap->a_vp)->i_lfs_iflags & LFSI_WRAPWAIT))
2095 return EALREADY;
2096 mutex_enter(&lfs_lock);
2097 if (fs->lfs_stoplwp != curlwp) {
2098 mutex_exit(&lfs_lock);
2099 return EALREADY;
2100 }
2101 if (fs->lfs_nowrap == 0) {
2102 mutex_exit(&lfs_lock);
2103 return EBUSY;
2104 }
2105 fs->lfs_wrappass = 1;
2106 wakeup(&fs->lfs_wrappass);
2107 /* Wait for the log to wrap, if asked */
2108 if (*(int *)ap->a_data) {
2109 mutex_enter(ap->a_vp->v_interlock);
2110 if (lfs_vref(ap->a_vp) != 0)
2111 panic("LFCNWRAPPASS: lfs_vref failed");
2112 VTOI(ap->a_vp)->i_lfs_iflags |= LFSI_WRAPWAIT;
2113 log(LOG_NOTICE, "LFCNPASS waiting for log wrap\n");
2114 error = mtsleep(&fs->lfs_nowrap, PCATCH | PUSER,
2115 "segwrap", 0, &lfs_lock);
2116 log(LOG_NOTICE, "LFCNPASS done waiting\n");
2117 VTOI(ap->a_vp)->i_lfs_iflags &= ~LFSI_WRAPWAIT;
2118 lfs_vunref(ap->a_vp);
2119 }
2120 mutex_exit(&lfs_lock);
2121 return error;
2122
2123 case LFCNWRAPSTATUS:
2124 mutex_enter(&lfs_lock);
2125 *(int *)ap->a_data = fs->lfs_wrapstatus;
2126 mutex_exit(&lfs_lock);
2127 return 0;
2128
2129 default:
2130 return ulfs_fcntl(v);
2131 }
2132 return 0;
2133 }
2134
2135 /*
2136 * Return the last logical file offset that should be written for this file
2137 * if we're doing a write that ends at "size". If writing, we need to know
2138 * about sizes on disk, i.e. fragments if there are any; if reading, we need
2139 * to know about entire blocks.
2140 */
2141 void
2142 lfs_gop_size(struct vnode *vp, off_t size, off_t *eobp, int flags)
2143 {
2144 struct inode *ip = VTOI(vp);
2145 struct lfs *fs = ip->i_lfs;
2146 daddr_t olbn, nlbn;
2147
2148 olbn = lfs_lblkno(fs, ip->i_size);
2149 nlbn = lfs_lblkno(fs, size);
2150 if (!(flags & GOP_SIZE_MEM) && nlbn < ULFS_NDADDR && olbn <= nlbn) {
2151 *eobp = lfs_fragroundup(fs, size);
2152 } else {
2153 *eobp = lfs_blkroundup(fs, size);
2154 }
2155 }
2156
2157 #ifdef DEBUG
2158 void lfs_dump_vop(void *);
2159
2160 void
2161 lfs_dump_vop(void *v)
2162 {
2163 struct vop_putpages_args /* {
2164 struct vnode *a_vp;
2165 voff_t a_offlo;
2166 voff_t a_offhi;
2167 int a_flags;
2168 } */ *ap = v;
2169
2170 #ifdef DDB
2171 vfs_vnode_print(ap->a_vp, 0, printf);
2172 #endif
2173 lfs_dump_dinode(VTOI(ap->a_vp)->i_din.ffs1_din);
2174 }
2175 #endif
2176
2177 int
2178 lfs_mmap(void *v)
2179 {
2180 struct vop_mmap_args /* {
2181 const struct vnodeop_desc *a_desc;
2182 struct vnode *a_vp;
2183 vm_prot_t a_prot;
2184 kauth_cred_t a_cred;
2185 } */ *ap = v;
2186
2187 if (VTOI(ap->a_vp)->i_number == LFS_IFILE_INUM)
2188 return EOPNOTSUPP;
2189 return ulfs_mmap(v);
2190 }
2191
2192 static int
2193 lfs_openextattr(void *v)
2194 {
2195 struct vop_openextattr_args /* {
2196 struct vnode *a_vp;
2197 kauth_cred_t a_cred;
2198 struct proc *a_p;
2199 } */ *ap = v;
2200 struct inode *ip = VTOI(ap->a_vp);
2201 struct ulfsmount *ump = ip->i_ump;
2202 //struct lfs *fs = ip->i_lfs;
2203
2204 /* Not supported for ULFS1 file systems. */
2205 if (ump->um_fstype == ULFS1)
2206 return (EOPNOTSUPP);
2207
2208 /* XXX Not implemented for ULFS2 file systems. */
2209 return (EOPNOTSUPP);
2210 }
2211
2212 static int
2213 lfs_closeextattr(void *v)
2214 {
2215 struct vop_closeextattr_args /* {
2216 struct vnode *a_vp;
2217 int a_commit;
2218 kauth_cred_t a_cred;
2219 struct proc *a_p;
2220 } */ *ap = v;
2221 struct inode *ip = VTOI(ap->a_vp);
2222 struct ulfsmount *ump = ip->i_ump;
2223 //struct lfs *fs = ip->i_lfs;
2224
2225 /* Not supported for ULFS1 file systems. */
2226 if (ump->um_fstype == ULFS1)
2227 return (EOPNOTSUPP);
2228
2229 /* XXX Not implemented for ULFS2 file systems. */
2230 return (EOPNOTSUPP);
2231 }
2232
2233 static int
2234 lfs_getextattr(void *v)
2235 {
2236 struct vop_getextattr_args /* {
2237 struct vnode *a_vp;
2238 int a_attrnamespace;
2239 const char *a_name;
2240 struct uio *a_uio;
2241 size_t *a_size;
2242 kauth_cred_t a_cred;
2243 struct proc *a_p;
2244 } */ *ap = v;
2245 struct vnode *vp = ap->a_vp;
2246 struct inode *ip = VTOI(vp);
2247 struct ulfsmount *ump = ip->i_ump;
2248 //struct lfs *fs = ip->i_lfs;
2249 int error;
2250
2251 if (ump->um_fstype == ULFS1) {
2252 #ifdef LFS_EXTATTR
2253 fstrans_start(vp->v_mount, FSTRANS_SHARED);
2254 error = ulfs_getextattr(ap);
2255 fstrans_done(vp->v_mount);
2256 #else
2257 error = EOPNOTSUPP;
2258 #endif
2259 return error;
2260 }
2261
2262 /* XXX Not implemented for ULFS2 file systems. */
2263 return (EOPNOTSUPP);
2264 }
2265
2266 static int
2267 lfs_setextattr(void *v)
2268 {
2269 struct vop_setextattr_args /* {
2270 struct vnode *a_vp;
2271 int a_attrnamespace;
2272 const char *a_name;
2273 struct uio *a_uio;
2274 kauth_cred_t a_cred;
2275 struct proc *a_p;
2276 } */ *ap = v;
2277 struct vnode *vp = ap->a_vp;
2278 struct inode *ip = VTOI(vp);
2279 struct ulfsmount *ump = ip->i_ump;
2280 //struct lfs *fs = ip->i_lfs;
2281 int error;
2282
2283 if (ump->um_fstype == ULFS1) {
2284 #ifdef LFS_EXTATTR
2285 fstrans_start(vp->v_mount, FSTRANS_SHARED);
2286 error = ulfs_setextattr(ap);
2287 fstrans_done(vp->v_mount);
2288 #else
2289 error = EOPNOTSUPP;
2290 #endif
2291 return error;
2292 }
2293
2294 /* XXX Not implemented for ULFS2 file systems. */
2295 return (EOPNOTSUPP);
2296 }
2297
2298 static int
2299 lfs_listextattr(void *v)
2300 {
2301 struct vop_listextattr_args /* {
2302 struct vnode *a_vp;
2303 int a_attrnamespace;
2304 struct uio *a_uio;
2305 size_t *a_size;
2306 kauth_cred_t a_cred;
2307 struct proc *a_p;
2308 } */ *ap = v;
2309 struct vnode *vp = ap->a_vp;
2310 struct inode *ip = VTOI(vp);
2311 struct ulfsmount *ump = ip->i_ump;
2312 //struct lfs *fs = ip->i_lfs;
2313 int error;
2314
2315 if (ump->um_fstype == ULFS1) {
2316 #ifdef LFS_EXTATTR
2317 fstrans_start(vp->v_mount, FSTRANS_SHARED);
2318 error = ulfs_listextattr(ap);
2319 fstrans_done(vp->v_mount);
2320 #else
2321 error = EOPNOTSUPP;
2322 #endif
2323 return error;
2324 }
2325
2326 /* XXX Not implemented for ULFS2 file systems. */
2327 return (EOPNOTSUPP);
2328 }
2329
2330 static int
2331 lfs_deleteextattr(void *v)
2332 {
2333 struct vop_deleteextattr_args /* {
2334 struct vnode *a_vp;
2335 int a_attrnamespace;
2336 kauth_cred_t a_cred;
2337 struct proc *a_p;
2338 } */ *ap = v;
2339 struct vnode *vp = ap->a_vp;
2340 struct inode *ip = VTOI(vp);
2341 struct ulfsmount *ump = ip->i_ump;
2342 //struct fs *fs = ip->i_lfs;
2343 int error;
2344
2345 if (ump->um_fstype == ULFS1) {
2346 #ifdef LFS_EXTATTR
2347 fstrans_start(vp->v_mount, FSTRANS_SHARED);
2348 error = ulfs_deleteextattr(ap);
2349 fstrans_done(vp->v_mount);
2350 #else
2351 error = EOPNOTSUPP;
2352 #endif
2353 return error;
2354 }
2355
2356 /* XXX Not implemented for ULFS2 file systems. */
2357 return (EOPNOTSUPP);
2358 }
2359