xref: /dragonfly/sys/vfs/hammer2/hammer2_vnops.c (revision 2c3b1d1b)
1 /*
2  * Copyright (c) 2011-2018 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@dragonflybsd.org>
6  * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org>
7  * by Daniel Flores (GSOC 2013 - mentored by Matthew Dillon, compression)
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
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
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  * 3. Neither the name of The DragonFly Project nor the names of its
20  *    contributors may be used to endorse or promote products derived
21  *    from this software without specific, prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
27  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 /*
37  * Kernel Filesystem interface
38  *
39  * NOTE! local ipdata pointers must be reloaded on any modifying operation
40  *	 to the inode as its underlying chain may have changed.
41  */
42 
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/kernel.h>
46 #include <sys/fcntl.h>
47 #include <sys/buf.h>
48 #include <sys/proc.h>
49 #include <sys/namei.h>
50 #include <sys/mount.h>
51 #include <sys/vnode.h>
52 #include <sys/mountctl.h>
53 #include <sys/dirent.h>
54 #include <sys/uio.h>
55 #include <sys/objcache.h>
56 #include <sys/event.h>
57 #include <sys/file.h>
58 #include <vfs/fifofs/fifo.h>
59 
60 #include "hammer2.h"
61 
62 static int hammer2_read_file(hammer2_inode_t *ip, struct uio *uio,
63 				int seqcount);
64 static int hammer2_write_file(hammer2_inode_t *ip, struct uio *uio,
65 				int ioflag, int seqcount);
66 static void hammer2_extend_file(hammer2_inode_t *ip, hammer2_key_t nsize);
67 static void hammer2_truncate_file(hammer2_inode_t *ip, hammer2_key_t nsize);
68 
69 struct objcache *cache_xops;
70 
71 static __inline
72 void
73 hammer2_knote(struct vnode *vp, int flags)
74 {
75 	if (flags)
76 		KNOTE(&vp->v_pollinfo.vpi_kqinfo.ki_note, flags);
77 }
78 
79 /*
80  * Last reference to a vnode is going away but it is still cached.
81  */
82 static
83 int
84 hammer2_vop_inactive(struct vop_inactive_args *ap)
85 {
86 	hammer2_inode_t *ip;
87 	struct vnode *vp;
88 
89 	vp = ap->a_vp;
90 	ip = VTOI(vp);
91 
92 	/*
93 	 * Degenerate case
94 	 */
95 	if (ip == NULL) {
96 		vrecycle(vp);
97 		return (0);
98 	}
99 
100 	/*
101 	 * Check for deleted inodes and recycle immediately on the last
102 	 * release.  Be sure to destroy any left-over buffer cache buffers
103 	 * so we do not waste time trying to flush them.
104 	 *
105 	 * Note that deleting the file block chains under the inode chain
106 	 * would just be a waste of energy, so don't do it.
107 	 *
108 	 * WARNING: nvtruncbuf() can only be safely called without the inode
109 	 *	    lock held due to the way our write thread works.
110 	 */
111 	if (ip->flags & HAMMER2_INODE_ISUNLINKED) {
112 		hammer2_key_t lbase;
113 		int nblksize;
114 
115 		/*
116 		 * Detect updates to the embedded data which may be
117 		 * synchronized by the strategy code.  Simply mark the
118 		 * inode modified so it gets picked up by our normal flush.
119 		 */
120 		nblksize = hammer2_calc_logical(ip, 0, &lbase, NULL);
121 		nvtruncbuf(vp, 0, nblksize, 0, 0);
122 		vrecycle(vp);
123 	}
124 	return (0);
125 }
126 
127 /*
128  * Reclaim a vnode so that it can be reused; after the inode is
129  * disassociated, the filesystem must manage it alone.
130  */
131 static
132 int
133 hammer2_vop_reclaim(struct vop_reclaim_args *ap)
134 {
135 	hammer2_inode_t *ip;
136 	hammer2_pfs_t *pmp;
137 	struct vnode *vp;
138 
139 	vp = ap->a_vp;
140 	ip = VTOI(vp);
141 	if (ip == NULL) {
142 		return(0);
143 	}
144 	pmp = ip->pmp;
145 
146 	/*
147 	 * The final close of a deleted file or directory marks it for
148 	 * destruction.  The DELETED flag allows the flusher to shortcut
149 	 * any modified blocks still unflushed (that is, just ignore them).
150 	 *
151 	 * HAMMER2 usually does not try to optimize the freemap by returning
152 	 * deleted blocks to it as it does not usually know how many snapshots
153 	 * might be referencing portions of the file/dir.
154 	 */
155 	vp->v_data = NULL;
156 	ip->vp = NULL;
157 
158 	/*
159 	 * NOTE! We do not attempt to flush chains here, flushing is
160 	 *	 really fragile and could also deadlock.
161 	 */
162 	vclrisdirty(vp);
163 
164 	/*
165 	 * Modified inodes will already be on SIDEQ or SYNCQ.  However,
166 	 * unlinked-but-open inodes may already have been synced and might
167 	 * still require deletion-on-reclaim.
168 	 */
169 	if ((ip->flags & (HAMMER2_INODE_ISUNLINKED |
170 			  HAMMER2_INODE_DELETING)) ==
171 	    HAMMER2_INODE_ISUNLINKED) {
172 		hammer2_inode_lock(ip, 0);
173 		if ((ip->flags & (HAMMER2_INODE_ISUNLINKED |
174 				  HAMMER2_INODE_DELETING)) ==
175 		    HAMMER2_INODE_ISUNLINKED) {
176 			atomic_set_int(&ip->flags, HAMMER2_INODE_DELETING);
177 			hammer2_inode_delayed_sideq(ip);
178 		}
179 		hammer2_inode_unlock(ip);
180 	}
181 
182 	/*
183 	 * Modified inodes will already be on SIDEQ or SYNCQ, no further
184 	 * action is needed.
185 	 *
186 	 * We cannot safely synchronize the inode from inside the reclaim
187 	 * due to potentially deep locks held as-of when the reclaim occurs.
188 	 * Interactions and potential deadlocks abound.  We also can't do it
189 	 * here without desynchronizing from the related directory entrie(s).
190 	 */
191 	hammer2_inode_drop(ip);			/* vp ref */
192 
193 	/*
194 	 * XXX handle background sync when ip dirty, kernel will no longer
195 	 * notify us regarding this inode because there is no longer a
196 	 * vnode attached to it.
197 	 */
198 
199 	return (0);
200 }
201 
202 /*
203  * Currently this function synchronizes the front-end inode state to the
204  * backend chain topology, then flushes the inode's chain and sub-topology
205  * to backend media.  This function does not flush the root topology down to
206  * the inode.
207  */
208 static
209 int
210 hammer2_vop_fsync(struct vop_fsync_args *ap)
211 {
212 	hammer2_inode_t *ip;
213 	struct vnode *vp;
214 	int error1;
215 	int error2;
216 
217 	vp = ap->a_vp;
218 	ip = VTOI(vp);
219 	error1 = 0;
220 
221 	hammer2_trans_init(ip->pmp, 0);
222 
223 	/*
224 	 * Flush dirty buffers in the file's logical buffer cache.
225 	 * It is best to wait for the strategy code to commit the
226 	 * buffers to the device's backing buffer cache before
227 	 * then trying to flush the inode.
228 	 *
229 	 * This should be quick, but certain inode modifications cached
230 	 * entirely in the hammer2_inode structure may not trigger a
231 	 * buffer read until the flush so the fsync can wind up also
232 	 * doing scattered reads.
233 	 */
234 	vfsync(vp, ap->a_waitfor, 1, NULL, NULL);
235 	bio_track_wait(&vp->v_track_write, 0, 0);
236 
237 	/*
238 	 * Flush any inode changes
239 	 */
240 	hammer2_inode_lock(ip, 0);
241 	if (ip->flags & (HAMMER2_INODE_RESIZED|HAMMER2_INODE_MODIFIED))
242 		error1 = hammer2_inode_chain_sync(ip);
243 
244 	/*
245 	 * Flush dirty chains related to the inode.
246 	 *
247 	 * NOTE! We are not in a flush transaction.  The inode remains on
248 	 *	 the sideq so the filesystem syncer can synchronize it to
249 	 *	 the volume root.
250 	 */
251 	error2 = hammer2_inode_chain_flush(ip, HAMMER2_XOP_INODE_STOP);
252 	if (error2)
253 		error1 = error2;
254 
255 	/*
256 	 * We may be able to clear the vnode dirty flag.  The
257 	 * hammer2_pfs_moderate() code depends on this usually working.
258 	 */
259 	if ((ip->flags & (HAMMER2_INODE_MODIFIED |
260 			  HAMMER2_INODE_RESIZED |
261 			  HAMMER2_INODE_DIRTYDATA)) == 0 &&
262 	    RB_EMPTY(&vp->v_rbdirty_tree) &&
263 	    !bio_track_active(&vp->v_track_write)) {
264 		vclrisdirty(vp);
265 	}
266 	hammer2_inode_unlock(ip);
267 	hammer2_trans_done(ip->pmp, 0);
268 
269 	return (error1);
270 }
271 
272 static
273 int
274 hammer2_vop_access(struct vop_access_args *ap)
275 {
276 	hammer2_inode_t *ip = VTOI(ap->a_vp);
277 	uid_t uid;
278 	gid_t gid;
279 	int error;
280 
281 	hammer2_inode_lock(ip, HAMMER2_RESOLVE_SHARED);
282 	uid = hammer2_to_unix_xid(&ip->meta.uid);
283 	gid = hammer2_to_unix_xid(&ip->meta.gid);
284 	error = vop_helper_access(ap, uid, gid, ip->meta.mode, ip->meta.uflags);
285 	hammer2_inode_unlock(ip);
286 
287 	return (error);
288 }
289 
290 static
291 int
292 hammer2_vop_getattr(struct vop_getattr_args *ap)
293 {
294 	hammer2_pfs_t *pmp;
295 	hammer2_inode_t *ip;
296 	struct vnode *vp;
297 	struct vattr *vap;
298 	hammer2_chain_t *chain;
299 	int i;
300 
301 	vp = ap->a_vp;
302 	vap = ap->a_vap;
303 
304 	ip = VTOI(vp);
305 	pmp = ip->pmp;
306 
307 	hammer2_inode_lock(ip, HAMMER2_RESOLVE_SHARED);
308 
309 	vap->va_fsid = pmp->mp->mnt_stat.f_fsid.val[0];
310 	vap->va_fileid = ip->meta.inum;
311 	vap->va_mode = ip->meta.mode;
312 	vap->va_nlink = ip->meta.nlinks;
313 	vap->va_uid = hammer2_to_unix_xid(&ip->meta.uid);
314 	vap->va_gid = hammer2_to_unix_xid(&ip->meta.gid);
315 	vap->va_rmajor = 0;
316 	vap->va_rminor = 0;
317 	vap->va_size = ip->meta.size;	/* protected by shared lock */
318 	vap->va_blocksize = HAMMER2_PBUFSIZE;
319 	vap->va_flags = ip->meta.uflags;
320 	hammer2_time_to_timespec(ip->meta.ctime, &vap->va_ctime);
321 	hammer2_time_to_timespec(ip->meta.mtime, &vap->va_mtime);
322 	hammer2_time_to_timespec(ip->meta.mtime, &vap->va_atime);
323 	vap->va_gen = 1;
324 	vap->va_bytes = 0;
325 	if (ip->meta.type == HAMMER2_OBJTYPE_DIRECTORY) {
326 		/*
327 		 * Can't really calculate directory use sans the files under
328 		 * it, just assume one block for now.
329 		 */
330 		vap->va_bytes += HAMMER2_INODE_BYTES;
331 	} else {
332 		for (i = 0; i < ip->cluster.nchains; ++i) {
333 			if ((chain = ip->cluster.array[i].chain) != NULL) {
334 				if (vap->va_bytes <
335 				    chain->bref.embed.stats.data_count) {
336 					vap->va_bytes =
337 					    chain->bref.embed.stats.data_count;
338 				}
339 			}
340 		}
341 	}
342 	vap->va_type = hammer2_get_vtype(ip->meta.type);
343 	vap->va_filerev = 0;
344 	vap->va_uid_uuid = ip->meta.uid;
345 	vap->va_gid_uuid = ip->meta.gid;
346 	vap->va_vaflags = VA_UID_UUID_VALID | VA_GID_UUID_VALID |
347 			  VA_FSID_UUID_VALID;
348 
349 	hammer2_inode_unlock(ip);
350 
351 	return (0);
352 }
353 
354 static
355 int
356 hammer2_vop_setattr(struct vop_setattr_args *ap)
357 {
358 	hammer2_inode_t *ip;
359 	struct vnode *vp;
360 	struct vattr *vap;
361 	int error;
362 	int kflags = 0;
363 	uint64_t ctime;
364 
365 	vp = ap->a_vp;
366 	vap = ap->a_vap;
367 	hammer2_update_time(&ctime);
368 
369 	ip = VTOI(vp);
370 
371 	if (ip->pmp->ronly)
372 		return (EROFS);
373 
374 	/*
375 	 * Normally disallow setattr if there is no space, unless we
376 	 * are in emergency mode (might be needed to chflags -R noschg
377 	 * files prior to removal).
378 	 */
379 	if ((ip->pmp->flags & HAMMER2_PMPF_EMERG) == 0 &&
380 	    hammer2_vfs_enospace(ip, 0, ap->a_cred) > 1) {
381 		return (ENOSPC);
382 	}
383 
384 	hammer2_trans_init(ip->pmp, 0);
385 	hammer2_inode_lock(ip, 0);
386 	error = 0;
387 
388 	if (vap->va_flags != VNOVAL) {
389 		uint32_t flags;
390 
391 		flags = ip->meta.uflags;
392 		error = vop_helper_setattr_flags(&flags, vap->va_flags,
393 				     hammer2_to_unix_xid(&ip->meta.uid),
394 				     ap->a_cred);
395 		if (error == 0) {
396 			if (ip->meta.uflags != flags) {
397 				hammer2_inode_modify(ip);
398 				ip->meta.uflags = flags;
399 				ip->meta.ctime = ctime;
400 				kflags |= NOTE_ATTRIB;
401 			}
402 			if (ip->meta.uflags & (IMMUTABLE | APPEND)) {
403 				error = 0;
404 				goto done;
405 			}
406 		}
407 		goto done;
408 	}
409 	if (ip->meta.uflags & (IMMUTABLE | APPEND)) {
410 		error = EPERM;
411 		goto done;
412 	}
413 	if (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL) {
414 		mode_t cur_mode = ip->meta.mode;
415 		uid_t cur_uid = hammer2_to_unix_xid(&ip->meta.uid);
416 		gid_t cur_gid = hammer2_to_unix_xid(&ip->meta.gid);
417 		uuid_t uuid_uid;
418 		uuid_t uuid_gid;
419 
420 		error = vop_helper_chown(ap->a_vp, vap->va_uid, vap->va_gid,
421 					 ap->a_cred,
422 					 &cur_uid, &cur_gid, &cur_mode);
423 		if (error == 0) {
424 			hammer2_guid_to_uuid(&uuid_uid, cur_uid);
425 			hammer2_guid_to_uuid(&uuid_gid, cur_gid);
426 			if (bcmp(&uuid_uid, &ip->meta.uid, sizeof(uuid_uid)) ||
427 			    bcmp(&uuid_gid, &ip->meta.gid, sizeof(uuid_gid)) ||
428 			    ip->meta.mode != cur_mode
429 			) {
430 				hammer2_inode_modify(ip);
431 				ip->meta.uid = uuid_uid;
432 				ip->meta.gid = uuid_gid;
433 				ip->meta.mode = cur_mode;
434 				ip->meta.ctime = ctime;
435 			}
436 			kflags |= NOTE_ATTRIB;
437 		}
438 	}
439 
440 	/*
441 	 * Resize the file
442 	 */
443 	if (vap->va_size != VNOVAL && ip->meta.size != vap->va_size) {
444 		switch(vp->v_type) {
445 		case VREG:
446 			if (vap->va_size == ip->meta.size)
447 				break;
448 			if (vap->va_size < ip->meta.size) {
449 				hammer2_mtx_ex(&ip->truncate_lock);
450 				hammer2_truncate_file(ip, vap->va_size);
451 				hammer2_mtx_unlock(&ip->truncate_lock);
452 				kflags |= NOTE_WRITE;
453 			} else {
454 				hammer2_extend_file(ip, vap->va_size);
455 				kflags |= NOTE_WRITE | NOTE_EXTEND;
456 			}
457 			hammer2_inode_modify(ip);
458 			ip->meta.mtime = ctime;
459 			vclrflags(vp, VLASTWRITETS);
460 			break;
461 		default:
462 			error = EINVAL;
463 			goto done;
464 		}
465 	}
466 #if 0
467 	/* atime not supported */
468 	if (vap->va_atime.tv_sec != VNOVAL) {
469 		hammer2_inode_modify(ip);
470 		ip->meta.atime = hammer2_timespec_to_time(&vap->va_atime);
471 		kflags |= NOTE_ATTRIB;
472 	}
473 #endif
474 	if (vap->va_mode != (mode_t)VNOVAL) {
475 		mode_t cur_mode = ip->meta.mode;
476 		uid_t cur_uid = hammer2_to_unix_xid(&ip->meta.uid);
477 		gid_t cur_gid = hammer2_to_unix_xid(&ip->meta.gid);
478 
479 		error = vop_helper_chmod(ap->a_vp, vap->va_mode, ap->a_cred,
480 					 cur_uid, cur_gid, &cur_mode);
481 		if (error == 0 && ip->meta.mode != cur_mode) {
482 			hammer2_inode_modify(ip);
483 			ip->meta.mode = cur_mode;
484 			ip->meta.ctime = ctime;
485 			kflags |= NOTE_ATTRIB;
486 		}
487 	}
488 
489 	if (vap->va_mtime.tv_sec != VNOVAL) {
490 		hammer2_inode_modify(ip);
491 		ip->meta.mtime = hammer2_timespec_to_time(&vap->va_mtime);
492 		kflags |= NOTE_ATTRIB;
493 		vclrflags(vp, VLASTWRITETS);
494 	}
495 
496 done:
497 	/*
498 	 * If a truncation occurred we must call chain_sync() now in order
499 	 * to trim the related data chains, otherwise a later expansion can
500 	 * cause havoc.
501 	 *
502 	 * If an extend occured that changed the DIRECTDATA state, we must
503 	 * call inode_fsync now in order to prepare the inode's indirect
504 	 * block table.
505 	 *
506 	 * WARNING! This means we are making an adjustment to the inode's
507 	 * chain outside of sync/fsync, and not just to inode->meta, which
508 	 * may result in some consistency issues if a crash were to occur
509 	 * at just the wrong time.
510 	 */
511 	if (ip->flags & HAMMER2_INODE_RESIZED)
512 		hammer2_inode_chain_sync(ip);
513 
514 	/*
515 	 * Cleanup.
516 	 */
517 	hammer2_inode_unlock(ip);
518 	hammer2_trans_done(ip->pmp, HAMMER2_TRANS_SIDEQ);
519 	hammer2_knote(ip->vp, kflags);
520 
521 	return (error);
522 }
523 
524 static
525 int
526 hammer2_vop_readdir(struct vop_readdir_args *ap)
527 {
528 	hammer2_xop_readdir_t *xop;
529 	hammer2_blockref_t bref;
530 	hammer2_inode_t *ip;
531 	hammer2_tid_t inum;
532 	hammer2_key_t lkey;
533 	struct uio *uio;
534 	off_t *cookies;
535 	off_t saveoff;
536 	int cookie_index;
537 	int ncookies;
538 	int error;
539 	int eofflag;
540 	int r;
541 
542 	ip = VTOI(ap->a_vp);
543 	uio = ap->a_uio;
544 	saveoff = uio->uio_offset;
545 	eofflag = 0;
546 	error = 0;
547 
548 	/*
549 	 * Setup cookies directory entry cookies if requested
550 	 */
551 	if (ap->a_ncookies) {
552 		ncookies = uio->uio_resid / 16 + 1;
553 		if (ncookies > 1024)
554 			ncookies = 1024;
555 		cookies = kmalloc(ncookies * sizeof(off_t), M_TEMP, M_WAITOK);
556 	} else {
557 		ncookies = -1;
558 		cookies = NULL;
559 	}
560 	cookie_index = 0;
561 
562 	hammer2_inode_lock(ip, HAMMER2_RESOLVE_SHARED);
563 
564 	/*
565 	 * Handle artificial entries.  To ensure that only positive 64 bit
566 	 * quantities are returned to userland we always strip off bit 63.
567 	 * The hash code is designed such that codes 0x0000-0x7FFF are not
568 	 * used, allowing us to use these codes for articial entries.
569 	 *
570 	 * Entry 0 is used for '.' and entry 1 is used for '..'.  Do not
571 	 * allow '..' to cross the mount point into (e.g.) the super-root.
572 	 */
573 	if (saveoff == 0) {
574 		inum = ip->meta.inum & HAMMER2_DIRHASH_USERMSK;
575 		r = vop_write_dirent(&error, uio, inum, DT_DIR, 1, ".");
576 		if (r)
577 			goto done;
578 		if (cookies)
579 			cookies[cookie_index] = saveoff;
580 		++saveoff;
581 		++cookie_index;
582 		if (cookie_index == ncookies)
583 			goto done;
584 	}
585 
586 	if (saveoff == 1) {
587 		/*
588 		 * Be careful with lockorder when accessing ".."
589 		 *
590 		 * (ip is the current dir. xip is the parent dir).
591 		 */
592 		inum = ip->meta.inum & HAMMER2_DIRHASH_USERMSK;
593 		if (ip != ip->pmp->iroot)
594 			inum = ip->meta.iparent & HAMMER2_DIRHASH_USERMSK;
595 		r = vop_write_dirent(&error, uio, inum, DT_DIR, 2, "..");
596 		if (r)
597 			goto done;
598 		if (cookies)
599 			cookies[cookie_index] = saveoff;
600 		++saveoff;
601 		++cookie_index;
602 		if (cookie_index == ncookies)
603 			goto done;
604 	}
605 
606 	lkey = saveoff | HAMMER2_DIRHASH_VISIBLE;
607 	if (hammer2_debug & 0x0020)
608 		kprintf("readdir: lkey %016jx\n", lkey);
609 	if (error)
610 		goto done;
611 
612 	/*
613 	 * Use XOP for cluster scan.
614 	 *
615 	 * parent is the inode cluster, already locked for us.  Don't
616 	 * double lock shared locks as this will screw up upgrades.
617 	 */
618 	xop = hammer2_xop_alloc(ip, 0);
619 	xop->lkey = lkey;
620 	hammer2_xop_start(&xop->head, &hammer2_readdir_desc);
621 
622 	for (;;) {
623 		const hammer2_inode_data_t *ripdata;
624 		const char *dname;
625 		int dtype;
626 
627 		error = hammer2_xop_collect(&xop->head, 0);
628 		error = hammer2_error_to_errno(error);
629 		if (error) {
630 			break;
631 		}
632 		if (cookie_index == ncookies)
633 			break;
634 		if (hammer2_debug & 0x0020)
635 			kprintf("cluster chain %p %p\n",
636 				xop->head.cluster.focus,
637 				(xop->head.cluster.focus ?
638 				 xop->head.cluster.focus->data : (void *)-1));
639 		hammer2_cluster_bref(&xop->head.cluster, &bref);
640 
641 		if (bref.type == HAMMER2_BREF_TYPE_INODE) {
642 			ripdata = &hammer2_xop_gdata(&xop->head)->ipdata;
643 			dtype = hammer2_get_dtype(ripdata->meta.type);
644 			saveoff = bref.key & HAMMER2_DIRHASH_USERMSK;
645 			r = vop_write_dirent(&error, uio,
646 					     ripdata->meta.inum &
647 					      HAMMER2_DIRHASH_USERMSK,
648 					     dtype,
649 					     ripdata->meta.name_len,
650 					     ripdata->filename);
651 			hammer2_xop_pdata(&xop->head);
652 			if (r)
653 				break;
654 			if (cookies)
655 				cookies[cookie_index] = saveoff;
656 			++cookie_index;
657 		} else if (bref.type == HAMMER2_BREF_TYPE_DIRENT) {
658 			uint16_t namlen;
659 
660 			dtype = hammer2_get_dtype(bref.embed.dirent.type);
661 			saveoff = bref.key & HAMMER2_DIRHASH_USERMSK;
662 			namlen = bref.embed.dirent.namlen;
663 			if (namlen <= sizeof(bref.check.buf)) {
664 				dname = bref.check.buf;
665 			} else {
666 				dname = hammer2_xop_gdata(&xop->head)->buf;
667 			}
668 			r = vop_write_dirent(&error, uio,
669 					     bref.embed.dirent.inum, dtype,
670 					     namlen, dname);
671 			if (namlen > sizeof(bref.check.buf))
672 				hammer2_xop_pdata(&xop->head);
673 			if (r)
674 				break;
675 			if (cookies)
676 				cookies[cookie_index] = saveoff;
677 			++cookie_index;
678 		} else {
679 			/* XXX chain error */
680 			kprintf("bad chain type readdir %d\n", bref.type);
681 		}
682 	}
683 	hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP);
684 	if (error == ENOENT) {
685 		error = 0;
686 		eofflag = 1;
687 		saveoff = (hammer2_key_t)-1;
688 	} else {
689 		saveoff = bref.key & HAMMER2_DIRHASH_USERMSK;
690 	}
691 done:
692 	hammer2_inode_unlock(ip);
693 	if (ap->a_eofflag)
694 		*ap->a_eofflag = eofflag;
695 	if (hammer2_debug & 0x0020)
696 		kprintf("readdir: done at %016jx\n", saveoff);
697 	uio->uio_offset = saveoff & ~HAMMER2_DIRHASH_VISIBLE;
698 	if (error && cookie_index == 0) {
699 		if (cookies) {
700 			kfree(cookies, M_TEMP);
701 			*ap->a_ncookies = 0;
702 			*ap->a_cookies = NULL;
703 		}
704 	} else {
705 		if (cookies) {
706 			*ap->a_ncookies = cookie_index;
707 			*ap->a_cookies = cookies;
708 		}
709 	}
710 	return (error);
711 }
712 
713 /*
714  * hammer2_vop_readlink { vp, uio, cred }
715  */
716 static
717 int
718 hammer2_vop_readlink(struct vop_readlink_args *ap)
719 {
720 	struct vnode *vp;
721 	hammer2_inode_t *ip;
722 	int error;
723 
724 	vp = ap->a_vp;
725 	if (vp->v_type != VLNK)
726 		return (EINVAL);
727 	ip = VTOI(vp);
728 
729 	error = hammer2_read_file(ip, ap->a_uio, 0);
730 	return (error);
731 }
732 
733 static
734 int
735 hammer2_vop_read(struct vop_read_args *ap)
736 {
737 	struct vnode *vp;
738 	hammer2_inode_t *ip;
739 	struct uio *uio;
740 	int error;
741 	int seqcount;
742 	int bigread;
743 
744 	/*
745 	 * Read operations supported on this vnode?
746 	 */
747 	vp = ap->a_vp;
748 	if (vp->v_type != VREG)
749 		return (EINVAL);
750 
751 	/*
752 	 * Misc
753 	 */
754 	ip = VTOI(vp);
755 	uio = ap->a_uio;
756 	error = 0;
757 
758 	seqcount = ap->a_ioflag >> IO_SEQSHIFT;
759 	bigread = (uio->uio_resid > 100 * 1024 * 1024);
760 
761 	error = hammer2_read_file(ip, uio, seqcount);
762 	return (error);
763 }
764 
765 static
766 int
767 hammer2_vop_write(struct vop_write_args *ap)
768 {
769 	hammer2_inode_t *ip;
770 	thread_t td;
771 	struct vnode *vp;
772 	struct uio *uio;
773 	int error;
774 	int seqcount;
775 	int ioflag;
776 
777 	/*
778 	 * Read operations supported on this vnode?
779 	 */
780 	vp = ap->a_vp;
781 	if (vp->v_type != VREG)
782 		return (EINVAL);
783 
784 	/*
785 	 * Misc
786 	 */
787 	ip = VTOI(vp);
788 	ioflag = ap->a_ioflag;
789 	uio = ap->a_uio;
790 	error = 0;
791 	if (ip->pmp->ronly || (ip->pmp->flags & HAMMER2_PMPF_EMERG))
792 		return (EROFS);
793 	switch (hammer2_vfs_enospace(ip, uio->uio_resid, ap->a_cred)) {
794 	case 2:
795 		return (ENOSPC);
796 	case 1:
797 		ioflag |= IO_DIRECT;	/* semi-synchronous */
798 		/* fall through */
799 	default:
800 		break;
801 	}
802 
803 	seqcount = ioflag >> IO_SEQSHIFT;
804 
805 	/*
806 	 * Check resource limit
807 	 */
808 	if (uio->uio_resid > 0 && (td = uio->uio_td) != NULL && td->td_proc &&
809 	    uio->uio_offset + uio->uio_resid >
810 	     td->td_proc->p_rlimit[RLIMIT_FSIZE].rlim_cur) {
811 		lwpsignal(td->td_proc, td->td_lwp, SIGXFSZ);
812 		return (EFBIG);
813 	}
814 
815 	/*
816 	 * The transaction interlocks against flush initiations
817 	 * (note: but will run concurrently with the actual flush).
818 	 *
819 	 * To avoid deadlocking against the VM system, we must flag any
820 	 * transaction related to the buffer cache or other direct
821 	 * VM page manipulation.
822 	 */
823 	if (uio->uio_segflg == UIO_NOCOPY) {
824 		hammer2_trans_init(ip->pmp, HAMMER2_TRANS_BUFCACHE);
825 	} else {
826 		hammer2_trans_init(ip->pmp, 0);
827 	}
828 	error = hammer2_write_file(ip, uio, ioflag, seqcount);
829 	if (uio->uio_segflg == UIO_NOCOPY)
830 		hammer2_trans_done(ip->pmp, HAMMER2_TRANS_BUFCACHE |
831 					    HAMMER2_TRANS_SIDEQ);
832 	else
833 		hammer2_trans_done(ip->pmp, HAMMER2_TRANS_SIDEQ);
834 
835 	return (error);
836 }
837 
838 /*
839  * Perform read operations on a file or symlink given an UNLOCKED
840  * inode and uio.
841  *
842  * The passed ip is not locked.
843  */
844 static
845 int
846 hammer2_read_file(hammer2_inode_t *ip, struct uio *uio, int seqcount)
847 {
848 	hammer2_off_t size;
849 	struct buf *bp;
850 	int error;
851 
852 	error = 0;
853 
854 	/*
855 	 * UIO read loop.
856 	 *
857 	 * WARNING! Assumes that the kernel interlocks size changes at the
858 	 *	    vnode level.
859 	 */
860 	hammer2_mtx_sh(&ip->lock);
861 	hammer2_mtx_sh(&ip->truncate_lock);
862 	size = ip->meta.size;
863 	hammer2_mtx_unlock(&ip->lock);
864 
865 	while (uio->uio_resid > 0 && uio->uio_offset < size) {
866 		hammer2_key_t lbase;
867 		hammer2_key_t leof;
868 		int lblksize;
869 		int loff;
870 		int n;
871 
872 		lblksize = hammer2_calc_logical(ip, uio->uio_offset,
873 						&lbase, &leof);
874 
875 #if 1
876 		bp = NULL;
877 		error = cluster_readx(ip->vp, leof, lbase, lblksize,
878 				      B_NOTMETA | B_KVABIO,
879 				      uio->uio_resid,
880 				      seqcount * MAXBSIZE,
881 				      &bp);
882 #else
883 		if (uio->uio_segflg == UIO_NOCOPY) {
884 			bp = getblk(ip->vp, lbase, lblksize,
885 				    GETBLK_BHEAVY | GETBLK_KVABIO, 0);
886 			if (bp->b_flags & B_CACHE) {
887 				int i;
888 				int j = 0;
889 				if (bp->b_xio.xio_npages != 16)
890 					kprintf("NPAGES BAD\n");
891 				for (i = 0; i < bp->b_xio.xio_npages; ++i) {
892 					vm_page_t m;
893 					m = bp->b_xio.xio_pages[i];
894 					if (m == NULL || m->valid == 0) {
895 						kprintf("bp %016jx %016jx pg %d inv",
896 							lbase, leof, i);
897 						if (m)
898 							kprintf("m->object %p/%p", m->object, ip->vp->v_object);
899 						kprintf("\n");
900 						j = 1;
901 					}
902 				}
903 				if (j)
904 					kprintf("b_flags %08x, b_error %d\n", bp->b_flags, bp->b_error);
905 			}
906 			bqrelse(bp);
907 		}
908 		error = bread_kvabio(ip->vp, lbase, lblksize, &bp);
909 #endif
910 		if (error) {
911 			brelse(bp);
912 			break;
913 		}
914 		bkvasync(bp);
915 		loff = (int)(uio->uio_offset - lbase);
916 		n = lblksize - loff;
917 		if (n > uio->uio_resid)
918 			n = uio->uio_resid;
919 		if (n > size - uio->uio_offset)
920 			n = (int)(size - uio->uio_offset);
921 		bp->b_flags |= B_AGE;
922 		uiomovebp(bp, (char *)bp->b_data + loff, n, uio);
923 		bqrelse(bp);
924 	}
925 	hammer2_mtx_unlock(&ip->truncate_lock);
926 
927 	return (error);
928 }
929 
930 /*
931  * Write to the file represented by the inode via the logical buffer cache.
932  * The inode may represent a regular file or a symlink.
933  *
934  * The inode must not be locked.
935  */
936 static
937 int
938 hammer2_write_file(hammer2_inode_t *ip, struct uio *uio,
939 		   int ioflag, int seqcount)
940 {
941 	hammer2_key_t old_eof;
942 	hammer2_key_t new_eof;
943 	struct buf *bp;
944 	int kflags;
945 	int error;
946 	int modified;
947 
948 	/*
949 	 * Setup if append
950 	 *
951 	 * WARNING! Assumes that the kernel interlocks size changes at the
952 	 *	    vnode level.
953 	 */
954 	hammer2_mtx_ex(&ip->lock);
955 	hammer2_mtx_sh(&ip->truncate_lock);
956 	if (ioflag & IO_APPEND)
957 		uio->uio_offset = ip->meta.size;
958 	old_eof = ip->meta.size;
959 
960 	/*
961 	 * Extend the file if necessary.  If the write fails at some point
962 	 * we will truncate it back down to cover as much as we were able
963 	 * to write.
964 	 *
965 	 * Doing this now makes it easier to calculate buffer sizes in
966 	 * the loop.
967 	 */
968 	kflags = 0;
969 	error = 0;
970 	modified = 0;
971 
972 	if (uio->uio_offset + uio->uio_resid > old_eof) {
973 		new_eof = uio->uio_offset + uio->uio_resid;
974 		modified = 1;
975 		hammer2_extend_file(ip, new_eof);
976 		kflags |= NOTE_EXTEND;
977 	} else {
978 		new_eof = old_eof;
979 	}
980 	hammer2_mtx_unlock(&ip->lock);
981 
982 	/*
983 	 * UIO write loop
984 	 */
985 	while (uio->uio_resid > 0) {
986 		hammer2_key_t lbase;
987 		int trivial;
988 		int endofblk;
989 		int lblksize;
990 		int loff;
991 		int n;
992 
993 		/*
994 		 * Don't allow the buffer build to blow out the buffer
995 		 * cache.
996 		 */
997 		if ((ioflag & IO_RECURSE) == 0)
998 			bwillwrite(HAMMER2_PBUFSIZE);
999 
1000 		/*
1001 		 * This nominally tells us how much we can cluster and
1002 		 * what the logical buffer size needs to be.  Currently
1003 		 * we don't try to cluster the write and just handle one
1004 		 * block at a time.
1005 		 */
1006 		lblksize = hammer2_calc_logical(ip, uio->uio_offset,
1007 						&lbase, NULL);
1008 		loff = (int)(uio->uio_offset - lbase);
1009 
1010 		KKASSERT(lblksize <= MAXBSIZE);
1011 
1012 		/*
1013 		 * Calculate bytes to copy this transfer and whether the
1014 		 * copy completely covers the buffer or not.
1015 		 */
1016 		trivial = 0;
1017 		n = lblksize - loff;
1018 		if (n > uio->uio_resid) {
1019 			n = uio->uio_resid;
1020 			if (loff == lbase && uio->uio_offset + n == new_eof)
1021 				trivial = 1;
1022 			endofblk = 0;
1023 		} else {
1024 			if (loff == 0)
1025 				trivial = 1;
1026 			endofblk = 1;
1027 		}
1028 		if (lbase >= new_eof)
1029 			trivial = 1;
1030 
1031 		/*
1032 		 * Get the buffer
1033 		 */
1034 		if (uio->uio_segflg == UIO_NOCOPY) {
1035 			/*
1036 			 * Issuing a write with the same data backing the
1037 			 * buffer.  Instantiate the buffer to collect the
1038 			 * backing vm pages, then read-in any missing bits.
1039 			 *
1040 			 * This case is used by vop_stdputpages().
1041 			 */
1042 			bp = getblk(ip->vp, lbase, lblksize,
1043 				    GETBLK_BHEAVY | GETBLK_KVABIO, 0);
1044 			if ((bp->b_flags & B_CACHE) == 0) {
1045 				bqrelse(bp);
1046 				error = bread_kvabio(ip->vp, lbase,
1047 						     lblksize, &bp);
1048 			}
1049 		} else if (trivial) {
1050 			/*
1051 			 * Even though we are entirely overwriting the buffer
1052 			 * we may still have to zero it out to avoid a
1053 			 * mmap/write visibility issue.
1054 			 */
1055 			bp = getblk(ip->vp, lbase, lblksize,
1056 				    GETBLK_BHEAVY | GETBLK_KVABIO, 0);
1057 			if ((bp->b_flags & B_CACHE) == 0)
1058 				vfs_bio_clrbuf(bp);
1059 		} else {
1060 			/*
1061 			 * Partial overwrite, read in any missing bits then
1062 			 * replace the portion being written.
1063 			 *
1064 			 * (The strategy code will detect zero-fill physical
1065 			 * blocks for this case).
1066 			 */
1067 			error = bread_kvabio(ip->vp, lbase, lblksize, &bp);
1068 			if (error == 0)
1069 				bheavy(bp);
1070 		}
1071 
1072 		if (error) {
1073 			brelse(bp);
1074 			break;
1075 		}
1076 
1077 		/*
1078 		 * Ok, copy the data in
1079 		 */
1080 		bkvasync(bp);
1081 		error = uiomovebp(bp, bp->b_data + loff, n, uio);
1082 		kflags |= NOTE_WRITE;
1083 		modified = 1;
1084 		if (error) {
1085 			brelse(bp);
1086 			break;
1087 		}
1088 
1089 		/*
1090 		 * WARNING: Pageout daemon will issue UIO_NOCOPY writes
1091 		 *	    with IO_SYNC or IO_ASYNC set.  These writes
1092 		 *	    must be handled as the pageout daemon expects.
1093 		 *
1094 		 * NOTE!    H2 relies on cluster_write() here because it
1095 		 *	    cannot preallocate disk blocks at the logical
1096 		 *	    level due to not knowing what the compression
1097 		 *	    size will be at this time.
1098 		 *
1099 		 *	    We must use cluster_write() here and we depend
1100 		 *	    on the write-behind feature to flush buffers
1101 		 *	    appropriately.  If we let the buffer daemons do
1102 		 *	    it the block allocations will be all over the
1103 		 *	    map.
1104 		 */
1105 		if (ioflag & IO_SYNC) {
1106 			bwrite(bp);
1107 		} else if ((ioflag & IO_DIRECT) && endofblk) {
1108 			bawrite(bp);
1109 		} else if (ioflag & IO_ASYNC) {
1110 			bawrite(bp);
1111 		} else if (ip->vp->v_mount->mnt_flag & MNT_NOCLUSTERW) {
1112 			bdwrite(bp);
1113 		} else {
1114 #if 1
1115 			bp->b_flags |= B_CLUSTEROK;
1116 			cluster_write(bp, new_eof, lblksize, seqcount);
1117 #else
1118 			bp->b_flags |= B_CLUSTEROK;
1119 			bdwrite(bp);
1120 #endif
1121 		}
1122 	}
1123 
1124 	/*
1125 	 * Cleanup.  If we extended the file EOF but failed to write through
1126 	 * the entire write is a failure and we have to back-up.
1127 	 */
1128 	if (error && new_eof != old_eof) {
1129 		hammer2_mtx_unlock(&ip->truncate_lock);
1130 		hammer2_mtx_ex(&ip->lock);		/* note lock order */
1131 		hammer2_mtx_ex(&ip->truncate_lock);	/* note lock order */
1132 		hammer2_truncate_file(ip, old_eof);
1133 		if (ip->flags & HAMMER2_INODE_MODIFIED)
1134 			hammer2_inode_chain_sync(ip);
1135 		hammer2_mtx_unlock(&ip->lock);
1136 	} else if (modified) {
1137 		struct vnode *vp = ip->vp;
1138 
1139 		hammer2_mtx_ex(&ip->lock);
1140 		hammer2_inode_modify(ip);
1141 		if (uio->uio_segflg == UIO_NOCOPY) {
1142 			if (vp->v_flag & VLASTWRITETS) {
1143 				ip->meta.mtime =
1144 				    (unsigned long)vp->v_lastwrite_ts.tv_sec *
1145 				    1000000 +
1146 				    vp->v_lastwrite_ts.tv_nsec / 1000;
1147 			}
1148 		} else {
1149 			hammer2_update_time(&ip->meta.mtime);
1150 			vclrflags(vp, VLASTWRITETS);
1151 		}
1152 
1153 #if 0
1154 		/*
1155 		 * REMOVED - handled by hammer2_extend_file().  Do not issue
1156 		 * a chain_sync() outside of a sync/fsync except for DIRECTDATA
1157 		 * state changes.
1158 		 *
1159 		 * Under normal conditions we only issue a chain_sync if
1160 		 * the inode's DIRECTDATA state changed.
1161 		 */
1162 		if (ip->flags & HAMMER2_INODE_RESIZED)
1163 			hammer2_inode_chain_sync(ip);
1164 #endif
1165 		hammer2_mtx_unlock(&ip->lock);
1166 		hammer2_knote(ip->vp, kflags);
1167 	}
1168 	hammer2_trans_assert_strategy(ip->pmp);
1169 	hammer2_mtx_unlock(&ip->truncate_lock);
1170 
1171 	return error;
1172 }
1173 
1174 /*
1175  * Truncate the size of a file.  The inode must be locked.
1176  *
1177  * We must unconditionally set HAMMER2_INODE_RESIZED to properly
1178  * ensure that any on-media data beyond the new file EOF has been destroyed.
1179  *
1180  * WARNING: nvtruncbuf() can only be safely called without the inode lock
1181  *	    held due to the way our write thread works.  If the truncation
1182  *	    occurs in the middle of a buffer, nvtruncbuf() is responsible
1183  *	    for dirtying that buffer and zeroing out trailing bytes.
1184  *
1185  * WARNING! Assumes that the kernel interlocks size changes at the
1186  *	    vnode level.
1187  *
1188  * WARNING! Caller assumes responsibility for removing dead blocks
1189  *	    if INODE_RESIZED is set.
1190  */
1191 static
1192 void
1193 hammer2_truncate_file(hammer2_inode_t *ip, hammer2_key_t nsize)
1194 {
1195 	hammer2_key_t lbase;
1196 	int nblksize;
1197 
1198 	hammer2_mtx_unlock(&ip->lock);
1199 	if (ip->vp) {
1200 		nblksize = hammer2_calc_logical(ip, nsize, &lbase, NULL);
1201 		nvtruncbuf(ip->vp, nsize,
1202 			   nblksize, (int)nsize & (nblksize - 1),
1203 			   0);
1204 	}
1205 	hammer2_mtx_ex(&ip->lock);
1206 	KKASSERT((ip->flags & HAMMER2_INODE_RESIZED) == 0);
1207 	ip->osize = ip->meta.size;
1208 	ip->meta.size = nsize;
1209 	atomic_set_int(&ip->flags, HAMMER2_INODE_RESIZED);
1210 	hammer2_inode_modify(ip);
1211 }
1212 
1213 /*
1214  * Extend the size of a file.  The inode must be locked.
1215  *
1216  * Even though the file size is changing, we do not have to set the
1217  * INODE_RESIZED bit unless the file size crosses the EMBEDDED_BYTES
1218  * boundary.  When this occurs a hammer2_inode_chain_sync() is required
1219  * to prepare the inode cluster's indirect block table, otherwise
1220  * async execution of the strategy code will implode on us.
1221  *
1222  * WARNING! Assumes that the kernel interlocks size changes at the
1223  *	    vnode level.
1224  *
1225  * WARNING! Caller assumes responsibility for transitioning out
1226  *	    of the inode DIRECTDATA mode if INODE_RESIZED is set.
1227  */
1228 static
1229 void
1230 hammer2_extend_file(hammer2_inode_t *ip, hammer2_key_t nsize)
1231 {
1232 	hammer2_key_t lbase;
1233 	hammer2_key_t osize;
1234 	int oblksize;
1235 	int nblksize;
1236 	int error;
1237 
1238 	KKASSERT((ip->flags & HAMMER2_INODE_RESIZED) == 0);
1239 	hammer2_inode_modify(ip);
1240 	osize = ip->meta.size;
1241 	ip->osize = osize;
1242 	ip->meta.size = nsize;
1243 
1244 	/*
1245 	 * We must issue a chain_sync() when the DIRECTDATA state changes
1246 	 * to prevent confusion between the flush code and the in-memory
1247 	 * state.  This is not perfect because we are doing it outside of
1248 	 * a sync/fsync operation, so it might not be fully synchronized
1249 	 * with the meta-data topology flush.
1250 	 *
1251 	 * We must retain and re-dirty the buffer cache buffer containing
1252 	 * the direct data so it can be written to a real block.  It should
1253 	 * not be possible for a bread error to occur since the original data
1254 	 * is extracted from the inode structure directly.
1255 	 */
1256 	if (osize <= HAMMER2_EMBEDDED_BYTES && nsize > HAMMER2_EMBEDDED_BYTES) {
1257 		if (osize) {
1258 			struct buf *bp;
1259 
1260 			oblksize = hammer2_calc_logical(ip, 0, NULL, NULL);
1261 			error = bread_kvabio(ip->vp, 0, oblksize, &bp);
1262 			atomic_set_int(&ip->flags, HAMMER2_INODE_RESIZED);
1263 			hammer2_inode_chain_sync(ip);
1264 			if (error == 0) {
1265 				bheavy(bp);
1266 				bdwrite(bp);
1267 			} else {
1268 				brelse(bp);
1269 			}
1270 		} else {
1271 			atomic_set_int(&ip->flags, HAMMER2_INODE_RESIZED);
1272 			hammer2_inode_chain_sync(ip);
1273 		}
1274 	}
1275 	hammer2_mtx_unlock(&ip->lock);
1276 	if (ip->vp) {
1277 		oblksize = hammer2_calc_logical(ip, osize, &lbase, NULL);
1278 		nblksize = hammer2_calc_logical(ip, nsize, &lbase, NULL);
1279 		nvextendbuf(ip->vp,
1280 			    osize, nsize,
1281 			    oblksize, nblksize,
1282 			    -1, -1, 0);
1283 	}
1284 	hammer2_mtx_ex(&ip->lock);
1285 }
1286 
1287 static
1288 int
1289 hammer2_vop_nresolve(struct vop_nresolve_args *ap)
1290 {
1291 	hammer2_xop_nresolve_t *xop;
1292 	hammer2_inode_t *ip;
1293 	hammer2_inode_t *dip;
1294 	struct namecache *ncp;
1295 	struct vnode *vp;
1296 	int error;
1297 
1298 	dip = VTOI(ap->a_dvp);
1299 	xop = hammer2_xop_alloc(dip, 0);
1300 
1301 	ncp = ap->a_nch->ncp;
1302 	hammer2_xop_setname(&xop->head, ncp->nc_name, ncp->nc_nlen);
1303 
1304 	/*
1305 	 * Note: In DragonFly the kernel handles '.' and '..'.
1306 	 */
1307 	hammer2_inode_lock(dip, HAMMER2_RESOLVE_SHARED);
1308 	hammer2_xop_start(&xop->head, &hammer2_nresolve_desc);
1309 
1310 	error = hammer2_xop_collect(&xop->head, 0);
1311 	error = hammer2_error_to_errno(error);
1312 	if (error) {
1313 		ip = NULL;
1314 	} else {
1315 		ip = hammer2_inode_get(dip->pmp, &xop->head, -1, -1);
1316 	}
1317 	hammer2_inode_unlock(dip);
1318 
1319 	/*
1320 	 * Acquire the related vnode
1321 	 *
1322 	 * NOTE: For error processing, only ENOENT resolves the namecache
1323 	 *	 entry to NULL, otherwise we just return the error and
1324 	 *	 leave the namecache unresolved.
1325 	 *
1326 	 * NOTE: multiple hammer2_inode structures can be aliased to the
1327 	 *	 same chain element, for example for hardlinks.  This
1328 	 *	 use case does not 'reattach' inode associations that
1329 	 *	 might already exist, but always allocates a new one.
1330 	 *
1331 	 * WARNING: inode structure is locked exclusively via inode_get
1332 	 *	    but chain was locked shared.  inode_unlock()
1333 	 *	    will handle it properly.
1334 	 */
1335 	if (ip) {
1336 		vp = hammer2_igetv(ip, &error);	/* error set to UNIX error */
1337 		if (error == 0) {
1338 			vn_unlock(vp);
1339 			cache_setvp(ap->a_nch, vp);
1340 		} else if (error == ENOENT) {
1341 			cache_setvp(ap->a_nch, NULL);
1342 		}
1343 		hammer2_inode_unlock(ip);
1344 
1345 		/*
1346 		 * The vp should not be released until after we've disposed
1347 		 * of our locks, because it might cause vop_inactive() to
1348 		 * be called.
1349 		 */
1350 		if (vp)
1351 			vrele(vp);
1352 	} else {
1353 		error = ENOENT;
1354 		cache_setvp(ap->a_nch, NULL);
1355 	}
1356 	hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP);
1357 	KASSERT(error || ap->a_nch->ncp->nc_vp != NULL,
1358 		("resolve error %d/%p ap %p\n",
1359 		 error, ap->a_nch->ncp->nc_vp, ap));
1360 
1361 	return error;
1362 }
1363 
1364 static
1365 int
1366 hammer2_vop_nlookupdotdot(struct vop_nlookupdotdot_args *ap)
1367 {
1368 	hammer2_inode_t *dip;
1369 	hammer2_tid_t inum;
1370 	int error;
1371 
1372 	dip = VTOI(ap->a_dvp);
1373 	inum = dip->meta.iparent;
1374 	*ap->a_vpp = NULL;
1375 
1376 	if (inum) {
1377 		error = hammer2_vfs_vget(ap->a_dvp->v_mount, NULL,
1378 					 inum, ap->a_vpp);
1379 	} else {
1380 		error = ENOENT;
1381 	}
1382 	return error;
1383 }
1384 
1385 static
1386 int
1387 hammer2_vop_nmkdir(struct vop_nmkdir_args *ap)
1388 {
1389 	hammer2_inode_t *dip;
1390 	hammer2_inode_t *nip;
1391 	struct namecache *ncp;
1392 	const uint8_t *name;
1393 	size_t name_len;
1394 	hammer2_tid_t inum;
1395 	int error;
1396 
1397 	dip = VTOI(ap->a_dvp);
1398 	if (dip->pmp->ronly || (dip->pmp->flags & HAMMER2_PMPF_EMERG))
1399 		return (EROFS);
1400 	if (hammer2_vfs_enospace(dip, 0, ap->a_cred) > 1)
1401 		return (ENOSPC);
1402 
1403 	ncp = ap->a_nch->ncp;
1404 	name = ncp->nc_name;
1405 	name_len = ncp->nc_nlen;
1406 
1407 	hammer2_trans_init(dip->pmp, 0);
1408 
1409 	inum = hammer2_trans_newinum(dip->pmp);
1410 
1411 	/*
1412 	 * Create the actual inode as a hidden file in the iroot, then
1413 	 * create the directory entry.  The creation of the actual inode
1414 	 * sets its nlinks to 1 which is the value we desire.
1415 	 *
1416 	 * dip must be locked before nip to avoid deadlock.
1417 	 */
1418 	hammer2_inode_lock(dip, 0);
1419 	nip = hammer2_inode_create_normal(dip, ap->a_vap, ap->a_cred,
1420 					  inum, &error);
1421 	if (error) {
1422 		error = hammer2_error_to_errno(error);
1423 	} else {
1424 		error = hammer2_dirent_create(dip, name, name_len,
1425 					      nip->meta.inum, nip->meta.type);
1426 		/* returns UNIX error code */
1427 	}
1428 	if (error) {
1429 		if (nip) {
1430 			hammer2_inode_unlink_finisher(nip, 0);
1431 			hammer2_inode_unlock(nip);
1432 			nip = NULL;
1433 		}
1434 		*ap->a_vpp = NULL;
1435 	} else {
1436 		/*
1437 		 * inode_depend() must occur before the igetv() because
1438 		 * the igetv() can temporarily release the inode lock.
1439 		 */
1440 		hammer2_inode_depend(dip, nip);	/* before igetv */
1441 		*ap->a_vpp = hammer2_igetv(nip, &error);
1442 		hammer2_inode_unlock(nip);
1443 	}
1444 
1445 	/*
1446 	 * Update dip's mtime
1447 	 *
1448 	 * We can use a shared inode lock and allow the meta.mtime update
1449 	 * SMP race.  hammer2_inode_modify() is MPSAFE w/a shared lock.
1450 	 */
1451 	if (error == 0) {
1452 		uint64_t mtime;
1453 
1454 		/*hammer2_inode_lock(dip, HAMMER2_RESOLVE_SHARED);*/
1455 		hammer2_update_time(&mtime);
1456 		hammer2_inode_modify(dip);
1457 		dip->meta.mtime = mtime;
1458 		/*hammer2_inode_unlock(dip);*/
1459 	}
1460 	hammer2_inode_unlock(dip);
1461 
1462 	hammer2_trans_done(dip->pmp, HAMMER2_TRANS_SIDEQ);
1463 
1464 	if (error == 0) {
1465 		cache_setunresolved(ap->a_nch);
1466 		cache_setvp(ap->a_nch, *ap->a_vpp);
1467 		hammer2_knote(ap->a_dvp, NOTE_WRITE | NOTE_LINK);
1468 	}
1469 	return error;
1470 }
1471 
1472 static
1473 int
1474 hammer2_vop_open(struct vop_open_args *ap)
1475 {
1476 	return vop_stdopen(ap);
1477 }
1478 
1479 /*
1480  * hammer2_vop_advlock { vp, id, op, fl, flags }
1481  */
1482 static
1483 int
1484 hammer2_vop_advlock(struct vop_advlock_args *ap)
1485 {
1486 	hammer2_inode_t *ip = VTOI(ap->a_vp);
1487 	hammer2_off_t size;
1488 
1489 	size = ip->meta.size;
1490 	return (lf_advlock(ap, &ip->advlock, size));
1491 }
1492 
1493 static
1494 int
1495 hammer2_vop_close(struct vop_close_args *ap)
1496 {
1497 	return vop_stdclose(ap);
1498 }
1499 
1500 /*
1501  * hammer2_vop_nlink { nch, dvp, vp, cred }
1502  *
1503  * Create a hardlink from (vp) to {dvp, nch}.
1504  */
1505 static
1506 int
1507 hammer2_vop_nlink(struct vop_nlink_args *ap)
1508 {
1509 	hammer2_inode_t *tdip;	/* target directory to create link in */
1510 	hammer2_inode_t *ip;	/* inode we are hardlinking to */
1511 	struct namecache *ncp;
1512 	const uint8_t *name;
1513 	size_t name_len;
1514 	int error;
1515 
1516 	if (ap->a_dvp->v_mount != ap->a_vp->v_mount)
1517 		return(EXDEV);
1518 
1519 	tdip = VTOI(ap->a_dvp);
1520 	if (tdip->pmp->ronly || (tdip->pmp->flags & HAMMER2_PMPF_EMERG))
1521 		return (EROFS);
1522 	if (hammer2_vfs_enospace(tdip, 0, ap->a_cred) > 1)
1523 		return (ENOSPC);
1524 
1525 	ncp = ap->a_nch->ncp;
1526 	name = ncp->nc_name;
1527 	name_len = ncp->nc_nlen;
1528 
1529 	/*
1530 	 * ip represents the file being hardlinked.  The file could be a
1531 	 * normal file or a hardlink target if it has already been hardlinked.
1532 	 * (with the new semantics, it will almost always be a hardlink
1533 	 * target).
1534 	 *
1535 	 * Bump nlinks and potentially also create or move the hardlink
1536 	 * target in the parent directory common to (ip) and (tdip).  The
1537 	 * consolidation code can modify ip->cluster.  The returned cluster
1538 	 * is locked.
1539 	 */
1540 	ip = VTOI(ap->a_vp);
1541 	KASSERT(ip->pmp, ("ip->pmp is NULL %p %p", ip, ip->pmp));
1542 	hammer2_trans_init(ip->pmp, 0);
1543 
1544 	/*
1545 	 * Target should be an indexed inode or there's no way we will ever
1546 	 * be able to find it!
1547 	 */
1548 	KKASSERT((ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE) == 0);
1549 
1550 	error = 0;
1551 
1552 	/*
1553 	 * Can return NULL and error == EXDEV if the common parent
1554 	 * crosses a directory with the xlink flag set.
1555 	 */
1556 	hammer2_inode_lock4(tdip, ip, NULL, NULL);
1557 
1558 	/*
1559 	 * Create the directory entry and bump nlinks.
1560 	 */
1561 	if (error == 0) {
1562 		error = hammer2_dirent_create(tdip, name, name_len,
1563 					      ip->meta.inum, ip->meta.type);
1564 		hammer2_inode_modify(ip);
1565 		++ip->meta.nlinks;
1566 	}
1567 	if (error == 0) {
1568 		/*
1569 		 * Update dip's mtime
1570 		 */
1571 		uint64_t mtime;
1572 
1573 		hammer2_update_time(&mtime);
1574 		hammer2_inode_modify(tdip);
1575 		tdip->meta.mtime = mtime;
1576 
1577 		cache_setunresolved(ap->a_nch);
1578 		cache_setvp(ap->a_nch, ap->a_vp);
1579 	}
1580 	hammer2_inode_unlock(ip);
1581 	hammer2_inode_unlock(tdip);
1582 
1583 	hammer2_trans_done(ip->pmp, HAMMER2_TRANS_SIDEQ);
1584 	hammer2_knote(ap->a_vp, NOTE_LINK);
1585 	hammer2_knote(ap->a_dvp, NOTE_WRITE);
1586 
1587 	return error;
1588 }
1589 
1590 /*
1591  * hammer2_vop_ncreate { nch, dvp, vpp, cred, vap }
1592  *
1593  * The operating system has already ensured that the directory entry
1594  * does not exist and done all appropriate namespace locking.
1595  */
1596 static
1597 int
1598 hammer2_vop_ncreate(struct vop_ncreate_args *ap)
1599 {
1600 	hammer2_inode_t *dip;
1601 	hammer2_inode_t *nip;
1602 	struct namecache *ncp;
1603 	const uint8_t *name;
1604 	size_t name_len;
1605 	hammer2_tid_t inum;
1606 	int error;
1607 
1608 	dip = VTOI(ap->a_dvp);
1609 	if (dip->pmp->ronly || (dip->pmp->flags & HAMMER2_PMPF_EMERG))
1610 		return (EROFS);
1611 	if (hammer2_vfs_enospace(dip, 0, ap->a_cred) > 1)
1612 		return (ENOSPC);
1613 
1614 	ncp = ap->a_nch->ncp;
1615 	name = ncp->nc_name;
1616 	name_len = ncp->nc_nlen;
1617 	hammer2_trans_init(dip->pmp, 0);
1618 
1619 	inum = hammer2_trans_newinum(dip->pmp);
1620 
1621 	/*
1622 	 * Create the actual inode as a hidden file in the iroot, then
1623 	 * create the directory entry.  The creation of the actual inode
1624 	 * sets its nlinks to 1 which is the value we desire.
1625 	 *
1626 	 * dip must be locked before nip to avoid deadlock.
1627 	 */
1628 	hammer2_inode_lock(dip, 0);
1629 	nip = hammer2_inode_create_normal(dip, ap->a_vap, ap->a_cred,
1630 					  inum, &error);
1631 
1632 	if (error) {
1633 		error = hammer2_error_to_errno(error);
1634 	} else {
1635 		error = hammer2_dirent_create(dip, name, name_len,
1636 					      nip->meta.inum, nip->meta.type);
1637 	}
1638 	if (error) {
1639 		if (nip) {
1640 			hammer2_inode_unlink_finisher(nip, 0);
1641 			hammer2_inode_unlock(nip);
1642 			nip = NULL;
1643 		}
1644 		*ap->a_vpp = NULL;
1645 	} else {
1646 		hammer2_inode_depend(dip, nip);	/* before igetv */
1647 		*ap->a_vpp = hammer2_igetv(nip, &error);
1648 		hammer2_inode_unlock(nip);
1649 	}
1650 
1651 	/*
1652 	 * Update dip's mtime
1653 	 */
1654 	if (error == 0) {
1655 		uint64_t mtime;
1656 
1657 		/*hammer2_inode_lock(dip, HAMMER2_RESOLVE_SHARED);*/
1658 		hammer2_update_time(&mtime);
1659 		hammer2_inode_modify(dip);
1660 		dip->meta.mtime = mtime;
1661 		/*hammer2_inode_unlock(dip);*/
1662 	}
1663 	hammer2_inode_unlock(dip);
1664 
1665 	hammer2_trans_done(dip->pmp, HAMMER2_TRANS_SIDEQ);
1666 
1667 	if (error == 0) {
1668 		cache_setunresolved(ap->a_nch);
1669 		cache_setvp(ap->a_nch, *ap->a_vpp);
1670 		hammer2_knote(ap->a_dvp, NOTE_WRITE);
1671 	}
1672 	return error;
1673 }
1674 
1675 /*
1676  * Make a device node (typically a fifo)
1677  */
1678 static
1679 int
1680 hammer2_vop_nmknod(struct vop_nmknod_args *ap)
1681 {
1682 	hammer2_inode_t *dip;
1683 	hammer2_inode_t *nip;
1684 	struct namecache *ncp;
1685 	const uint8_t *name;
1686 	size_t name_len;
1687 	hammer2_tid_t inum;
1688 	int error;
1689 
1690 	dip = VTOI(ap->a_dvp);
1691 	if (dip->pmp->ronly || (dip->pmp->flags & HAMMER2_PMPF_EMERG))
1692 		return (EROFS);
1693 	if (hammer2_vfs_enospace(dip, 0, ap->a_cred) > 1)
1694 		return (ENOSPC);
1695 
1696 	ncp = ap->a_nch->ncp;
1697 	name = ncp->nc_name;
1698 	name_len = ncp->nc_nlen;
1699 	hammer2_trans_init(dip->pmp, 0);
1700 
1701 	/*
1702 	 * Create the device inode and then create the directory entry.
1703 	 *
1704 	 * dip must be locked before nip to avoid deadlock.
1705 	 */
1706 	inum = hammer2_trans_newinum(dip->pmp);
1707 
1708 	hammer2_inode_lock(dip, 0);
1709 	nip = hammer2_inode_create_normal(dip, ap->a_vap, ap->a_cred,
1710 					  inum, &error);
1711 	if (error == 0) {
1712 		error = hammer2_dirent_create(dip, name, name_len,
1713 					      nip->meta.inum, nip->meta.type);
1714 	}
1715 	if (error) {
1716 		if (nip) {
1717 			hammer2_inode_unlink_finisher(nip, 0);
1718 			hammer2_inode_unlock(nip);
1719 			nip = NULL;
1720 		}
1721 		*ap->a_vpp = NULL;
1722 	} else {
1723 		hammer2_inode_depend(dip, nip);	/* before igetv */
1724 		*ap->a_vpp = hammer2_igetv(nip, &error);
1725 		hammer2_inode_unlock(nip);
1726 	}
1727 
1728 	/*
1729 	 * Update dip's mtime
1730 	 */
1731 	if (error == 0) {
1732 		uint64_t mtime;
1733 
1734 		/*hammer2_inode_lock(dip, HAMMER2_RESOLVE_SHARED);*/
1735 		hammer2_update_time(&mtime);
1736 		hammer2_inode_modify(dip);
1737 		dip->meta.mtime = mtime;
1738 		/*hammer2_inode_unlock(dip);*/
1739 	}
1740 	hammer2_inode_unlock(dip);
1741 
1742 	hammer2_trans_done(dip->pmp, HAMMER2_TRANS_SIDEQ);
1743 
1744 	if (error == 0) {
1745 		cache_setunresolved(ap->a_nch);
1746 		cache_setvp(ap->a_nch, *ap->a_vpp);
1747 		hammer2_knote(ap->a_dvp, NOTE_WRITE);
1748 	}
1749 	return error;
1750 }
1751 
1752 /*
1753  * hammer2_vop_nsymlink { nch, dvp, vpp, cred, vap, target }
1754  */
1755 static
1756 int
1757 hammer2_vop_nsymlink(struct vop_nsymlink_args *ap)
1758 {
1759 	hammer2_inode_t *dip;
1760 	hammer2_inode_t *nip;
1761 	struct namecache *ncp;
1762 	const uint8_t *name;
1763 	size_t name_len;
1764 	hammer2_tid_t inum;
1765 	int error;
1766 
1767 	dip = VTOI(ap->a_dvp);
1768 	if (dip->pmp->ronly || (dip->pmp->flags & HAMMER2_PMPF_EMERG))
1769 		return (EROFS);
1770 	if (hammer2_vfs_enospace(dip, 0, ap->a_cred) > 1)
1771 		return (ENOSPC);
1772 
1773 	ncp = ap->a_nch->ncp;
1774 	name = ncp->nc_name;
1775 	name_len = ncp->nc_nlen;
1776 	hammer2_trans_init(dip->pmp, 0);
1777 
1778 	ap->a_vap->va_type = VLNK;	/* enforce type */
1779 
1780 	/*
1781 	 * Create the softlink as an inode and then create the directory
1782 	 * entry.
1783 	 *
1784 	 * dip must be locked before nip to avoid deadlock.
1785 	 */
1786 	inum = hammer2_trans_newinum(dip->pmp);
1787 
1788 	hammer2_inode_lock(dip, 0);
1789 	nip = hammer2_inode_create_normal(dip, ap->a_vap, ap->a_cred,
1790 					  inum, &error);
1791 	if (error == 0) {
1792 		error = hammer2_dirent_create(dip, name, name_len,
1793 					      nip->meta.inum, nip->meta.type);
1794 	}
1795 	if (error) {
1796 		if (nip) {
1797 			hammer2_inode_unlink_finisher(nip, 0);
1798 			hammer2_inode_unlock(nip);
1799 			nip = NULL;
1800 		}
1801 		*ap->a_vpp = NULL;
1802 		hammer2_inode_unlock(dip);
1803 		hammer2_trans_done(dip->pmp, HAMMER2_TRANS_SIDEQ);
1804 		return error;
1805 	}
1806 	hammer2_inode_depend(dip, nip);	/* before igetv */
1807 	*ap->a_vpp = hammer2_igetv(nip, &error);
1808 
1809 	/*
1810 	 * Build the softlink (~like file data) and finalize the namecache.
1811 	 */
1812 	if (error == 0) {
1813 		size_t bytes;
1814 		struct uio auio;
1815 		struct iovec aiov;
1816 
1817 		bytes = strlen(ap->a_target);
1818 
1819 		hammer2_inode_unlock(nip);
1820 		bzero(&auio, sizeof(auio));
1821 		bzero(&aiov, sizeof(aiov));
1822 		auio.uio_iov = &aiov;
1823 		auio.uio_segflg = UIO_SYSSPACE;
1824 		auio.uio_rw = UIO_WRITE;
1825 		auio.uio_resid = bytes;
1826 		auio.uio_iovcnt = 1;
1827 		auio.uio_td = curthread;
1828 		aiov.iov_base = ap->a_target;
1829 		aiov.iov_len = bytes;
1830 		error = hammer2_write_file(nip, &auio, IO_APPEND, 0);
1831 		/* XXX handle error */
1832 		error = 0;
1833 	} else {
1834 		hammer2_inode_unlock(nip);
1835 	}
1836 
1837 	/*
1838 	 * Update dip's mtime
1839 	 */
1840 	if (error == 0) {
1841 		uint64_t mtime;
1842 
1843 		/*hammer2_inode_lock(dip, HAMMER2_RESOLVE_SHARED);*/
1844 		hammer2_update_time(&mtime);
1845 		hammer2_inode_modify(dip);
1846 		dip->meta.mtime = mtime;
1847 		/*hammer2_inode_unlock(dip);*/
1848 	}
1849 	hammer2_inode_unlock(dip);
1850 
1851 	hammer2_trans_done(dip->pmp, HAMMER2_TRANS_SIDEQ);
1852 
1853 	/*
1854 	 * Finalize namecache
1855 	 */
1856 	if (error == 0) {
1857 		cache_setunresolved(ap->a_nch);
1858 		cache_setvp(ap->a_nch, *ap->a_vpp);
1859 		hammer2_knote(ap->a_dvp, NOTE_WRITE);
1860 	}
1861 	return error;
1862 }
1863 
1864 /*
1865  * hammer2_vop_nremove { nch, dvp, cred }
1866  */
1867 static
1868 int
1869 hammer2_vop_nremove(struct vop_nremove_args *ap)
1870 {
1871 	hammer2_xop_unlink_t *xop;
1872 	hammer2_inode_t *dip;
1873 	hammer2_inode_t *ip;
1874 	struct namecache *ncp;
1875 	int error;
1876 	int isopen;
1877 
1878 	dip = VTOI(ap->a_dvp);
1879 	if (dip->pmp->ronly)
1880 		return (EROFS);
1881 #if 0
1882 	/* allow removals, except user to also bulkfree */
1883 	if (hammer2_vfs_enospace(dip, 0, ap->a_cred) > 1)
1884 		return (ENOSPC);
1885 #endif
1886 
1887 	ncp = ap->a_nch->ncp;
1888 
1889 	if (hammer2_debug_inode && dip->meta.inum == hammer2_debug_inode) {
1890 		kprintf("hammer2: attempt to delete inside debug inode: %s\n",
1891 			ncp->nc_name);
1892 		while (hammer2_debug_inode &&
1893 		       dip->meta.inum == hammer2_debug_inode) {
1894 			tsleep(&hammer2_debug_inode, 0, "h2debug", hz*5);
1895 		}
1896 	}
1897 
1898 	hammer2_trans_init(dip->pmp, 0);
1899 	hammer2_inode_lock(dip, 0);
1900 
1901 	/*
1902 	 * The unlink XOP unlinks the path from the directory and
1903 	 * locates and returns the cluster associated with the real inode.
1904 	 * We have to handle nlinks here on the frontend.
1905 	 */
1906 	xop = hammer2_xop_alloc(dip, HAMMER2_XOP_MODIFYING);
1907 	hammer2_xop_setname(&xop->head, ncp->nc_name, ncp->nc_nlen);
1908 
1909 	/*
1910 	 * The namecache entry is locked so nobody can use this namespace.
1911 	 * Calculate isopen to determine if this namespace has an open vp
1912 	 * associated with it and resolve the vp only if it does.
1913 	 *
1914 	 * We try to avoid resolving the vnode if nobody has it open, but
1915 	 * note that the test is via this namespace only.
1916 	 */
1917 	isopen = cache_isopen(ap->a_nch);
1918 	xop->isdir = 0;
1919 	xop->dopermanent = 0;
1920 	hammer2_xop_start(&xop->head, &hammer2_unlink_desc);
1921 
1922 	/*
1923 	 * Collect the real inode and adjust nlinks, destroy the real
1924 	 * inode if nlinks transitions to 0 and it was the real inode
1925 	 * (else it has already been removed).
1926 	 */
1927 	error = hammer2_xop_collect(&xop->head, 0);
1928 	error = hammer2_error_to_errno(error);
1929 
1930 	if (error == 0) {
1931 		ip = hammer2_inode_get(dip->pmp, &xop->head, -1, -1);
1932 		hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP);
1933 		if (ip) {
1934 			if (hammer2_debug_inode &&
1935 			    ip->meta.inum == hammer2_debug_inode) {
1936 				kprintf("hammer2: attempt to delete debug "
1937 					"inode!\n");
1938 				while (hammer2_debug_inode &&
1939 				       ip->meta.inum == hammer2_debug_inode) {
1940 					tsleep(&hammer2_debug_inode, 0,
1941 					       "h2debug", hz*5);
1942 				}
1943 			}
1944 			hammer2_inode_unlink_finisher(ip, isopen);
1945 			hammer2_inode_depend(dip, ip); /* after modified */
1946 			hammer2_inode_unlock(ip);
1947 		}
1948 	} else {
1949 		hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP);
1950 	}
1951 
1952 	/*
1953 	 * Update dip's mtime
1954 	 */
1955 	if (error == 0) {
1956 		uint64_t mtime;
1957 
1958 		/*hammer2_inode_lock(dip, HAMMER2_RESOLVE_SHARED);*/
1959 		hammer2_update_time(&mtime);
1960 		hammer2_inode_modify(dip);
1961 		dip->meta.mtime = mtime;
1962 		/*hammer2_inode_unlock(dip);*/
1963 	}
1964 	hammer2_inode_unlock(dip);
1965 
1966 	hammer2_trans_done(dip->pmp, HAMMER2_TRANS_SIDEQ);
1967 	if (error == 0) {
1968 		cache_unlink(ap->a_nch);
1969 		hammer2_knote(ap->a_dvp, NOTE_WRITE);
1970 	}
1971 	return (error);
1972 }
1973 
1974 /*
1975  * hammer2_vop_nrmdir { nch, dvp, cred }
1976  */
1977 static
1978 int
1979 hammer2_vop_nrmdir(struct vop_nrmdir_args *ap)
1980 {
1981 	hammer2_xop_unlink_t *xop;
1982 	hammer2_inode_t *dip;
1983 	hammer2_inode_t *ip;
1984 	struct namecache *ncp;
1985 	int isopen;
1986 	int error;
1987 
1988 	dip = VTOI(ap->a_dvp);
1989 	if (dip->pmp->ronly)
1990 		return (EROFS);
1991 #if 0
1992 	/* allow removals, except user to also bulkfree */
1993 	if (hammer2_vfs_enospace(dip, 0, ap->a_cred) > 1)
1994 		return (ENOSPC);
1995 #endif
1996 
1997 	hammer2_trans_init(dip->pmp, 0);
1998 	hammer2_inode_lock(dip, 0);
1999 
2000 	xop = hammer2_xop_alloc(dip, HAMMER2_XOP_MODIFYING);
2001 
2002 	ncp = ap->a_nch->ncp;
2003 	hammer2_xop_setname(&xop->head, ncp->nc_name, ncp->nc_nlen);
2004 	isopen = cache_isopen(ap->a_nch);
2005 	xop->isdir = 1;
2006 	xop->dopermanent = 0;
2007 	hammer2_xop_start(&xop->head, &hammer2_unlink_desc);
2008 
2009 	/*
2010 	 * Collect the real inode and adjust nlinks, destroy the real
2011 	 * inode if nlinks transitions to 0 and it was the real inode
2012 	 * (else it has already been removed).
2013 	 */
2014 	error = hammer2_xop_collect(&xop->head, 0);
2015 	error = hammer2_error_to_errno(error);
2016 
2017 	if (error == 0) {
2018 		ip = hammer2_inode_get(dip->pmp, &xop->head, -1, -1);
2019 		hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP);
2020 		if (ip) {
2021 			hammer2_inode_unlink_finisher(ip, isopen);
2022 			hammer2_inode_depend(dip, ip);	/* after modified */
2023 			hammer2_inode_unlock(ip);
2024 		}
2025 	} else {
2026 		hammer2_xop_retire(&xop->head, HAMMER2_XOPMASK_VOP);
2027 	}
2028 
2029 	/*
2030 	 * Update dip's mtime
2031 	 */
2032 	if (error == 0) {
2033 		uint64_t mtime;
2034 
2035 		/*hammer2_inode_lock(dip, HAMMER2_RESOLVE_SHARED);*/
2036 		hammer2_update_time(&mtime);
2037 		hammer2_inode_modify(dip);
2038 		dip->meta.mtime = mtime;
2039 		/*hammer2_inode_unlock(dip);*/
2040 	}
2041 	hammer2_inode_unlock(dip);
2042 
2043 	hammer2_trans_done(dip->pmp, HAMMER2_TRANS_SIDEQ);
2044 	if (error == 0) {
2045 		cache_unlink(ap->a_nch);
2046 		hammer2_knote(ap->a_dvp, NOTE_WRITE | NOTE_LINK);
2047 	}
2048 	return (error);
2049 }
2050 
2051 /*
2052  * hammer2_vop_nrename { fnch, tnch, fdvp, tdvp, cred }
2053  */
2054 static
2055 int
2056 hammer2_vop_nrename(struct vop_nrename_args *ap)
2057 {
2058 	struct namecache *fncp;
2059 	struct namecache *tncp;
2060 	hammer2_inode_t *fdip;	/* source directory */
2061 	hammer2_inode_t *tdip;	/* target directory */
2062 	hammer2_inode_t *ip;	/* file being renamed */
2063 	hammer2_inode_t *tip;	/* replaced target during rename or NULL */
2064 	const uint8_t *fname;
2065 	size_t fname_len;
2066 	const uint8_t *tname;
2067 	size_t tname_len;
2068 	int error;
2069 	int update_tdip;
2070 	int update_fdip;
2071 	hammer2_key_t tlhc;
2072 
2073 	if (ap->a_fdvp->v_mount != ap->a_tdvp->v_mount)
2074 		return(EXDEV);
2075 	if (ap->a_fdvp->v_mount != ap->a_fnch->ncp->nc_vp->v_mount)
2076 		return(EXDEV);
2077 
2078 	fdip = VTOI(ap->a_fdvp);	/* source directory */
2079 	tdip = VTOI(ap->a_tdvp);	/* target directory */
2080 
2081 	if (fdip->pmp->ronly || (fdip->pmp->flags & HAMMER2_PMPF_EMERG))
2082 		return (EROFS);
2083 	if (hammer2_vfs_enospace(fdip, 0, ap->a_cred) > 1)
2084 		return (ENOSPC);
2085 
2086 	fncp = ap->a_fnch->ncp;		/* entry name in source */
2087 	fname = fncp->nc_name;
2088 	fname_len = fncp->nc_nlen;
2089 
2090 	tncp = ap->a_tnch->ncp;		/* entry name in target */
2091 	tname = tncp->nc_name;
2092 	tname_len = tncp->nc_nlen;
2093 
2094 	hammer2_trans_init(tdip->pmp, 0);
2095 
2096 	update_tdip = 0;
2097 	update_fdip = 0;
2098 
2099 	ip = VTOI(fncp->nc_vp);
2100 	hammer2_inode_ref(ip);		/* extra ref */
2101 
2102 	/*
2103 	 * Lookup the target name to determine if a directory entry
2104 	 * is being overwritten.  We only hold related inode locks
2105 	 * temporarily, the operating system is expected to protect
2106 	 * against rename races.
2107 	 */
2108 	tip = tncp->nc_vp ? VTOI(tncp->nc_vp) : NULL;
2109 	if (tip)
2110 		hammer2_inode_ref(tip);	/* extra ref */
2111 
2112 	/*
2113 	 * Can return NULL and error == EXDEV if the common parent
2114 	 * crosses a directory with the xlink flag set.
2115 	 *
2116 	 * For now try to avoid deadlocks with a simple pointer address
2117 	 * test.  (tip) can be NULL.
2118 	 */
2119 	error = 0;
2120 	{
2121 		hammer2_inode_t *ip1 = fdip;
2122 		hammer2_inode_t *ip2 = tdip;
2123 		hammer2_inode_t *ip3 = ip;
2124 		hammer2_inode_t *ip4 = tip;	/* may be NULL */
2125 
2126 		if (fdip > tdip) {
2127 			ip1 = tdip;
2128 			ip2 = fdip;
2129 		}
2130 		if (tip && ip > tip) {
2131 			ip3 = tip;
2132 			ip4 = ip;
2133 		}
2134 		hammer2_inode_lock4(ip1, ip2, ip3, ip4);
2135 	}
2136 
2137 	/*
2138 	 * Resolve the collision space for (tdip, tname, tname_len)
2139 	 *
2140 	 * tdip must be held exclusively locked to prevent races since
2141 	 * multiple filenames can end up in the same collision space.
2142 	 */
2143 	{
2144 		hammer2_xop_scanlhc_t *sxop;
2145 		hammer2_tid_t lhcbase;
2146 
2147 		tlhc = hammer2_dirhash(tname, tname_len);
2148 		lhcbase = tlhc;
2149 		sxop = hammer2_xop_alloc(tdip, HAMMER2_XOP_MODIFYING);
2150 		sxop->lhc = tlhc;
2151 		hammer2_xop_start(&sxop->head, &hammer2_scanlhc_desc);
2152 		while ((error = hammer2_xop_collect(&sxop->head, 0)) == 0) {
2153 			if (tlhc != sxop->head.cluster.focus->bref.key)
2154 				break;
2155 			++tlhc;
2156 		}
2157 		error = hammer2_error_to_errno(error);
2158 		hammer2_xop_retire(&sxop->head, HAMMER2_XOPMASK_VOP);
2159 
2160 		if (error) {
2161 			if (error != ENOENT)
2162 				goto done2;
2163 			++tlhc;
2164 			error = 0;
2165 		}
2166 		if ((lhcbase ^ tlhc) & ~HAMMER2_DIRHASH_LOMASK) {
2167 			error = ENOSPC;
2168 			goto done2;
2169 		}
2170 	}
2171 
2172 	/*
2173 	 * Ready to go, issue the rename to the backend.  Note that meta-data
2174 	 * updates to the related inodes occur separately from the rename
2175 	 * operation.
2176 	 *
2177 	 * NOTE: While it is not necessary to update ip->meta.name*, doing
2178 	 *	 so aids catastrophic recovery and debugging.
2179 	 */
2180 	if (error == 0) {
2181 		hammer2_xop_nrename_t *xop4;
2182 
2183 		xop4 = hammer2_xop_alloc(fdip, HAMMER2_XOP_MODIFYING);
2184 		xop4->lhc = tlhc;
2185 		xop4->ip_key = ip->meta.name_key;
2186 		hammer2_xop_setip2(&xop4->head, ip);
2187 		hammer2_xop_setip3(&xop4->head, tdip);
2188 		hammer2_xop_setname(&xop4->head, fname, fname_len);
2189 		hammer2_xop_setname2(&xop4->head, tname, tname_len);
2190 		hammer2_xop_start(&xop4->head, &hammer2_nrename_desc);
2191 
2192 		error = hammer2_xop_collect(&xop4->head, 0);
2193 		error = hammer2_error_to_errno(error);
2194 		hammer2_xop_retire(&xop4->head, HAMMER2_XOPMASK_VOP);
2195 
2196 		if (error == ENOENT)
2197 			error = 0;
2198 
2199 		/*
2200 		 * Update inode meta-data.
2201 		 *
2202 		 * WARNING!  The in-memory inode (ip) structure does not
2203 		 *	     maintain a copy of the inode's filename buffer.
2204 		 */
2205 		if (error == 0 &&
2206 		    (ip->meta.name_key & HAMMER2_DIRHASH_VISIBLE)) {
2207 			hammer2_inode_modify(ip);
2208 			ip->meta.name_len = tname_len;
2209 			ip->meta.name_key = tlhc;
2210 		}
2211 		if (error == 0) {
2212 			hammer2_inode_modify(ip);
2213 			ip->meta.iparent = tdip->meta.inum;
2214 		}
2215 		update_fdip = 1;
2216 		update_tdip = 1;
2217 	}
2218 
2219 done2:
2220 	/*
2221 	 * If no error, the backend has replaced the target directory entry.
2222 	 * We must adjust nlinks on the original replace target if it exists.
2223 	 */
2224 	if (error == 0 && tip) {
2225 		int isopen;
2226 
2227 		isopen = cache_isopen(ap->a_tnch);
2228 		hammer2_inode_unlink_finisher(tip, isopen);
2229 	}
2230 
2231 	/*
2232 	 * Update directory mtimes to represent the something changed.
2233 	 */
2234 	if (update_fdip || update_tdip) {
2235 		uint64_t mtime;
2236 
2237 		hammer2_update_time(&mtime);
2238 		if (update_fdip) {
2239 			hammer2_inode_modify(fdip);
2240 			fdip->meta.mtime = mtime;
2241 		}
2242 		if (update_tdip) {
2243 			hammer2_inode_modify(tdip);
2244 			tdip->meta.mtime = mtime;
2245 		}
2246 	}
2247 	if (tip) {
2248 		hammer2_inode_unlock(tip);
2249 		hammer2_inode_drop(tip);
2250 	}
2251 	hammer2_inode_unlock(ip);
2252 	hammer2_inode_unlock(tdip);
2253 	hammer2_inode_unlock(fdip);
2254 	hammer2_inode_drop(ip);
2255 	hammer2_trans_done(tdip->pmp, HAMMER2_TRANS_SIDEQ);
2256 
2257 	/*
2258 	 * Issue the namecache update after unlocking all the internal
2259 	 * hammer2 structures, otherwise we might deadlock.
2260 	 *
2261 	 * WARNING! The target namespace must be updated atomically,
2262 	 *	    and we depend on cache_rename() to handle that for
2263 	 *	    us.  Do not do a separate cache_unlink() because
2264 	 *	    that leaves a small window of opportunity for other
2265 	 *	    threads to allocate the target namespace before we
2266 	 *	    manage to complete our rename.
2267 	 *
2268 	 * WARNING! cache_rename() (and cache_unlink()) will properly
2269 	 *	    set VREF_FINALIZE on any attached vnode.  Do not
2270 	 *	    call cache_setunresolved() manually before-hand as
2271 	 *	    this will prevent the flag from being set later via
2272 	 *	    cache_rename().  If VREF_FINALIZE is not properly set
2273 	 *	    and the inode is no longer in the topology, related
2274 	 *	    chains can remain dirty indefinitely.
2275 	 */
2276 	if (error == 0 && tip) {
2277 		/*cache_unlink(ap->a_tnch); see above */
2278 		/*cache_setunresolved(ap->a_tnch); see above */
2279 	}
2280 	if (error == 0) {
2281 		cache_rename(ap->a_fnch, ap->a_tnch);
2282 		hammer2_knote(ap->a_fdvp, NOTE_WRITE);
2283 		hammer2_knote(ap->a_tdvp, NOTE_WRITE);
2284 		hammer2_knote(fncp->nc_vp, NOTE_RENAME);
2285 	}
2286 
2287 	return (error);
2288 }
2289 
2290 /*
2291  * hammer2_vop_ioctl { vp, command, data, fflag, cred }
2292  */
2293 static
2294 int
2295 hammer2_vop_ioctl(struct vop_ioctl_args *ap)
2296 {
2297 	hammer2_inode_t *ip;
2298 	int error;
2299 
2300 	ip = VTOI(ap->a_vp);
2301 
2302 	error = hammer2_ioctl(ip, ap->a_command, (void *)ap->a_data,
2303 			      ap->a_fflag, ap->a_cred);
2304 	return (error);
2305 }
2306 
2307 static
2308 int
2309 hammer2_vop_mountctl(struct vop_mountctl_args *ap)
2310 {
2311 	struct mount *mp;
2312 	hammer2_pfs_t *pmp;
2313 	int rc;
2314 
2315 	switch (ap->a_op) {
2316 	case (MOUNTCTL_SET_EXPORT):
2317 		mp = ap->a_head.a_ops->head.vv_mount;
2318 		pmp = MPTOPMP(mp);
2319 
2320 		if (ap->a_ctllen != sizeof(struct export_args))
2321 			rc = (EINVAL);
2322 		else
2323 			rc = vfs_export(mp, &pmp->export,
2324 					(const struct export_args *)ap->a_ctl);
2325 		break;
2326 	default:
2327 		rc = vop_stdmountctl(ap);
2328 		break;
2329 	}
2330 	return (rc);
2331 }
2332 
2333 /*
2334  * KQFILTER
2335  */
2336 static void filt_hammer2detach(struct knote *kn);
2337 static int filt_hammer2read(struct knote *kn, long hint);
2338 static int filt_hammer2write(struct knote *kn, long hint);
2339 static int filt_hammer2vnode(struct knote *kn, long hint);
2340 
2341 static struct filterops hammer2read_filtops =
2342 	{ FILTEROP_ISFD | FILTEROP_MPSAFE,
2343 	  NULL, filt_hammer2detach, filt_hammer2read };
2344 static struct filterops hammer2write_filtops =
2345 	{ FILTEROP_ISFD | FILTEROP_MPSAFE,
2346 	  NULL, filt_hammer2detach, filt_hammer2write };
2347 static struct filterops hammer2vnode_filtops =
2348 	{ FILTEROP_ISFD | FILTEROP_MPSAFE,
2349 	  NULL, filt_hammer2detach, filt_hammer2vnode };
2350 
2351 static
2352 int
2353 hammer2_vop_kqfilter(struct vop_kqfilter_args *ap)
2354 {
2355 	struct vnode *vp = ap->a_vp;
2356 	struct knote *kn = ap->a_kn;
2357 
2358 	switch (kn->kn_filter) {
2359 	case EVFILT_READ:
2360 		kn->kn_fop = &hammer2read_filtops;
2361 		break;
2362 	case EVFILT_WRITE:
2363 		kn->kn_fop = &hammer2write_filtops;
2364 		break;
2365 	case EVFILT_VNODE:
2366 		kn->kn_fop = &hammer2vnode_filtops;
2367 		break;
2368 	default:
2369 		return (EOPNOTSUPP);
2370 	}
2371 
2372 	kn->kn_hook = (caddr_t)vp;
2373 
2374 	knote_insert(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn);
2375 
2376 	return(0);
2377 }
2378 
2379 static void
2380 filt_hammer2detach(struct knote *kn)
2381 {
2382 	struct vnode *vp = (void *)kn->kn_hook;
2383 
2384 	knote_remove(&vp->v_pollinfo.vpi_kqinfo.ki_note, kn);
2385 }
2386 
2387 static int
2388 filt_hammer2read(struct knote *kn, long hint)
2389 {
2390 	struct vnode *vp = (void *)kn->kn_hook;
2391 	hammer2_inode_t *ip = VTOI(vp);
2392 	off_t off;
2393 
2394 	if (hint == NOTE_REVOKE) {
2395 		kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT);
2396 		return(1);
2397 	}
2398 	off = ip->meta.size - kn->kn_fp->f_offset;
2399 	kn->kn_data = (off < INTPTR_MAX) ? off : INTPTR_MAX;
2400 	if (kn->kn_sfflags & NOTE_OLDAPI)
2401 		return(1);
2402 	return (kn->kn_data != 0);
2403 }
2404 
2405 
2406 static int
2407 filt_hammer2write(struct knote *kn, long hint)
2408 {
2409 	if (hint == NOTE_REVOKE)
2410 		kn->kn_flags |= (EV_EOF | EV_NODATA | EV_ONESHOT);
2411 	kn->kn_data = 0;
2412 	return (1);
2413 }
2414 
2415 static int
2416 filt_hammer2vnode(struct knote *kn, long hint)
2417 {
2418 	if (kn->kn_sfflags & hint)
2419 		kn->kn_fflags |= hint;
2420 	if (hint == NOTE_REVOKE) {
2421 		kn->kn_flags |= (EV_EOF | EV_NODATA);
2422 		return (1);
2423 	}
2424 	return (kn->kn_fflags != 0);
2425 }
2426 
2427 /*
2428  * FIFO VOPS
2429  */
2430 static
2431 int
2432 hammer2_vop_markatime(struct vop_markatime_args *ap)
2433 {
2434 	hammer2_inode_t *ip;
2435 	struct vnode *vp;
2436 
2437 	vp = ap->a_vp;
2438 	ip = VTOI(vp);
2439 
2440 	if (ip->pmp->ronly || (ip->pmp->flags & HAMMER2_PMPF_EMERG))
2441 		return (EROFS);
2442 	return(0);
2443 }
2444 
2445 static
2446 int
2447 hammer2_vop_fifokqfilter(struct vop_kqfilter_args *ap)
2448 {
2449 	int error;
2450 
2451 	error = VOCALL(&fifo_vnode_vops, &ap->a_head);
2452 	if (error)
2453 		error = hammer2_vop_kqfilter(ap);
2454 	return(error);
2455 }
2456 
2457 /*
2458  * VOPS vector
2459  */
2460 struct vop_ops hammer2_vnode_vops = {
2461 	.vop_default	= vop_defaultop,
2462 	.vop_fsync	= hammer2_vop_fsync,
2463 	.vop_getpages	= vop_stdgetpages,
2464 	.vop_putpages	= vop_stdputpages,
2465 	.vop_access	= hammer2_vop_access,
2466 	.vop_advlock	= hammer2_vop_advlock,
2467 	.vop_close	= hammer2_vop_close,
2468 	.vop_nlink	= hammer2_vop_nlink,
2469 	.vop_ncreate	= hammer2_vop_ncreate,
2470 	.vop_nsymlink	= hammer2_vop_nsymlink,
2471 	.vop_nremove	= hammer2_vop_nremove,
2472 	.vop_nrmdir	= hammer2_vop_nrmdir,
2473 	.vop_nrename	= hammer2_vop_nrename,
2474 	.vop_getattr	= hammer2_vop_getattr,
2475 	.vop_setattr	= hammer2_vop_setattr,
2476 	.vop_readdir	= hammer2_vop_readdir,
2477 	.vop_readlink	= hammer2_vop_readlink,
2478 	.vop_read	= hammer2_vop_read,
2479 	.vop_write	= hammer2_vop_write,
2480 	.vop_open	= hammer2_vop_open,
2481 	.vop_inactive	= hammer2_vop_inactive,
2482 	.vop_reclaim 	= hammer2_vop_reclaim,
2483 	.vop_nresolve	= hammer2_vop_nresolve,
2484 	.vop_nlookupdotdot = hammer2_vop_nlookupdotdot,
2485 	.vop_nmkdir 	= hammer2_vop_nmkdir,
2486 	.vop_nmknod 	= hammer2_vop_nmknod,
2487 	.vop_ioctl	= hammer2_vop_ioctl,
2488 	.vop_mountctl	= hammer2_vop_mountctl,
2489 	.vop_bmap	= hammer2_vop_bmap,
2490 	.vop_strategy	= hammer2_vop_strategy,
2491         .vop_kqfilter	= hammer2_vop_kqfilter
2492 };
2493 
2494 struct vop_ops hammer2_spec_vops = {
2495         .vop_default =          vop_defaultop,
2496         .vop_fsync =            hammer2_vop_fsync,
2497         .vop_read =             vop_stdnoread,
2498         .vop_write =            vop_stdnowrite,
2499         .vop_access =           hammer2_vop_access,
2500         .vop_close =            hammer2_vop_close,
2501         .vop_markatime =        hammer2_vop_markatime,
2502         .vop_getattr =          hammer2_vop_getattr,
2503         .vop_inactive =         hammer2_vop_inactive,
2504         .vop_reclaim =          hammer2_vop_reclaim,
2505         .vop_setattr =          hammer2_vop_setattr
2506 };
2507 
2508 struct vop_ops hammer2_fifo_vops = {
2509         .vop_default =          fifo_vnoperate,
2510         .vop_fsync =            hammer2_vop_fsync,
2511 #if 0
2512         .vop_read =             hammer2_vop_fiforead,
2513         .vop_write =            hammer2_vop_fifowrite,
2514 #endif
2515         .vop_access =           hammer2_vop_access,
2516 #if 0
2517         .vop_close =            hammer2_vop_fifoclose,
2518 #endif
2519         .vop_markatime =        hammer2_vop_markatime,
2520         .vop_getattr =          hammer2_vop_getattr,
2521         .vop_inactive =         hammer2_vop_inactive,
2522         .vop_reclaim =          hammer2_vop_reclaim,
2523         .vop_setattr =          hammer2_vop_setattr,
2524         .vop_kqfilter =         hammer2_vop_fifokqfilter
2525 };
2526 
2527