2 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.1 2007/11/01 20:53:05 dillon Exp $
41 static enum vtype hammer_get_vnode_type(u_int16_t obj_type);
44 hammer_vop_inactive(struct vop_inactive_args *ap)
50 hammer_vop_reclaim(struct vop_reclaim_args *ap)
52 struct hammer_mount *hmp;
53 struct hammer_inode *ip;
57 hmp = (void *)vp->v_mount->mnt_data;
58 if ((ip = vp->v_data) != NULL) {
61 RB_REMOVE(hammer_ino_rb_tree, &hmp->rb_inos_root, ip);
68 * Lookup or create the vnode associated with the specified inode number.
69 * ino_t in DragonFly is 64 bits which matches the 64 bit HAMMER inode
73 hammer_vfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
75 struct hammer_mount *hmp = (void *)mp->mnt_data;
76 struct hammer_btree_info binfo;
77 struct hammer_inode_info iinfo;
78 struct hammer_base_elm key;
79 struct hammer_inode *ip;
84 * Determine if we already have an inode cached. If we do then
90 ip = hammer_ino_rb_tree_RB_LOOKUP_INFO(&hmp->rb_inos_root, &iinfo);
93 if (vget(vp, LK_EXCLUSIVE) != 0)
95 ip = hammer_ino_rb_tree_RB_LOOKUP_INFO(&hmp->rb_inos_root,
97 if (ip == NULL || ip->vp != vp) {
106 * Lookup failed, instantiate a new vnode and inode in-memory
107 * structure so we don't block in kmalloc later on when holding
108 * locked buffer cached buffers.
110 error = getnewvnode(VT_HAMMER, mp, vpp, 0, 0);
116 ip = kmalloc(sizeof(*ip), M_HAMMER, M_WAITOK|M_ZERO);
119 * If we do not have an inode cached search the HAMMER on-disk B-Tree
122 hammer_btree_info_init(&binfo, hmp->rootcl);
127 key.rec_type = HAMMER_RECTYPE_INODE;
130 error = hammer_btree_lookup(&binfo, &key, HAMMER_BTREE_GET_RECORD |
131 HAMMER_BTREE_GET_DATA);
134 * On success the B-Tree lookup will hold the appropriate
135 * buffer cache buffers and provide a pointer to the requested
136 * information. Copy the information to the in-memory inode.
139 ip->ino_rec = binfo.rec->inode;
140 ip->ino_data = binfo.data->inode;
142 hammer_btree_info_done(&binfo);
145 * On success load the inode's record and data and insert the
146 * inode into the B-Tree. It is possible to race another lookup
147 * insertion of the same inode so deal with that condition too.
150 if (RB_INSERT(hammer_ino_rb_tree, &hmp->rb_inos_root, ip)) {
157 vp->v_data = (void *)ip;
159 hammer_get_vnode_type(ip->ino_rec.base.base.obj_type);
168 * Convert a HAMMER filesystem object type to a vnode type
172 hammer_get_vnode_type(u_int16_t obj_type)
175 case HAMMER_OBJTYPE_DIRECTORY:
177 case HAMMER_OBJTYPE_REGFILE:
179 case HAMMER_OBJTYPE_DBFILE:
181 case HAMMER_OBJTYPE_FIFO:
183 case HAMMER_OBJTYPE_CDEV:
185 case HAMMER_OBJTYPE_BDEV:
187 case HAMMER_OBJTYPE_SOFTLINK:
196 * Access the filesystem buffer containing the cluster-relative byte
197 * offset, validate the buffer type, load *bufferp and return a
198 * pointer to the requested data.
200 * If buf_type is 0 the buffer is assumed to be a pure-data buffer and
201 * no type or crc check is performed.
203 * XXX add a flag for the buffer type and check the CRC here XXX
206 hammer_bread(struct hammer_cluster *cluster, int32_t cloff,
208 int *errorp, struct hammer_buffer **bufferp)
210 struct hammer_buffer *buffer;
215 * Load the correct filesystem buffer, replacing *bufferp.
217 buf_no = cloff / HAMMER_BUFSIZE;
219 if (buffer == NULL || buffer->cluster != cluster ||
220 buffer->buf_no != buf_no) {
222 hammer_put_buffer(buffer);
223 buffer = hammer_get_buffer(cluster, buf_no, 0, errorp);
230 * Validate the buffer type and crc XXX
232 buf_off = cloff & HAMMER_BUFMASK;
234 if (buf_type != buffer->ondisk->head.buf_type) {
238 if (buf_off < sizeof(buffer->ondisk->head)) {
246 * Return a pointer to the buffer data.
249 return((char *)buffer->ondisk + buf_off);