Add a line to the rc.conf example to not try to set the screensaver
[dragonfly.git] / sys / vfs / hammer / hammer_inode.c
... / ...
CommitLineData
1/*
2 * Copyright (c) 2007 The DragonFly Project. All rights reserved.
3 *
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
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
16 * distribution.
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.
20 *
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
32 * SUCH DAMAGE.
33 *
34 * $DragonFly: src/sys/vfs/hammer/hammer_inode.c,v 1.2 2007/11/02 00:57:15 dillon Exp $
35 */
36
37#include "hammer.h"
38#include <sys/buf.h>
39#include <sys/buf2.h>
40
41static enum vtype hammer_get_vnode_type(u_int16_t obj_type);
42
43int
44hammer_vop_inactive(struct vop_inactive_args *ap)
45{
46#if 0
47 struct vnode *vp;
48
49 vp = ap->a_vp;
50#endif
51 return(0);
52}
53
54int
55hammer_vop_reclaim(struct vop_reclaim_args *ap)
56{
57 struct hammer_mount *hmp;
58 struct hammer_inode *ip;
59 struct vnode *vp;
60
61 vp = ap->a_vp;
62 hmp = (void *)vp->v_mount->mnt_data;
63 if ((ip = vp->v_data) != NULL) {
64 ip->vp = NULL;
65 vp->v_data = NULL;
66 RB_REMOVE(hammer_ino_rb_tree, &hmp->rb_inos_root, ip);
67 kfree(ip, M_HAMMER);
68 }
69 return(0);
70}
71
72/*
73 * Lookup or create the vnode associated with the specified inode number.
74 * ino_t in DragonFly is 64 bits which matches the 64 bit HAMMER inode
75 * number.
76 */
77int
78hammer_vfs_vget(struct mount *mp, ino_t ino, struct vnode **vpp)
79{
80 struct hammer_mount *hmp = (void *)mp->mnt_data;
81 struct hammer_btree_info binfo;
82 struct hammer_inode_info iinfo;
83 struct hammer_base_elm key;
84 struct hammer_inode *ip;
85 struct vnode *vp;
86 int error;
87
88 /*
89 * Determine if we already have an inode cached. If we do then
90 * we are golden.
91 */
92 iinfo.obj_id = ino;
93 iinfo.obj_asof = 0;
94loop:
95 ip = hammer_ino_rb_tree_RB_LOOKUP_INFO(&hmp->rb_inos_root, &iinfo);
96 if (ip) {
97 vp = ip->vp;
98 if (vget(vp, LK_EXCLUSIVE) != 0)
99 goto loop;
100 ip = hammer_ino_rb_tree_RB_LOOKUP_INFO(&hmp->rb_inos_root,
101 &iinfo);
102 if (ip == NULL || ip->vp != vp) {
103 vput(vp);
104 goto loop;
105 }
106 *vpp = vp;
107 return(0);
108 }
109
110 /*
111 * Lookup failed, instantiate a new vnode and inode in-memory
112 * structure so we don't block in kmalloc later on when holding
113 * locked buffer cached buffers.
114 */
115 error = getnewvnode(VT_HAMMER, mp, vpp, 0, 0);
116 if (error) {
117 *vpp = NULL;
118 return (error);
119 }
120 vp = *vpp;
121 ip = kmalloc(sizeof(*ip), M_HAMMER, M_WAITOK|M_ZERO);
122 ip->obj_id = ino;
123 ip->obj_asof = iinfo.obj_asof;
124
125 /*
126 * If we do not have an inode cached search the HAMMER on-disk B-Tree
127 * for it.
128 */
129 hammer_btree_info_init(&binfo, hmp->rootcl);
130 key.obj_id = ino;
131 key.key = 0;
132 key.create_tid = 0;
133 key.delete_tid = 0;
134 key.rec_type = HAMMER_RECTYPE_INODE;
135 key.obj_type = 0;
136
137 error = hammer_btree_lookup(&binfo, &key, HAMMER_BTREE_GET_RECORD |
138 HAMMER_BTREE_GET_DATA);
139
140 /*
141 * On success the B-Tree lookup will hold the appropriate
142 * buffer cache buffers and provide a pointer to the requested
143 * information. Copy the information to the in-memory inode.
144 */
145 if (error == 0) {
146 ip->ino_rec = binfo.rec->inode;
147 ip->ino_data = binfo.data->inode;
148 }
149 hammer_btree_info_done(&binfo);
150
151 /*
152 * On success load the inode's record and data and insert the
153 * inode into the B-Tree. It is possible to race another lookup
154 * insertion of the same inode so deal with that condition too.
155 */
156 if (error == 0) {
157 if (RB_INSERT(hammer_ino_rb_tree, &hmp->rb_inos_root, ip)) {
158 vp->v_type = VBAD;
159 vx_put(vp);
160 kfree(ip, M_HAMMER);
161 goto loop;
162 }
163 ip->vp = vp;
164 vp->v_data = (void *)ip;
165 vp->v_type =
166 hammer_get_vnode_type(ip->ino_rec.base.base.obj_type);
167 *vpp = vp;
168 } else {
169 *vpp = NULL;
170 }
171 return (error);
172}
173
174/*
175 * (called via RB_SCAN)
176 */
177int
178hammer_unload_inode(struct hammer_inode *ip, void *data)
179{
180 struct hammer_mount *hmp = data;
181 struct vnode *vp;
182
183 if ((vp = ip->vp) != NULL) {
184 ip->vp = NULL;
185 vp->v_data = NULL;
186 /* XXX */
187 }
188 RB_REMOVE(hammer_ino_rb_tree, &hmp->rb_inos_root, ip);
189 kfree(ip, M_HAMMER);
190 return(0);
191}
192
193
194/*
195 * Convert a HAMMER filesystem object type to a vnode type
196 */
197static
198enum vtype
199hammer_get_vnode_type(u_int16_t obj_type)
200{
201 switch(obj_type) {
202 case HAMMER_OBJTYPE_DIRECTORY:
203 return(VDIR);
204 case HAMMER_OBJTYPE_REGFILE:
205 return(VREG);
206 case HAMMER_OBJTYPE_DBFILE:
207 return(VDATABASE);
208 case HAMMER_OBJTYPE_FIFO:
209 return(VFIFO);
210 case HAMMER_OBJTYPE_CDEV:
211 return(VCHR);
212 case HAMMER_OBJTYPE_BDEV:
213 return(VBLK);
214 case HAMMER_OBJTYPE_SOFTLINK:
215 return(VLNK);
216 default:
217 return(VBAD);
218 }
219 /* not reached */
220}
221
222/*
223 * Access the filesystem buffer containing the cluster-relative byte
224 * offset, validate the buffer type, load *bufferp and return a
225 * pointer to the requested data.
226 *
227 * If buf_type is 0 the buffer is assumed to be a pure-data buffer and
228 * no type or crc check is performed.
229 *
230 * XXX add a flag for the buffer type and check the CRC here XXX
231 */
232void *
233hammer_bread(struct hammer_cluster *cluster, int32_t cloff,
234 u_int64_t buf_type,
235 int *errorp, struct hammer_buffer **bufferp)
236{
237 struct hammer_buffer *buffer;
238 int32_t buf_no;
239 int32_t buf_off;
240
241 /*
242 * Load the correct filesystem buffer, replacing *bufferp.
243 */
244 buf_no = cloff / HAMMER_BUFSIZE;
245 buffer = *bufferp;
246 if (buffer == NULL || buffer->cluster != cluster ||
247 buffer->buf_no != buf_no) {
248 if (buffer)
249 hammer_put_buffer(buffer);
250 buffer = hammer_get_buffer(cluster, buf_no, 0, errorp);
251 *bufferp = buffer;
252 if (buffer == NULL)
253 return(NULL);
254 }
255
256 /*
257 * Validate the buffer type and crc XXX
258 */
259 buf_off = cloff & HAMMER_BUFMASK;
260 if (buf_type) {
261 if (buf_type != buffer->ondisk->head.buf_type) {
262 kprintf("BUFFER HEAD TYPE MISMATCH %llx %llx\n",
263 buf_type, buffer->ondisk->head.buf_type);
264 *errorp = EIO;
265 return(NULL);
266 }
267 if (buf_off < sizeof(buffer->ondisk->head)) {
268 kprintf("BUFFER OFFSET TOO LOW %d\n", buf_off);
269 *errorp = EIO;
270 return(NULL);
271 }
272 /* XXX crc */
273 }
274
275 /*
276 * Return a pointer to the buffer data.
277 */
278 *errorp = 0;
279 return((char *)buffer->ondisk + buf_off);
280}
281