2 * Copyright (c) 2011-2012 The DragonFly Project. All rights reserved.
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>
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
18 * 3. Neither the name of The DragonFly Project nor the names of its
19 * contributors may be used to endorse or promote products derived
20 * from this software without specific, prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
30 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
31 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
32 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/cdefs.h>
36 #include <sys/cdefs.h>
37 #include <sys/param.h>
38 #include <sys/systm.h>
39 #include <sys/types.h>
48 * HAMMER2 offers shared locks, update locks, and exclusive locks on inodes.
50 * Shared locks allow concurrent access to an inode's fields, but exclude
51 * access by concurrent exclusive locks.
53 * Update locks are interesting -- an update lock will be taken after all
54 * shared locks on an inode are released, but once it is in place, shared
55 * locks may proceed. The update field is signalled by a busy flag in the
56 * inode. Only one update lock may be in place at a given time on an inode.
58 * Exclusive locks prevent concurrent access to the inode.
60 * XXX: What do we use each for? How is visibility to the inode controlled?
64 hammer2_inode_lock_sh(struct hammer2_inode *ip)
66 lockmgr(&ip->lk, LK_SHARED);
70 hammer2_inode_lock_up(struct hammer2_inode *ip)
72 lockmgr(&ip->lk, LK_EXCLUSIVE);
74 lockmgr(&ip->lk, LK_DOWNGRADE);
78 hammer2_inode_lock_ex(struct hammer2_inode *ip)
80 lockmgr(&ip->lk, LK_EXCLUSIVE);
84 hammer2_inode_unlock_ex(struct hammer2_inode *ip)
86 lockmgr(&ip->lk, LK_RELEASE);
90 hammer2_inode_unlock_up(struct hammer2_inode *ip)
92 lockmgr(&ip->lk, LK_UPGRADE);
94 lockmgr(&ip->lk, LK_RELEASE);
98 hammer2_inode_unlock_sh(struct hammer2_inode *ip)
100 lockmgr(&ip->lk, LK_RELEASE);
108 hammer2_mount_exlock(struct hammer2_mount *hmp)
110 lockmgr(&hmp->hm_lk, LK_EXCLUSIVE);
114 hammer2_mount_shlock(struct hammer2_mount *hmp)
116 lockmgr(&hmp->hm_lk, LK_SHARED);
120 hammer2_mount_unlock(struct hammer2_mount *hmp)
122 lockmgr(&hmp->hm_lk, LK_RELEASE);
126 * Inode/vnode subroutines
132 * Get a vnode associated with the given inode. If one exists, return it,
133 * locked and ref-ed. Otherwise, a new vnode is allocated and associated
136 * The lock prevents the inode from being reclaimed, I believe (XXX)
139 igetv(struct hammer2_inode *ip, int *error)
142 struct hammer2_mount *hmp;
149 tsleep(&igetv, 0, "", hz * 10);
151 hammer2_inode_lock_ex(ip);
153 /* Reuse existing vnode */
156 /* XXX: Is this necessary? */
161 /* Allocate and initialize a new vnode */
162 rc = getnewvnode(VT_HAMMER2, H2TOMP(hmp), &vp,
163 VLKTIMEOUT, LK_CANRECURSE);
169 kprintf("igetv new\n");
170 switch (ip->type & HAMMER2_INODE_TYPE_MASK) {
171 case HAMMER2_INODE_TYPE_DIR:
174 case HAMMER2_INODE_TYPE_FILE:
176 /*XXX: Init w/ true file size; 0*/
177 vinitvmio(vp, 0, PAGE_SIZE, -1);
183 if (ip->type & HAMMER2_INODE_TYPE_ROOT)
184 vsetflags(vp, VROOT);
189 hammer2_inode_unlock_ex(ip);
192 * XXX: Under what conditions can a vnode be reclaimed? How do we want
193 * to interlock against vreclaim calls into hammer2? When do we need to?
196 kprintf("igetv exit\n");
198 /* vp is either NULL or a locked, ref-ed vnode referring to inode ip */
206 * Allocate an inode in a HAMMER2 mount. The returned inode is locked
207 * exclusively. The HAMMER2 mountpoint must be locked on entry.
209 struct hammer2_inode *
210 alloci(struct hammer2_mount *hmp)
212 struct hammer2_inode *ip;
216 ip = kmalloc(sizeof(struct hammer2_inode), hmp->hm_inodes,
226 lockinit(&ip->lk, "h2inode", 0, 0);
229 hammer2_inode_lock_ex(ip);