nilfs_subr.c revision 1.4.2.2 1 1.4.2.2 yamt /* $NetBSD: nilfs_subr.c,v 1.4.2.2 2009/08/19 18:48:14 yamt Exp $ */
2 1.4.2.2 yamt
3 1.4.2.2 yamt /*
4 1.4.2.2 yamt * Copyright (c) 2008, 2009 Reinoud Zandijk
5 1.4.2.2 yamt * All rights reserved.
6 1.4.2.2 yamt *
7 1.4.2.2 yamt * Redistribution and use in source and binary forms, with or without
8 1.4.2.2 yamt * modification, are permitted provided that the following conditions
9 1.4.2.2 yamt * are met:
10 1.4.2.2 yamt * 1. Redistributions of source code must retain the above copyright
11 1.4.2.2 yamt * notice, this list of conditions and the following disclaimer.
12 1.4.2.2 yamt * 2. Redistributions in binary form must reproduce the above copyright
13 1.4.2.2 yamt * notice, this list of conditions and the following disclaimer in the
14 1.4.2.2 yamt * documentation and/or other materials provided with the distribution.
15 1.4.2.2 yamt *
16 1.4.2.2 yamt * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 1.4.2.2 yamt * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 1.4.2.2 yamt * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 1.4.2.2 yamt * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 1.4.2.2 yamt * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 1.4.2.2 yamt * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 1.4.2.2 yamt * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 1.4.2.2 yamt * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 1.4.2.2 yamt * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 1.4.2.2 yamt * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 1.4.2.2 yamt *
27 1.4.2.2 yamt */
28 1.4.2.2 yamt
29 1.4.2.2 yamt #include <sys/cdefs.h>
30 1.4.2.2 yamt #ifndef lint
31 1.4.2.2 yamt __KERNEL_RCSID(0, "$NetBSD: nilfs_subr.c,v 1.4.2.2 2009/08/19 18:48:14 yamt Exp $");
32 1.4.2.2 yamt #endif /* not lint */
33 1.4.2.2 yamt
34 1.4.2.2 yamt #include <sys/param.h>
35 1.4.2.2 yamt #include <sys/systm.h>
36 1.4.2.2 yamt #include <sys/namei.h>
37 1.4.2.2 yamt #include <sys/resourcevar.h> /* defines plimit structure in proc struct */
38 1.4.2.2 yamt #include <sys/kernel.h>
39 1.4.2.2 yamt #include <sys/file.h> /* define FWRITE ... */
40 1.4.2.2 yamt #include <sys/stat.h>
41 1.4.2.2 yamt #include <sys/buf.h>
42 1.4.2.2 yamt #include <sys/proc.h>
43 1.4.2.2 yamt #include <sys/mount.h>
44 1.4.2.2 yamt #include <sys/vnode.h>
45 1.4.2.2 yamt #include <sys/signalvar.h>
46 1.4.2.2 yamt #include <sys/malloc.h>
47 1.4.2.2 yamt #include <sys/dirent.h>
48 1.4.2.2 yamt #include <sys/lockf.h>
49 1.4.2.2 yamt #include <sys/kauth.h>
50 1.4.2.2 yamt #include <sys/dirhash.h>
51 1.4.2.2 yamt
52 1.4.2.2 yamt #include <miscfs/genfs/genfs.h>
53 1.4.2.2 yamt #include <uvm/uvm_extern.h>
54 1.4.2.2 yamt
55 1.4.2.2 yamt #include <fs/nilfs/nilfs_mount.h>
56 1.4.2.2 yamt #include "nilfs.h"
57 1.4.2.2 yamt #include "nilfs_subr.h"
58 1.4.2.2 yamt #include "nilfs_bswap.h"
59 1.4.2.2 yamt
60 1.4.2.2 yamt
61 1.4.2.2 yamt #define VTOI(vnode) ((struct nilfs_node *) (vnode)->v_data)
62 1.4.2.2 yamt
63 1.4.2.2 yamt /* basic calculators */
64 1.4.2.2 yamt uint64_t nilfs_get_segnum_of_block(struct nilfs_device *nilfsdev,
65 1.4.2.2 yamt uint64_t blocknr)
66 1.4.2.2 yamt {
67 1.4.2.2 yamt return blocknr / nilfs_rw32(nilfsdev->super.s_blocks_per_segment);
68 1.4.2.2 yamt }
69 1.4.2.2 yamt
70 1.4.2.2 yamt
71 1.4.2.2 yamt void
72 1.4.2.2 yamt nilfs_get_segment_range(struct nilfs_device *nilfsdev, uint64_t segnum,
73 1.4.2.2 yamt uint64_t *seg_start, uint64_t *seg_end)
74 1.4.2.2 yamt {
75 1.4.2.2 yamt uint64_t blks_per_seg;
76 1.4.2.2 yamt
77 1.4.2.2 yamt blks_per_seg = nilfs_rw64(nilfsdev->super.s_blocks_per_segment);
78 1.4.2.2 yamt *seg_start = blks_per_seg * segnum;
79 1.4.2.2 yamt *seg_end = *seg_start + blks_per_seg -1;
80 1.4.2.2 yamt if (segnum == 0)
81 1.4.2.2 yamt *seg_start = nilfs_rw64(nilfsdev->super.s_first_data_block);
82 1.4.2.2 yamt }
83 1.4.2.2 yamt
84 1.4.2.2 yamt
85 1.4.2.2 yamt void nilfs_calc_mdt_consts(struct nilfs_device *nilfsdev,
86 1.4.2.2 yamt struct nilfs_mdt *mdt, int entry_size)
87 1.4.2.2 yamt {
88 1.4.2.2 yamt uint32_t blocksize = nilfsdev->blocksize;
89 1.4.2.2 yamt
90 1.4.2.2 yamt mdt->entries_per_group = blocksize * 8; /* bits in sector */
91 1.4.2.2 yamt mdt->entries_per_block = blocksize / entry_size;
92 1.4.2.2 yamt
93 1.4.2.2 yamt mdt->blocks_per_group =
94 1.4.2.2 yamt (mdt->entries_per_group -1) / mdt->entries_per_block + 1 + 1;
95 1.4.2.2 yamt mdt->groups_per_desc_block =
96 1.4.2.2 yamt blocksize / sizeof(struct nilfs_block_group_desc);
97 1.4.2.2 yamt mdt->blocks_per_desc_block =
98 1.4.2.2 yamt mdt->groups_per_desc_block * mdt->blocks_per_group + 1;
99 1.4.2.2 yamt }
100 1.4.2.2 yamt
101 1.4.2.2 yamt
102 1.4.2.2 yamt /* from NetBSD's src/sys/net/if_ethersubr.c */
103 1.4.2.2 yamt uint32_t
104 1.4.2.2 yamt crc32_le(uint32_t crc, const uint8_t *buf, size_t len)
105 1.4.2.2 yamt {
106 1.4.2.2 yamt static const uint32_t crctab[] = {
107 1.4.2.2 yamt 0x00000000, 0x1db71064, 0x3b6e20c8, 0x26d930ac,
108 1.4.2.2 yamt 0x76dc4190, 0x6b6b51f4, 0x4db26158, 0x5005713c,
109 1.4.2.2 yamt 0xedb88320, 0xf00f9344, 0xd6d6a3e8, 0xcb61b38c,
110 1.4.2.2 yamt 0x9b64c2b0, 0x86d3d2d4, 0xa00ae278, 0xbdbdf21c
111 1.4.2.2 yamt };
112 1.4.2.2 yamt size_t i;
113 1.4.2.2 yamt
114 1.4.2.2 yamt for (i = 0; i < len; i++) {
115 1.4.2.2 yamt crc ^= buf[i];
116 1.4.2.2 yamt crc = (crc >> 4) ^ crctab[crc & 0xf];
117 1.4.2.2 yamt crc = (crc >> 4) ^ crctab[crc & 0xf];
118 1.4.2.2 yamt }
119 1.4.2.2 yamt
120 1.4.2.2 yamt return (crc);
121 1.4.2.2 yamt }
122 1.4.2.2 yamt
123 1.4.2.2 yamt
124 1.4.2.2 yamt static int
125 1.4.2.2 yamt nilfs_calchash(uint64_t ino)
126 1.4.2.2 yamt {
127 1.4.2.2 yamt return (int) ino;
128 1.4.2.2 yamt }
129 1.4.2.2 yamt
130 1.4.2.2 yamt
131 1.4.2.2 yamt /* dev reading */
132 1.4.2.2 yamt static int
133 1.4.2.2 yamt nilfs_dev_bread(struct nilfs_device *nilfsdev, uint64_t blocknr,
134 1.4.2.2 yamt struct kauth_cred *cred, int flags, struct buf **bpp)
135 1.4.2.2 yamt {
136 1.4.2.2 yamt int blk2dev = nilfsdev->blocksize / DEV_BSIZE;
137 1.4.2.2 yamt
138 1.4.2.2 yamt return bread(nilfsdev->devvp, blocknr * blk2dev, nilfsdev->blocksize,
139 1.4.2.2 yamt NOCRED, 0, bpp);
140 1.4.2.2 yamt }
141 1.4.2.2 yamt
142 1.4.2.2 yamt
143 1.4.2.2 yamt /* read on a node */
144 1.4.2.2 yamt int
145 1.4.2.2 yamt nilfs_bread(struct nilfs_node *node, uint64_t blocknr,
146 1.4.2.2 yamt struct kauth_cred *cred, int flags, struct buf **bpp)
147 1.4.2.2 yamt {
148 1.4.2.2 yamt return bread(node->vnode, blocknr, node->nilfsdev->blocksize,
149 1.4.2.2 yamt cred, flags, bpp);
150 1.4.2.2 yamt }
151 1.4.2.2 yamt
152 1.4.2.2 yamt
153 1.4.2.2 yamt /* segment-log reading */
154 1.4.2.2 yamt int
155 1.4.2.2 yamt nilfs_get_segment_log(struct nilfs_device *nilfsdev, uint64_t *blocknr,
156 1.4.2.2 yamt uint64_t *offset, struct buf **bpp, int len, void *blob)
157 1.4.2.2 yamt {
158 1.4.2.2 yamt int blocksize = nilfsdev->blocksize;
159 1.4.2.2 yamt int error;
160 1.4.2.2 yamt
161 1.4.2.2 yamt KASSERT(len <= blocksize);
162 1.4.2.2 yamt
163 1.4.2.2 yamt if (*offset + len > blocksize) {
164 1.4.2.2 yamt *blocknr = *blocknr + 1;
165 1.4.2.2 yamt *offset = 0;
166 1.4.2.2 yamt }
167 1.4.2.2 yamt if (*offset == 0) {
168 1.4.2.2 yamt if (*bpp)
169 1.4.2.2 yamt brelse(*bpp, BC_AGE);
170 1.4.2.2 yamt /* read in block */
171 1.4.2.2 yamt error = nilfs_dev_bread(nilfsdev, *blocknr, NOCRED, 0, bpp);
172 1.4.2.2 yamt if (error)
173 1.4.2.2 yamt return error;
174 1.4.2.2 yamt }
175 1.4.2.2 yamt memcpy(blob, ((uint8_t *) (*bpp)->b_data) + *offset, len);
176 1.4.2.2 yamt *offset += len;
177 1.4.2.2 yamt
178 1.4.2.2 yamt return 0;
179 1.4.2.2 yamt }
180 1.4.2.2 yamt
181 1.4.2.2 yamt /* -------------------------------------------------------------------------- */
182 1.4.2.2 yamt
183 1.4.2.2 yamt /* btree operations */
184 1.4.2.2 yamt
185 1.4.2.2 yamt static int
186 1.4.2.2 yamt nilfs_btree_lookup_level(struct nilfs_node *node, uint64_t lblocknr,
187 1.4.2.2 yamt uint64_t btree_vblknr, int level, uint64_t *vblocknr)
188 1.4.2.2 yamt {
189 1.4.2.2 yamt struct nilfs_device *nilfsdev = node->nilfsdev;
190 1.4.2.2 yamt struct nilfs_btree_node *btree_hdr;
191 1.4.2.2 yamt struct buf *bp;
192 1.4.2.2 yamt uint64_t btree_blknr;
193 1.4.2.2 yamt uint64_t *dkeys, *dptrs, child_btree_blk;
194 1.4.2.2 yamt uint8_t *pos;
195 1.4.2.2 yamt int i, error, selected;
196 1.4.2.2 yamt
197 1.4.2.2 yamt DPRINTF(TRANSLATE, ("nilfs_btree_lookup_level ino %"PRIu64", "
198 1.4.2.2 yamt "lblocknr %"PRIu64", btree_vblknr %"PRIu64", level %d\n",
199 1.4.2.2 yamt node->ino, lblocknr, btree_vblknr, level));
200 1.4.2.2 yamt
201 1.4.2.2 yamt /* translate btree_vblknr */
202 1.4.2.2 yamt error = nilfs_nvtop(node, 1, &btree_vblknr, &btree_blknr);
203 1.4.2.2 yamt if (error)
204 1.4.2.2 yamt return error;
205 1.4.2.2 yamt
206 1.4.2.2 yamt /* get our block */
207 1.4.2.2 yamt error = nilfs_dev_bread(nilfsdev, btree_blknr, NOCRED, 0, &bp);
208 1.4.2.2 yamt if (error) {
209 1.4.2.2 yamt brelse(bp, BC_AGE);
210 1.4.2.2 yamt return error;
211 1.4.2.2 yamt }
212 1.4.2.2 yamt
213 1.4.2.2 yamt btree_hdr = (struct nilfs_btree_node *) bp->b_data;
214 1.4.2.2 yamt pos = (uint8_t *) bp->b_data +
215 1.4.2.2 yamt sizeof(struct nilfs_btree_node) +
216 1.4.2.2 yamt NILFS_BTREE_NODE_EXTRA_PAD_SIZE;
217 1.4.2.2 yamt dkeys = (uint64_t *) pos;
218 1.4.2.2 yamt dptrs = dkeys + NILFS_BTREE_NODE_NCHILDREN_MAX(nilfsdev->blocksize);
219 1.4.2.2 yamt
220 1.4.2.2 yamt assert((btree_hdr->bn_flags & NILFS_BTREE_NODE_ROOT) == 0);
221 1.4.2.2 yamt
222 1.4.2.2 yamt /* select matching child XXX could use binary search */
223 1.4.2.2 yamt selected = 0;
224 1.4.2.2 yamt for (i = 0; i < nilfs_rw16(btree_hdr->bn_nchildren); i++) {
225 1.4.2.2 yamt if (dkeys[i] > lblocknr)
226 1.4.2.2 yamt break;
227 1.4.2.2 yamt selected = i;
228 1.4.2.2 yamt }
229 1.4.2.2 yamt
230 1.4.2.2 yamt if (level == 1) {
231 1.4.2.2 yamt /* if found it mapped */
232 1.4.2.2 yamt if (dkeys[selected] == lblocknr)
233 1.4.2.2 yamt *vblocknr = dptrs[selected];
234 1.4.2.2 yamt brelse(bp, BC_AGE);
235 1.4.2.2 yamt return 0;
236 1.4.2.2 yamt }
237 1.4.2.2 yamt
238 1.4.2.2 yamt /* lookup in selected child */
239 1.4.2.2 yamt assert(dkeys[selected] <= lblocknr);
240 1.4.2.2 yamt child_btree_blk = dptrs[selected];
241 1.4.2.2 yamt brelse(bp, BC_AGE);
242 1.4.2.2 yamt
243 1.4.2.2 yamt return nilfs_btree_lookup_level(node, lblocknr,
244 1.4.2.2 yamt child_btree_blk, btree_hdr->bn_level-1, vblocknr);
245 1.4.2.2 yamt }
246 1.4.2.2 yamt
247 1.4.2.2 yamt
248 1.4.2.2 yamt /* internal function */
249 1.4.2.2 yamt static int
250 1.4.2.2 yamt nilfs_btree_lookup(struct nilfs_node *node, uint64_t lblocknr,
251 1.4.2.2 yamt uint64_t *vblocknr)
252 1.4.2.2 yamt {
253 1.4.2.2 yamt struct nilfs_inode *inode = &node->inode;
254 1.4.2.2 yamt struct nilfs_btree_node *btree_hdr;
255 1.4.2.2 yamt uint64_t *dkeys, *dptrs, *dtrans;
256 1.4.2.2 yamt int i, selected;
257 1.4.2.2 yamt int error;
258 1.4.2.2 yamt
259 1.4.2.2 yamt DPRINTF(TRANSLATE, ("nilfs_btree_lookup ino %"PRIu64", "
260 1.4.2.2 yamt "lblocknr %"PRIu64"\n", node->ino, lblocknr));
261 1.4.2.2 yamt
262 1.4.2.2 yamt btree_hdr = (struct nilfs_btree_node *) &inode->i_bmap[0];
263 1.4.2.2 yamt dkeys = &inode->i_bmap[1];
264 1.4.2.2 yamt dptrs = dkeys + NILFS_BTREE_ROOT_NCHILDREN_MAX;
265 1.4.2.2 yamt dtrans = &inode->i_bmap[1];
266 1.4.2.2 yamt
267 1.4.2.2 yamt /* SMALL, direct lookup */
268 1.4.2.2 yamt *vblocknr = 0;
269 1.4.2.2 yamt if ((btree_hdr->bn_flags & NILFS_BMAP_LARGE) == 0) {
270 1.4.2.2 yamt if (lblocknr < NILFS_DIRECT_NBLOCKS) {
271 1.4.2.2 yamt *vblocknr = dtrans[lblocknr];
272 1.4.2.2 yamt return 0;
273 1.4.2.2 yamt }
274 1.4.2.2 yamt /* not mapped XXX could be considered error here */
275 1.4.2.2 yamt return 0;
276 1.4.2.2 yamt }
277 1.4.2.2 yamt
278 1.4.2.2 yamt /* LARGE, select matching child; XXX could use binary search */
279 1.4.2.2 yamt dtrans = NULL;
280 1.4.2.2 yamt error = 0;
281 1.4.2.2 yamt selected = 0;
282 1.4.2.2 yamt for (i = 0; i < nilfs_rw16(btree_hdr->bn_nchildren); i++) {
283 1.4.2.2 yamt if (dkeys[i] > lblocknr)
284 1.4.2.2 yamt break;
285 1.4.2.2 yamt selected = i;
286 1.4.2.2 yamt }
287 1.4.2.2 yamt
288 1.4.2.2 yamt /* if selected key > lblocknr, its not mapped */
289 1.4.2.2 yamt if (dkeys[selected] > lblocknr)
290 1.4.2.2 yamt return 0;
291 1.4.2.2 yamt
292 1.4.2.2 yamt /* overshooting? then not mapped */
293 1.4.2.2 yamt if (selected == nilfs_rw16(btree_hdr->bn_nchildren))
294 1.4.2.2 yamt return 0;
295 1.4.2.2 yamt
296 1.4.2.2 yamt /* level should be > 1 or otherwise it should be a direct one */
297 1.4.2.2 yamt assert(btree_hdr->bn_level > 1);
298 1.4.2.2 yamt
299 1.4.2.2 yamt /* lookup in selected child */
300 1.4.2.2 yamt assert(dkeys[selected] <= lblocknr);
301 1.4.2.2 yamt error = nilfs_btree_lookup_level(node, lblocknr,
302 1.4.2.2 yamt dptrs[selected], btree_hdr->bn_level-1, vblocknr);
303 1.4.2.2 yamt
304 1.4.2.2 yamt return error;
305 1.4.2.2 yamt }
306 1.4.2.2 yamt
307 1.4.2.2 yamt
308 1.4.2.2 yamt /* node should be locked on entry to prevent btree changes (unlikely) */
309 1.4.2.2 yamt int
310 1.4.2.2 yamt nilfs_btree_nlookup(struct nilfs_node *node, uint64_t from, uint64_t blks,
311 1.4.2.2 yamt uint64_t *l2vmap)
312 1.4.2.2 yamt {
313 1.4.2.2 yamt uint64_t lblocknr, *vblocknr;
314 1.4.2.2 yamt int i, error;
315 1.4.2.2 yamt
316 1.4.2.2 yamt /* TODO / OPTI multiple translations in one go possible */
317 1.4.2.2 yamt error = EINVAL;
318 1.4.2.2 yamt for (i = 0; i < blks; i++) {
319 1.4.2.2 yamt lblocknr = from + i;
320 1.4.2.2 yamt vblocknr = l2vmap + i;
321 1.4.2.2 yamt error = nilfs_btree_lookup(node, lblocknr, vblocknr);
322 1.4.2.2 yamt
323 1.4.2.2 yamt DPRINTF(TRANSLATE, ("btree_nlookup ino %"PRIu64", "
324 1.4.2.2 yamt "lblocknr %"PRIu64" -> %"PRIu64"\n",
325 1.4.2.2 yamt node->ino, lblocknr, *vblocknr));
326 1.4.2.2 yamt if (error)
327 1.4.2.2 yamt break;
328 1.4.2.2 yamt }
329 1.4.2.2 yamt
330 1.4.2.2 yamt return error;
331 1.4.2.2 yamt }
332 1.4.2.2 yamt
333 1.4.2.2 yamt /* --------------------------------------------------------------------- */
334 1.4.2.2 yamt
335 1.4.2.2 yamt /* vtop operations */
336 1.4.2.2 yamt
337 1.4.2.2 yamt /* translate index to a file block number and an entry */
338 1.4.2.2 yamt static void
339 1.4.2.2 yamt nilfs_mdt_trans(struct nilfs_mdt *mdt, uint64_t index,
340 1.4.2.2 yamt uint64_t *blocknr, uint32_t *entry_in_block)
341 1.4.2.2 yamt {
342 1.4.2.2 yamt uint64_t blknr;
343 1.4.2.2 yamt uint64_t group, group_offset, blocknr_in_group;
344 1.4.2.2 yamt uint64_t desc_block, desc_offset;
345 1.4.2.2 yamt
346 1.4.2.2 yamt /* calculate our offset in the file */
347 1.4.2.2 yamt group = index / mdt->entries_per_group;
348 1.4.2.2 yamt group_offset = index % mdt->entries_per_group;
349 1.4.2.2 yamt desc_block = group / mdt->groups_per_desc_block;
350 1.4.2.2 yamt desc_offset = group % mdt->groups_per_desc_block;
351 1.4.2.2 yamt blocknr_in_group = group_offset / mdt->entries_per_block;
352 1.4.2.2 yamt
353 1.4.2.2 yamt /* to descgroup offset */
354 1.4.2.2 yamt blknr = 1 + desc_block * mdt->blocks_per_desc_block;
355 1.4.2.2 yamt
356 1.4.2.2 yamt /* to group offset */
357 1.4.2.2 yamt blknr += desc_offset * mdt->blocks_per_group;
358 1.4.2.2 yamt
359 1.4.2.2 yamt /* to actual file block */
360 1.4.2.2 yamt blknr += 1 + blocknr_in_group;
361 1.4.2.2 yamt
362 1.4.2.2 yamt *blocknr = blknr;
363 1.4.2.2 yamt *entry_in_block = group_offset % mdt->entries_per_block;
364 1.4.2.2 yamt }
365 1.4.2.2 yamt
366 1.4.2.2 yamt
367 1.4.2.2 yamt static int
368 1.4.2.2 yamt nilfs_vtop(struct nilfs_device *nilfsdev, uint64_t vblocknr, uint64_t *pblocknr)
369 1.4.2.2 yamt {
370 1.4.2.2 yamt struct nilfs_dat_entry *entry;
371 1.4.2.2 yamt struct buf *bp;
372 1.4.2.2 yamt uint64_t ldatblknr;
373 1.4.2.2 yamt uint32_t entry_in_block;
374 1.4.2.2 yamt int error;
375 1.4.2.2 yamt
376 1.4.2.2 yamt nilfs_mdt_trans(&nilfsdev->dat_mdt, vblocknr,
377 1.4.2.2 yamt &ldatblknr, &entry_in_block);
378 1.4.2.2 yamt
379 1.4.2.2 yamt error = nilfs_bread(nilfsdev->dat_node, ldatblknr, NOCRED, 0, &bp);
380 1.4.2.2 yamt if (error) {
381 1.4.2.2 yamt printf("vtop: can't read in DAT block %"PRIu64"!\n", ldatblknr);
382 1.4.2.2 yamt brelse(bp, BC_AGE);
383 1.4.2.2 yamt return error;
384 1.4.2.2 yamt }
385 1.4.2.2 yamt
386 1.4.2.2 yamt /* get our translation */
387 1.4.2.2 yamt entry = ((struct nilfs_dat_entry *) bp->b_data) + entry_in_block;
388 1.4.2.2 yamt #if 0
389 1.4.2.2 yamt printf("\tvblk %4"PRIu64" -> %"PRIu64" for "
390 1.4.2.2 yamt "checkpoint %"PRIu64" to %"PRIu64"\n",
391 1.4.2.2 yamt vblocknr,
392 1.4.2.2 yamt nilfs_rw64(entry->de_blocknr),
393 1.4.2.2 yamt nilfs_rw64(entry->de_start),
394 1.4.2.2 yamt nilfs_rw64(entry->de_end));
395 1.4.2.2 yamt #endif
396 1.4.2.2 yamt
397 1.4.2.2 yamt *pblocknr = nilfs_rw64(entry->de_blocknr);
398 1.4.2.2 yamt brelse(bp, BC_AGE);
399 1.4.2.2 yamt
400 1.4.2.2 yamt return 0;
401 1.4.2.2 yamt }
402 1.4.2.2 yamt
403 1.4.2.2 yamt
404 1.4.2.2 yamt int
405 1.4.2.2 yamt nilfs_nvtop(struct nilfs_node *node, uint64_t blks, uint64_t *l2vmap,
406 1.4.2.2 yamt uint64_t *v2pmap)
407 1.4.2.2 yamt {
408 1.4.2.2 yamt uint64_t vblocknr, *pblocknr;
409 1.4.2.2 yamt int i, error;
410 1.4.2.2 yamt
411 1.4.2.2 yamt /* the DAT inode is the only one not mapped virtual */
412 1.4.2.2 yamt if (node->ino == NILFS_DAT_INO) {
413 1.4.2.2 yamt memcpy(v2pmap, l2vmap, blks * sizeof(uint64_t));
414 1.4.2.2 yamt return 0;
415 1.4.2.2 yamt }
416 1.4.2.2 yamt
417 1.4.2.2 yamt /* TODO / OPTI more translations in one go */
418 1.4.2.2 yamt error = 0;
419 1.4.2.2 yamt for (i = 0; i < blks; i++) {
420 1.4.2.2 yamt vblocknr = l2vmap[i];
421 1.4.2.2 yamt pblocknr = v2pmap + i;
422 1.4.2.2 yamt *pblocknr = 0;
423 1.4.2.2 yamt
424 1.4.2.2 yamt /* only translate valid vblocknrs */
425 1.4.2.2 yamt if (vblocknr == 0)
426 1.4.2.2 yamt continue;
427 1.4.2.2 yamt error = nilfs_vtop(node->nilfsdev, vblocknr, pblocknr);
428 1.4.2.2 yamt if (error)
429 1.4.2.2 yamt break;
430 1.4.2.2 yamt }
431 1.4.2.2 yamt
432 1.4.2.2 yamt return error;
433 1.4.2.2 yamt }
434 1.4.2.2 yamt
435 1.4.2.2 yamt /* --------------------------------------------------------------------- */
436 1.4.2.2 yamt
437 1.4.2.2 yamt struct nilfs_recover_info {
438 1.4.2.2 yamt uint64_t segnum;
439 1.4.2.2 yamt uint64_t pseg;
440 1.4.2.2 yamt
441 1.4.2.2 yamt struct nilfs_segment_summary segsum;
442 1.4.2.2 yamt struct nilfs_super_root super_root;
443 1.4.2.2 yamt STAILQ_ENTRY(nilfs_recover_info) next;
444 1.4.2.2 yamt };
445 1.4.2.2 yamt
446 1.4.2.2 yamt
447 1.4.2.2 yamt /*
448 1.4.2.2 yamt * Helper functions of nilfs_mount() that actually mounts the disc.
449 1.4.2.2 yamt */
450 1.4.2.2 yamt static int
451 1.4.2.2 yamt nilfs_load_segsum(struct nilfs_device *nilfsdev,
452 1.4.2.2 yamt struct nilfs_recover_info *ri)
453 1.4.2.2 yamt {
454 1.4.2.2 yamt struct buf *bp;
455 1.4.2.2 yamt uint64_t blocknr, offset;
456 1.4.2.2 yamt uint32_t segsum_struct_size;
457 1.4.2.2 yamt uint32_t magic;
458 1.4.2.2 yamt int error;
459 1.4.2.2 yamt
460 1.4.2.2 yamt segsum_struct_size = sizeof(struct nilfs_segment_summary);
461 1.4.2.2 yamt
462 1.4.2.2 yamt /* read in segsum structure */
463 1.4.2.2 yamt bp = NULL;
464 1.4.2.2 yamt blocknr = ri->pseg;
465 1.4.2.2 yamt offset = 0;
466 1.4.2.2 yamt error = nilfs_get_segment_log(nilfsdev,
467 1.4.2.2 yamt &blocknr, &offset, &bp,
468 1.4.2.2 yamt segsum_struct_size, (void *) &ri->segsum);
469 1.4.2.2 yamt if (error)
470 1.4.2.2 yamt goto out;
471 1.4.2.2 yamt
472 1.4.2.2 yamt /* sanity checks */
473 1.4.2.2 yamt magic = nilfs_rw32(ri->segsum.ss_magic);
474 1.4.2.2 yamt if (magic != NILFS_SEGSUM_MAGIC) {
475 1.4.2.2 yamt DPRINTF(VOLUMES, ("nilfs: bad magic in pseg %"PRIu64"\n",
476 1.4.2.2 yamt ri->pseg));
477 1.4.2.2 yamt error = EINVAL;
478 1.4.2.2 yamt goto out;
479 1.4.2.2 yamt }
480 1.4.2.2 yamt
481 1.4.2.2 yamt /* TODO check segment summary checksum */
482 1.4.2.2 yamt /* TODO check data checksum */
483 1.4.2.2 yamt
484 1.4.2.2 yamt /* adjust our walking point if we have an odd size */
485 1.4.2.2 yamt if (segsum_struct_size != nilfs_rw32(ri->segsum.ss_bytes)) {
486 1.4.2.2 yamt printf("nilfs: WARNING encountered segsum_struct size %d in "
487 1.4.2.2 yamt "pseg %"PRIu64"\n",
488 1.4.2.2 yamt nilfs_rw32(ri->segsum.ss_bytes), ri->pseg);
489 1.4.2.2 yamt /* XXX report as an error? */
490 1.4.2.2 yamt }
491 1.4.2.2 yamt
492 1.4.2.2 yamt out:
493 1.4.2.2 yamt if (bp)
494 1.4.2.2 yamt brelse(bp, BC_AGE);
495 1.4.2.2 yamt
496 1.4.2.2 yamt return error;
497 1.4.2.2 yamt }
498 1.4.2.2 yamt
499 1.4.2.2 yamt
500 1.4.2.2 yamt static int
501 1.4.2.2 yamt nilfs_load_super_root(struct nilfs_device *nilfsdev,
502 1.4.2.2 yamt struct nilfs_recover_info *ri)
503 1.4.2.2 yamt {
504 1.4.2.2 yamt struct nilfs_segment_summary *segsum = &ri->segsum;
505 1.4.2.2 yamt struct nilfs_super_root *super_root;
506 1.4.2.2 yamt struct buf *bp;
507 1.4.2.2 yamt uint64_t blocknr, offset;
508 1.4.2.2 yamt uint32_t segsum_size, size;
509 1.4.2.2 yamt uint32_t nsumblk, nfileblk;
510 1.4.2.2 yamt uint32_t super_root_crc, comp_crc;
511 1.4.2.2 yamt int off, error;
512 1.4.2.2 yamt
513 1.4.2.2 yamt /* process segment summary */
514 1.4.2.2 yamt segsum_size = nilfs_rw32(segsum->ss_sumbytes);
515 1.4.2.2 yamt nsumblk = (segsum_size - 1) / nilfsdev->blocksize + 1;
516 1.4.2.2 yamt nfileblk = nilfs_rw32(segsum->ss_nblocks) - nsumblk;
517 1.4.2.2 yamt
518 1.4.2.2 yamt /* check if there is a superroot */
519 1.4.2.2 yamt if ((nilfs_rw16(segsum->ss_flags) & NILFS_SS_SR) == 0) {
520 1.4.2.2 yamt DPRINTF(VOLUMES, ("nilfs: no super root in pseg %"PRIu64"\n",
521 1.4.2.2 yamt ri->pseg));
522 1.4.2.2 yamt return ENOENT;
523 1.4.2.2 yamt }
524 1.4.2.2 yamt
525 1.4.2.2 yamt /* get our super root, located at the end of the pseg */
526 1.4.2.2 yamt blocknr = ri->pseg + nsumblk + nfileblk - 1;
527 1.4.2.2 yamt offset = 0;
528 1.4.2.2 yamt size = sizeof(struct nilfs_super_root);
529 1.4.2.2 yamt bp = NULL;
530 1.4.2.2 yamt error = nilfs_get_segment_log(nilfsdev,
531 1.4.2.2 yamt &blocknr, &offset, &bp,
532 1.4.2.2 yamt size, (void *) &nilfsdev->super_root);
533 1.4.2.2 yamt if (bp)
534 1.4.2.2 yamt brelse(bp, BC_AGE);
535 1.4.2.2 yamt if (error) {
536 1.4.2.2 yamt printf("read in of superroot failed\n");
537 1.4.2.2 yamt return EIO;
538 1.4.2.2 yamt }
539 1.4.2.2 yamt
540 1.4.2.2 yamt /* check super root crc */
541 1.4.2.2 yamt super_root = &nilfsdev->super_root;
542 1.4.2.2 yamt super_root_crc = nilfs_rw32(super_root->sr_sum);
543 1.4.2.2 yamt off = sizeof(super_root->sr_sum);
544 1.4.2.2 yamt comp_crc = crc32_le(nilfs_rw32(nilfsdev->super.s_crc_seed),
545 1.4.2.2 yamt (uint8_t *) super_root + off,
546 1.4.2.2 yamt NILFS_SR_BYTES - off);
547 1.4.2.2 yamt if (super_root_crc != comp_crc) {
548 1.4.2.2 yamt DPRINTF(VOLUMES, (" invalid superroot, likely from old format\n"));
549 1.4.2.2 yamt return EINVAL;
550 1.4.2.2 yamt }
551 1.4.2.2 yamt
552 1.4.2.2 yamt DPRINTF(VOLUMES, (" got valid superroot\n"));
553 1.4.2.2 yamt
554 1.4.2.2 yamt return 0;
555 1.4.2.2 yamt }
556 1.4.2.2 yamt
557 1.4.2.2 yamt /*
558 1.4.2.2 yamt * Search for the last super root recorded.
559 1.4.2.2 yamt */
560 1.4.2.2 yamt void
561 1.4.2.2 yamt nilfs_search_super_root(struct nilfs_device *nilfsdev)
562 1.4.2.2 yamt {
563 1.4.2.2 yamt struct nilfs_super_block *super;
564 1.4.2.2 yamt struct nilfs_segment_summary *segsum;
565 1.4.2.2 yamt struct nilfs_recover_info *ri, *ori, *i_ri;
566 1.4.2.2 yamt STAILQ_HEAD(,nilfs_recover_info) ri_list;
567 1.4.2.2 yamt uint64_t seg_start, seg_end, cno;
568 1.4.2.2 yamt uint32_t segsum_size;
569 1.4.2.2 yamt uint32_t nsumblk, nfileblk;
570 1.4.2.2 yamt int error;
571 1.4.2.2 yamt
572 1.4.2.2 yamt STAILQ_INIT(&ri_list);
573 1.4.2.2 yamt
574 1.4.2.2 yamt /* search for last super root */
575 1.4.2.2 yamt ri = malloc(sizeof(struct nilfs_recover_info), M_NILFSTEMP, M_WAITOK);
576 1.4.2.2 yamt memset(ri, 0, sizeof(struct nilfs_recover_info));
577 1.4.2.2 yamt
578 1.4.2.2 yamt /* if enabled, start from the specified position */
579 1.4.2.2 yamt if (0) {
580 1.4.2.2 yamt /* start from set start */
581 1.4.2.2 yamt nilfsdev->super.s_last_pseg = nilfsdev->super.s_first_data_block;
582 1.4.2.2 yamt nilfsdev->super.s_last_cno = nilfs_rw64(1);
583 1.4.2.2 yamt }
584 1.4.2.2 yamt
585 1.4.2.2 yamt ri->pseg = nilfs_rw64(nilfsdev->super.s_last_pseg); /* blknr */
586 1.4.2.2 yamt ri->segnum = nilfs_get_segnum_of_block(nilfsdev, ri->pseg);
587 1.4.2.2 yamt
588 1.4.2.2 yamt error = 0;
589 1.4.2.2 yamt cno = nilfs_rw64(nilfsdev->super.s_last_cno);
590 1.4.2.2 yamt DPRINTF(VOLUMES, ("nilfs: seach_super_root start in pseg %"PRIu64"\n",
591 1.4.2.2 yamt ri->pseg));
592 1.4.2.2 yamt for (;;) {
593 1.4.2.2 yamt DPRINTF(VOLUMES, (" at pseg %"PRIu64"\n", ri->pseg));
594 1.4.2.2 yamt error = nilfs_load_segsum(nilfsdev, ri);
595 1.4.2.2 yamt if (error)
596 1.4.2.2 yamt break;
597 1.4.2.2 yamt
598 1.4.2.2 yamt segsum = &ri->segsum;
599 1.4.2.2 yamt
600 1.4.2.2 yamt /* try to load super root */
601 1.4.2.2 yamt if (nilfs_rw16(segsum->ss_flags) & NILFS_SS_SR) {
602 1.4.2.2 yamt DPRINTF(VOLUMES, (" try super root\n"));
603 1.4.2.2 yamt error = nilfs_load_super_root(nilfsdev, ri);
604 1.4.2.2 yamt if (error)
605 1.4.2.2 yamt break; /* confused */
606 1.4.2.2 yamt /* wipe current list of ri */
607 1.4.2.2 yamt while (!STAILQ_EMPTY(&ri_list)) {
608 1.4.2.2 yamt i_ri = STAILQ_FIRST(&ri_list);
609 1.4.2.2 yamt STAILQ_REMOVE_HEAD(&ri_list, next);
610 1.4.2.2 yamt free(i_ri, M_NILFSTEMP);
611 1.4.2.2 yamt }
612 1.4.2.2 yamt super = &nilfsdev->super;
613 1.4.2.2 yamt
614 1.4.2.2 yamt super->s_last_pseg = nilfs_rw64(ri->pseg);
615 1.4.2.2 yamt super->s_last_cno = cno++;
616 1.4.2.2 yamt super->s_last_seq = segsum->ss_seq;
617 1.4.2.2 yamt super->s_state = nilfs_rw16(NILFS_VALID_FS);
618 1.4.2.2 yamt } else {
619 1.4.2.2 yamt STAILQ_INSERT_TAIL(&ri_list, ri, next);
620 1.4.2.2 yamt ori = ri;
621 1.4.2.2 yamt ri = malloc(sizeof(struct nilfs_recover_info),
622 1.4.2.2 yamt M_NILFSTEMP, M_WAITOK);
623 1.4.2.2 yamt memset(ri, 0, sizeof(struct nilfs_recover_info));
624 1.4.2.2 yamt ri->segnum = ori->segnum;
625 1.4.2.2 yamt ri->pseg = ori->pseg;
626 1.4.2.2 yamt /* segsum keeps pointing to the `old' ri */
627 1.4.2.2 yamt }
628 1.4.2.2 yamt
629 1.4.2.2 yamt /* continue to the next pseg */
630 1.4.2.2 yamt segsum_size = nilfs_rw32(segsum->ss_sumbytes);
631 1.4.2.2 yamt nsumblk = (segsum_size - 1) / nilfsdev->blocksize + 1;
632 1.4.2.2 yamt nfileblk = nilfs_rw32(segsum->ss_nblocks) - nsumblk;
633 1.4.2.2 yamt
634 1.4.2.2 yamt /* calculate next partial segment location */
635 1.4.2.2 yamt ri->pseg += nsumblk + nfileblk;
636 1.4.2.2 yamt
637 1.4.2.2 yamt /* did we reach the end of the segment? if so, go to the next */
638 1.4.2.2 yamt nilfs_get_segment_range(nilfsdev, ri->segnum, &seg_start, &seg_end);
639 1.4.2.2 yamt if (ri->pseg >= seg_end)
640 1.4.2.2 yamt ri->pseg = nilfs_rw64(segsum->ss_next);
641 1.4.2.2 yamt ri->segnum = nilfs_get_segnum_of_block(nilfsdev, ri->pseg);
642 1.4.2.2 yamt }
643 1.4.2.2 yamt
644 1.4.2.2 yamt /*
645 1.4.2.2 yamt * XXX No roll-forward yet of the remaining partial segments.
646 1.4.2.2 yamt */
647 1.4.2.2 yamt
648 1.4.2.2 yamt /* wipe current list of ri */
649 1.4.2.2 yamt while (!STAILQ_EMPTY(&ri_list)) {
650 1.4.2.2 yamt i_ri = STAILQ_FIRST(&ri_list);
651 1.4.2.2 yamt STAILQ_REMOVE_HEAD(&ri_list, next);
652 1.4.2.2 yamt printf("nilfs: ignoring pseg at %"PRIu64"\n", i_ri->pseg);
653 1.4.2.2 yamt free(i_ri, M_NILFSTEMP);
654 1.4.2.2 yamt }
655 1.4.2.2 yamt free(ri, M_NILFSTEMP);
656 1.4.2.2 yamt }
657 1.4.2.2 yamt
658 1.4.2.2 yamt /* --------------------------------------------------------------------- */
659 1.4.2.2 yamt
660 1.4.2.2 yamt /*
661 1.4.2.2 yamt * Genfs interfacing
662 1.4.2.2 yamt *
663 1.4.2.2 yamt * static const struct genfs_ops nilfs_genfsops = {
664 1.4.2.2 yamt * .gop_size = genfs_size,
665 1.4.2.2 yamt * size of transfers
666 1.4.2.2 yamt * .gop_alloc = nilfs_gop_alloc,
667 1.4.2.2 yamt * allocate len bytes at offset
668 1.4.2.2 yamt * .gop_write = genfs_gop_write,
669 1.4.2.2 yamt * putpages interface code
670 1.4.2.2 yamt * .gop_markupdate = nilfs_gop_markupdate,
671 1.4.2.2 yamt * set update/modify flags etc.
672 1.4.2.2 yamt * }
673 1.4.2.2 yamt */
674 1.4.2.2 yamt
675 1.4.2.2 yamt /*
676 1.4.2.2 yamt * Callback from genfs to allocate len bytes at offset off; only called when
677 1.4.2.2 yamt * filling up gaps in the allocation.
678 1.4.2.2 yamt */
679 1.4.2.2 yamt static int
680 1.4.2.2 yamt nilfs_gop_alloc(struct vnode *vp, off_t off,
681 1.4.2.2 yamt off_t len, int flags, kauth_cred_t cred)
682 1.4.2.2 yamt {
683 1.4.2.2 yamt DPRINTF(NOTIMPL, ("nilfs_gop_alloc not implemented\n"));
684 1.4.2.2 yamt DPRINTF(ALLOC, ("nilfs_gop_alloc called for %"PRIu64" bytes\n", len));
685 1.4.2.2 yamt
686 1.4.2.2 yamt return 0;
687 1.4.2.2 yamt }
688 1.4.2.2 yamt
689 1.4.2.2 yamt
690 1.4.2.2 yamt /*
691 1.4.2.2 yamt * callback from genfs to update our flags
692 1.4.2.2 yamt */
693 1.4.2.2 yamt static void
694 1.4.2.2 yamt nilfs_gop_markupdate(struct vnode *vp, int flags)
695 1.4.2.2 yamt {
696 1.4.2.2 yamt struct nilfs_node *nilfs_node = VTOI(vp);
697 1.4.2.2 yamt u_long mask = 0;
698 1.4.2.2 yamt
699 1.4.2.2 yamt if ((flags & GOP_UPDATE_ACCESSED) != 0) {
700 1.4.2.2 yamt mask = IN_ACCESS;
701 1.4.2.2 yamt }
702 1.4.2.2 yamt if ((flags & GOP_UPDATE_MODIFIED) != 0) {
703 1.4.2.2 yamt if (vp->v_type == VREG) {
704 1.4.2.2 yamt mask |= IN_CHANGE | IN_UPDATE;
705 1.4.2.2 yamt } else {
706 1.4.2.2 yamt mask |= IN_MODIFY;
707 1.4.2.2 yamt }
708 1.4.2.2 yamt }
709 1.4.2.2 yamt if (mask) {
710 1.4.2.2 yamt nilfs_node->i_flags |= mask;
711 1.4.2.2 yamt }
712 1.4.2.2 yamt }
713 1.4.2.2 yamt
714 1.4.2.2 yamt
715 1.4.2.2 yamt static const struct genfs_ops nilfs_genfsops = {
716 1.4.2.2 yamt .gop_size = genfs_size,
717 1.4.2.2 yamt .gop_alloc = nilfs_gop_alloc,
718 1.4.2.2 yamt .gop_write = genfs_gop_write_rwmap,
719 1.4.2.2 yamt .gop_markupdate = nilfs_gop_markupdate,
720 1.4.2.2 yamt };
721 1.4.2.2 yamt
722 1.4.2.2 yamt /* --------------------------------------------------------------------- */
723 1.4.2.2 yamt
724 1.4.2.2 yamt static void
725 1.4.2.2 yamt nilfs_register_node(struct nilfs_node *node)
726 1.4.2.2 yamt {
727 1.4.2.2 yamt struct nilfs_mount *ump;
728 1.4.2.2 yamt struct nilfs_node *chk;
729 1.4.2.2 yamt uint32_t hashline;
730 1.4.2.2 yamt
731 1.4.2.2 yamt ump = node->ump;
732 1.4.2.2 yamt mutex_enter(&ump->ihash_lock);
733 1.4.2.2 yamt
734 1.4.2.2 yamt /* add to our hash table */
735 1.4.2.2 yamt hashline = nilfs_calchash(node->ino) & NILFS_INODE_HASHMASK;
736 1.4.2.2 yamt #ifdef DEBUG
737 1.4.2.2 yamt LIST_FOREACH(chk, &ump->nilfs_nodes[hashline], hashchain) {
738 1.4.2.2 yamt assert(chk);
739 1.4.2.2 yamt if (chk->ino == node->ino)
740 1.4.2.2 yamt panic("Double node entered\n");
741 1.4.2.2 yamt }
742 1.4.2.2 yamt #else
743 1.4.2.2 yamt chk = NULL;
744 1.4.2.2 yamt #endif
745 1.4.2.2 yamt LIST_INSERT_HEAD(&ump->nilfs_nodes[hashline], node, hashchain);
746 1.4.2.2 yamt
747 1.4.2.2 yamt mutex_exit(&ump->ihash_lock);
748 1.4.2.2 yamt }
749 1.4.2.2 yamt
750 1.4.2.2 yamt
751 1.4.2.2 yamt static void
752 1.4.2.2 yamt nilfs_deregister_node(struct nilfs_node *node)
753 1.4.2.2 yamt {
754 1.4.2.2 yamt struct nilfs_mount *ump;
755 1.4.2.2 yamt
756 1.4.2.2 yamt ump = node->ump;
757 1.4.2.2 yamt mutex_enter(&ump->ihash_lock);
758 1.4.2.2 yamt
759 1.4.2.2 yamt /* remove from hash list */
760 1.4.2.2 yamt LIST_REMOVE(node, hashchain);
761 1.4.2.2 yamt
762 1.4.2.2 yamt mutex_exit(&ump->ihash_lock);
763 1.4.2.2 yamt }
764 1.4.2.2 yamt
765 1.4.2.2 yamt
766 1.4.2.2 yamt static struct nilfs_node *
767 1.4.2.2 yamt nilfs_hash_lookup(struct nilfs_mount *ump, ino_t ino)
768 1.4.2.2 yamt {
769 1.4.2.2 yamt struct nilfs_node *node;
770 1.4.2.2 yamt struct vnode *vp;
771 1.4.2.2 yamt uint32_t hashline;
772 1.4.2.2 yamt
773 1.4.2.2 yamt loop:
774 1.4.2.2 yamt mutex_enter(&ump->ihash_lock);
775 1.4.2.2 yamt
776 1.4.2.2 yamt /* search our hash table */
777 1.4.2.2 yamt hashline = nilfs_calchash(ino) & NILFS_INODE_HASHMASK;
778 1.4.2.2 yamt LIST_FOREACH(node, &ump->nilfs_nodes[hashline], hashchain) {
779 1.4.2.2 yamt assert(node);
780 1.4.2.2 yamt if (node->ino == ino) {
781 1.4.2.2 yamt vp = node->vnode;
782 1.4.2.2 yamt assert(vp);
783 1.4.2.2 yamt mutex_enter(&vp->v_interlock);
784 1.4.2.2 yamt mutex_exit(&ump->ihash_lock);
785 1.4.2.2 yamt if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
786 1.4.2.2 yamt goto loop;
787 1.4.2.2 yamt return node;
788 1.4.2.2 yamt }
789 1.4.2.2 yamt }
790 1.4.2.2 yamt mutex_exit(&ump->ihash_lock);
791 1.4.2.2 yamt
792 1.4.2.2 yamt return NULL;
793 1.4.2.2 yamt }
794 1.4.2.2 yamt
795 1.4.2.2 yamt
796 1.4.2.2 yamt /* node action implementators */
797 1.4.2.2 yamt extern int (**nilfs_vnodeop_p)(void *);
798 1.4.2.2 yamt
799 1.4.2.2 yamt int
800 1.4.2.2 yamt nilfs_get_node_raw(struct nilfs_device *nilfsdev, struct nilfs_mount *ump,
801 1.4.2.2 yamt uint64_t ino, struct nilfs_inode *inode, struct nilfs_node **nodep)
802 1.4.2.2 yamt {
803 1.4.2.2 yamt struct nilfs_node *node;
804 1.4.2.2 yamt struct vnode *nvp;
805 1.4.2.2 yamt struct mount *mp;
806 1.4.2.2 yamt int (**vnodeops)(void *);
807 1.4.2.2 yamt int error;
808 1.4.2.2 yamt
809 1.4.2.2 yamt *nodep = NULL;
810 1.4.2.2 yamt vnodeops = nilfs_vnodeop_p;
811 1.4.2.2 yamt
812 1.4.2.2 yamt /* associate with mountpoint if present*/
813 1.4.2.2 yamt mp = ump? ump->vfs_mountp : NULL;
814 1.4.2.2 yamt error = getnewvnode(VT_NILFS, mp, vnodeops, &nvp);
815 1.4.2.2 yamt if (error)
816 1.4.2.2 yamt return error;
817 1.4.2.2 yamt
818 1.4.2.2 yamt /* lock node */
819 1.4.2.2 yamt error = vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY);
820 1.4.2.2 yamt if (error) {
821 1.4.2.2 yamt nvp->v_data = NULL;
822 1.4.2.2 yamt ungetnewvnode(nvp);
823 1.4.2.2 yamt return error;
824 1.4.2.2 yamt }
825 1.4.2.2 yamt
826 1.4.2.2 yamt node = pool_get(&nilfs_node_pool, PR_WAITOK);
827 1.4.2.2 yamt memset(node, 0, sizeof(struct nilfs_node));
828 1.4.2.2 yamt
829 1.4.2.2 yamt /* crosslink */
830 1.4.2.2 yamt node->vnode = nvp;
831 1.4.2.2 yamt node->ump = ump;
832 1.4.2.2 yamt node->nilfsdev = nilfsdev;
833 1.4.2.2 yamt nvp->v_data = node;
834 1.4.2.2 yamt
835 1.4.2.2 yamt /* initiase nilfs node */
836 1.4.2.2 yamt node->ino = ino;
837 1.4.2.2 yamt node->inode = *inode;
838 1.4.2.2 yamt node->lockf = NULL;
839 1.4.2.2 yamt
840 1.4.2.2 yamt /* needed? */
841 1.4.2.2 yamt mutex_init(&node->node_mutex, MUTEX_DEFAULT, IPL_NONE);
842 1.4.2.2 yamt cv_init(&node->node_lock, "nilfs_nlk");
843 1.4.2.2 yamt
844 1.4.2.2 yamt /* initialise genfs */
845 1.4.2.2 yamt genfs_node_init(nvp, &nilfs_genfsops);
846 1.4.2.2 yamt
847 1.4.2.2 yamt /* check if we're fetching the root */
848 1.4.2.2 yamt if (ino == NILFS_ROOT_INO)
849 1.4.2.2 yamt nvp->v_vflag |= VV_ROOT;
850 1.4.2.2 yamt
851 1.4.2.2 yamt /* update vnode's file type XXX is there a function for this? */
852 1.4.2.2 yamt nvp->v_type = VREG;
853 1.4.2.2 yamt if (S_ISDIR(inode->i_mode))
854 1.4.2.2 yamt nvp->v_type = VDIR;
855 1.4.2.2 yamt if (S_ISLNK(inode->i_mode))
856 1.4.2.2 yamt nvp->v_type = VLNK;
857 1.4.2.2 yamt #if 0
858 1.4.2.2 yamt if (S_ISCHR(inode->i_mode))
859 1.4.2.2 yamt nvp->v_type = VCHR;
860 1.4.2.2 yamt if (S_ISBLK(inode->i_mode))
861 1.4.2.2 yamt nvp->v_type = VBLK;
862 1.4.2.2 yamt #endif
863 1.4.2.2 yamt /* XXX what else? */
864 1.4.2.2 yamt
865 1.4.2.2 yamt /* fixup inode size for system nodes */
866 1.4.2.2 yamt if ((ino < NILFS_USER_INO) && (ino != NILFS_ROOT_INO)) {
867 1.4.2.2 yamt DPRINTF(VOLUMES, ("NEED TO GET my size for inode %"PRIu64"\n",
868 1.4.2.2 yamt ino));
869 1.4.2.2 yamt /* for now set it to maximum, -1 is illegal */
870 1.4.2.2 yamt inode->i_size = nilfs_rw64(((uint64_t) -2));
871 1.4.2.2 yamt }
872 1.4.2.2 yamt
873 1.4.2.2 yamt uvm_vnp_setsize(nvp, nilfs_rw64(inode->i_size));
874 1.4.2.2 yamt
875 1.4.2.2 yamt if (ump)
876 1.4.2.2 yamt nilfs_register_node(node);
877 1.4.2.2 yamt
878 1.4.2.2 yamt /* return node */
879 1.4.2.2 yamt *nodep = node;
880 1.4.2.2 yamt return 0;
881 1.4.2.2 yamt }
882 1.4.2.2 yamt
883 1.4.2.2 yamt
884 1.4.2.2 yamt int
885 1.4.2.2 yamt nilfs_get_node(struct nilfs_mount *ump, uint64_t ino, struct nilfs_node **nodep)
886 1.4.2.2 yamt {
887 1.4.2.2 yamt struct nilfs_device *nilfsdev;
888 1.4.2.2 yamt struct nilfs_inode inode, *entry;
889 1.4.2.2 yamt struct buf *bp;
890 1.4.2.2 yamt uint64_t ivblocknr;
891 1.4.2.2 yamt uint32_t entry_in_block;
892 1.4.2.2 yamt int error;
893 1.4.2.2 yamt
894 1.4.2.2 yamt /* lookup node in hash table */
895 1.4.2.2 yamt *nodep = nilfs_hash_lookup(ump, ino);
896 1.4.2.2 yamt if (*nodep)
897 1.4.2.2 yamt return 0;
898 1.4.2.2 yamt
899 1.4.2.2 yamt /* lock to disallow simultanious creation of same udf_node */
900 1.4.2.2 yamt mutex_enter(&ump->get_node_lock);
901 1.4.2.2 yamt
902 1.4.2.2 yamt /* relookup since it could be created while waiting for the mutex */
903 1.4.2.2 yamt *nodep = nilfs_hash_lookup(ump, ino);
904 1.4.2.2 yamt if (*nodep) {
905 1.4.2.2 yamt mutex_exit(&ump->get_node_lock);
906 1.4.2.2 yamt return 0;
907 1.4.2.2 yamt }
908 1.4.2.2 yamt
909 1.4.2.2 yamt /* create new inode; XXX check could be handier */
910 1.4.2.2 yamt if ((ino < NILFS_ATIME_INO) && (ino != NILFS_ROOT_INO)) {
911 1.4.2.2 yamt printf("nilfs_get_node: system ino %"PRIu64" not in mount "
912 1.4.2.2 yamt "point!\n", ino);
913 1.4.2.2 yamt mutex_exit(&ump->get_node_lock);
914 1.4.2.2 yamt return ENOENT;
915 1.4.2.2 yamt }
916 1.4.2.2 yamt
917 1.4.2.2 yamt /* lookup inode in the ifile */
918 1.4.2.2 yamt DPRINTF(NODE, ("lookup ino %"PRIu64"\n", ino));
919 1.4.2.2 yamt
920 1.4.2.2 yamt /* lookup inode structure in mountpoints ifile */
921 1.4.2.2 yamt nilfsdev = ump->nilfsdev;
922 1.4.2.2 yamt nilfs_mdt_trans(&nilfsdev->ifile_mdt, ino, &ivblocknr, &entry_in_block);
923 1.4.2.2 yamt
924 1.4.2.2 yamt error = nilfs_bread(ump->ifile_node, ivblocknr, NOCRED, 0, &bp);
925 1.4.2.2 yamt if (error) {
926 1.4.2.2 yamt mutex_exit(&ump->get_node_lock);
927 1.4.2.2 yamt return ENOENT;
928 1.4.2.2 yamt }
929 1.4.2.2 yamt
930 1.4.2.2 yamt /* get inode entry */
931 1.4.2.2 yamt entry = (struct nilfs_inode *) bp->b_data + entry_in_block;
932 1.4.2.2 yamt inode = *entry;
933 1.4.2.2 yamt brelse(bp, BC_AGE);
934 1.4.2.2 yamt
935 1.4.2.2 yamt /* get node */
936 1.4.2.2 yamt error = nilfs_get_node_raw(ump->nilfsdev, ump, ino, &inode, nodep);
937 1.4.2.2 yamt mutex_exit(&ump->get_node_lock);
938 1.4.2.2 yamt
939 1.4.2.2 yamt return error;
940 1.4.2.2 yamt }
941 1.4.2.2 yamt
942 1.4.2.2 yamt
943 1.4.2.2 yamt void
944 1.4.2.2 yamt nilfs_dispose_node(struct nilfs_node **nodep)
945 1.4.2.2 yamt {
946 1.4.2.2 yamt struct vnode *vp;
947 1.4.2.2 yamt struct nilfs_node *node;
948 1.4.2.2 yamt
949 1.4.2.2 yamt /* protect against rogue values */
950 1.4.2.2 yamt if (!*nodep)
951 1.4.2.2 yamt return;
952 1.4.2.2 yamt
953 1.4.2.2 yamt node = *nodep;
954 1.4.2.2 yamt vp = node->vnode;
955 1.4.2.2 yamt
956 1.4.2.2 yamt /* remove dirhash if present */
957 1.4.2.2 yamt dirhash_purge(&node->dir_hash);
958 1.4.2.2 yamt
959 1.4.2.2 yamt /* remove from our hash lookup table */
960 1.4.2.2 yamt if (node->ump)
961 1.4.2.2 yamt nilfs_deregister_node(node);
962 1.4.2.2 yamt
963 1.4.2.2 yamt /* destroy our locks */
964 1.4.2.2 yamt mutex_destroy(&node->node_mutex);
965 1.4.2.2 yamt cv_destroy(&node->node_lock);
966 1.4.2.2 yamt
967 1.4.2.2 yamt /* dissociate from our vnode */
968 1.4.2.2 yamt genfs_node_destroy(node->vnode);
969 1.4.2.2 yamt vp->v_data = NULL;
970 1.4.2.2 yamt
971 1.4.2.2 yamt /* free our associated memory */
972 1.4.2.2 yamt pool_put(&nilfs_node_pool, node);
973 1.4.2.2 yamt
974 1.4.2.2 yamt *nodep = NULL;
975 1.4.2.2 yamt }
976 1.4.2.2 yamt
977 1.4.2.2 yamt
978 1.4.2.2 yamt void
979 1.4.2.2 yamt nilfs_itimes(struct nilfs_node *node, struct timespec *acc,
980 1.4.2.2 yamt struct timespec *mod, struct timespec *birth)
981 1.4.2.2 yamt {
982 1.4.2.2 yamt }
983 1.4.2.2 yamt
984 1.4.2.2 yamt
985 1.4.2.2 yamt int
986 1.4.2.2 yamt nilfs_update(struct vnode *node, struct timespec *acc,
987 1.4.2.2 yamt struct timespec *mod, struct timespec *birth, int updflags)
988 1.4.2.2 yamt {
989 1.4.2.2 yamt return EROFS;
990 1.4.2.2 yamt }
991 1.4.2.2 yamt
992 1.4.2.2 yamt
993 1.4.2.2 yamt int
994 1.4.2.2 yamt nilfs_chsize(struct vnode *vp, u_quad_t newsize, kauth_cred_t cred)
995 1.4.2.2 yamt {
996 1.4.2.2 yamt return EROFS;
997 1.4.2.2 yamt }
998 1.4.2.2 yamt
999 1.4.2.2 yamt
1000 1.4.2.2 yamt
1001 1.4.2.2 yamt int
1002 1.4.2.2 yamt nilfs_grow_node(struct nilfs_node *node, uint64_t new_size)
1003 1.4.2.2 yamt {
1004 1.4.2.2 yamt return EROFS;
1005 1.4.2.2 yamt }
1006 1.4.2.2 yamt
1007 1.4.2.2 yamt
1008 1.4.2.2 yamt int
1009 1.4.2.2 yamt nilfs_shrink_node(struct nilfs_node *node, uint64_t new_size)
1010 1.4.2.2 yamt {
1011 1.4.2.2 yamt return EROFS;
1012 1.4.2.2 yamt }
1013 1.4.2.2 yamt
1014 1.4.2.2 yamt
1015 1.4.2.2 yamt static int
1016 1.4.2.2 yamt dirhash_fill(struct nilfs_node *dir_node)
1017 1.4.2.2 yamt {
1018 1.4.2.2 yamt struct vnode *dvp = dir_node->vnode;
1019 1.4.2.2 yamt struct dirhash *dirh;
1020 1.4.2.2 yamt struct nilfs_dir_entry *ndirent;
1021 1.4.2.2 yamt struct dirent dirent;
1022 1.4.2.2 yamt struct buf *bp;
1023 1.4.2.2 yamt uint64_t file_size, diroffset, blkoff;
1024 1.4.2.2 yamt uint64_t blocknr;
1025 1.4.2.2 yamt uint32_t blocksize = dir_node->nilfsdev->blocksize;
1026 1.4.2.2 yamt uint8_t *pos, name_len;
1027 1.4.2.2 yamt int error;
1028 1.4.2.2 yamt
1029 1.4.2.2 yamt DPRINTF(CALL, ("dirhash_fill called\n"));
1030 1.4.2.2 yamt
1031 1.4.2.2 yamt if (dvp->v_type != VDIR)
1032 1.4.2.2 yamt return ENOTDIR;
1033 1.4.2.2 yamt
1034 1.4.2.2 yamt /* make sure we have a dirhash to work on */
1035 1.4.2.2 yamt dirh = dir_node->dir_hash;
1036 1.4.2.2 yamt KASSERT(dirh);
1037 1.4.2.2 yamt KASSERT(dirh->refcnt > 0);
1038 1.4.2.2 yamt
1039 1.4.2.2 yamt if (dirh->flags & DIRH_BROKEN)
1040 1.4.2.2 yamt return EIO;
1041 1.4.2.2 yamt
1042 1.4.2.2 yamt if (dirh->flags & DIRH_COMPLETE)
1043 1.4.2.2 yamt return 0;
1044 1.4.2.2 yamt
1045 1.4.2.2 yamt DPRINTF(DIRHASH, ("Filling directory hash\n"));
1046 1.4.2.2 yamt
1047 1.4.2.2 yamt /* make sure we have a clean dirhash to add to */
1048 1.4.2.2 yamt dirhash_purge_entries(dirh);
1049 1.4.2.2 yamt
1050 1.4.2.2 yamt /* get directory filesize */
1051 1.4.2.2 yamt file_size = nilfs_rw64(dir_node->inode.i_size);
1052 1.4.2.2 yamt
1053 1.4.2.2 yamt /* walk the directory */
1054 1.4.2.2 yamt error = 0;
1055 1.4.2.2 yamt diroffset = 0;
1056 1.4.2.2 yamt
1057 1.4.2.2 yamt blocknr = diroffset / blocksize;
1058 1.4.2.2 yamt blkoff = diroffset % blocksize;
1059 1.4.2.2 yamt error = nilfs_bread(dir_node, blocknr, NOCRED, 0, &bp);
1060 1.4.2.2 yamt if (error) {
1061 1.4.2.2 yamt dirh->flags |= DIRH_BROKEN;
1062 1.4.2.2 yamt dirhash_purge_entries(dirh);
1063 1.4.2.2 yamt return EIO;
1064 1.4.2.2 yamt }
1065 1.4.2.2 yamt while (diroffset < file_size) {
1066 1.4.2.2 yamt DPRINTF(READDIR, ("filldir : offset = %"PRIu64"\n",
1067 1.4.2.2 yamt diroffset));
1068 1.4.2.2 yamt if (blkoff >= blocksize) {
1069 1.4.2.2 yamt blkoff = 0; blocknr++;
1070 1.4.2.2 yamt brelse(bp, BC_AGE);
1071 1.4.2.2 yamt error = nilfs_bread(dir_node, blocknr, NOCRED, 0,
1072 1.4.2.2 yamt &bp);
1073 1.4.2.2 yamt if (error) {
1074 1.4.2.2 yamt dirh->flags |= DIRH_BROKEN;
1075 1.4.2.2 yamt dirhash_purge_entries(dirh);
1076 1.4.2.2 yamt return EIO;
1077 1.4.2.2 yamt }
1078 1.4.2.2 yamt }
1079 1.4.2.2 yamt
1080 1.4.2.2 yamt /* read in one dirent */
1081 1.4.2.2 yamt pos = (uint8_t *) bp->b_data + blkoff;
1082 1.4.2.2 yamt ndirent = (struct nilfs_dir_entry *) pos;
1083 1.4.2.2 yamt name_len = ndirent->name_len;
1084 1.4.2.2 yamt
1085 1.4.2.2 yamt memset(&dirent, 0, sizeof(struct dirent));
1086 1.4.2.2 yamt dirent.d_fileno = nilfs_rw64(ndirent->inode);
1087 1.4.2.2 yamt dirent.d_type = ndirent->file_type; /* 1:1 ? */
1088 1.4.2.2 yamt dirent.d_namlen = name_len;
1089 1.4.2.2 yamt strncpy(dirent.d_name, ndirent->name, name_len);
1090 1.4.2.2 yamt dirent.d_reclen = _DIRENT_SIZE(&dirent);
1091 1.4.2.2 yamt DPRINTF(DIRHASH, ("copying `%*.*s`\n", name_len,
1092 1.4.2.2 yamt name_len, dirent.d_name));
1093 1.4.2.2 yamt
1094 1.4.2.2 yamt /* XXX is it deleted? extra free space? */
1095 1.4.2.2 yamt dirhash_enter(dirh, &dirent, diroffset,
1096 1.4.2.2 yamt nilfs_rw16(ndirent->rec_len), 0);
1097 1.4.2.2 yamt
1098 1.4.2.2 yamt /* advance */
1099 1.4.2.2 yamt diroffset += nilfs_rw16(ndirent->rec_len);
1100 1.4.2.2 yamt blkoff += nilfs_rw16(ndirent->rec_len);
1101 1.4.2.2 yamt }
1102 1.4.2.2 yamt brelse(bp, BC_AGE);
1103 1.4.2.2 yamt
1104 1.4.2.2 yamt dirh->flags |= DIRH_COMPLETE;
1105 1.4.2.2 yamt
1106 1.4.2.2 yamt return 0;
1107 1.4.2.2 yamt }
1108 1.4.2.2 yamt
1109 1.4.2.2 yamt
1110 1.4.2.2 yamt int
1111 1.4.2.2 yamt nilfs_lookup_name_in_dir(struct vnode *dvp, const char *name, int namelen,
1112 1.4.2.2 yamt uint64_t *ino, int *found)
1113 1.4.2.2 yamt {
1114 1.4.2.2 yamt struct nilfs_node *dir_node = VTOI(dvp);
1115 1.4.2.2 yamt struct nilfs_dir_entry *ndirent;
1116 1.4.2.2 yamt struct dirhash *dirh;
1117 1.4.2.2 yamt struct dirhash_entry *dirh_ep;
1118 1.4.2.2 yamt struct buf *bp;
1119 1.4.2.2 yamt uint64_t diroffset, blkoff;
1120 1.4.2.2 yamt uint64_t blocknr;
1121 1.4.2.2 yamt uint32_t blocksize = dir_node->nilfsdev->blocksize;
1122 1.4.2.2 yamt uint8_t *pos;
1123 1.4.2.2 yamt int hit, error;
1124 1.4.2.2 yamt
1125 1.4.2.2 yamt /* set default return */
1126 1.4.2.2 yamt *found = 0;
1127 1.4.2.2 yamt
1128 1.4.2.2 yamt /* get our dirhash and make sure its read in */
1129 1.4.2.2 yamt dirhash_get(&dir_node->dir_hash);
1130 1.4.2.2 yamt error = dirhash_fill(dir_node);
1131 1.4.2.2 yamt if (error) {
1132 1.4.2.2 yamt dirhash_put(dir_node->dir_hash);
1133 1.4.2.2 yamt return error;
1134 1.4.2.2 yamt }
1135 1.4.2.2 yamt dirh = dir_node->dir_hash;
1136 1.4.2.2 yamt
1137 1.4.2.2 yamt /* allocate temporary space for fid */
1138 1.4.2.2 yamt
1139 1.4.2.2 yamt DPRINTF(DIRHASH, ("dirhash_lookup looking for `%*.*s`\n",
1140 1.4.2.2 yamt namelen, namelen, name));
1141 1.4.2.2 yamt
1142 1.4.2.2 yamt /* search our dirhash hits */
1143 1.4.2.2 yamt *ino = 0;
1144 1.4.2.2 yamt dirh_ep = NULL;
1145 1.4.2.2 yamt for (;;) {
1146 1.4.2.2 yamt hit = dirhash_lookup(dirh, name, namelen, &dirh_ep);
1147 1.4.2.2 yamt /* if no hit, abort the search */
1148 1.4.2.2 yamt if (!hit)
1149 1.4.2.2 yamt break;
1150 1.4.2.2 yamt
1151 1.4.2.2 yamt /* check this hit */
1152 1.4.2.2 yamt diroffset = dirh_ep->offset;
1153 1.4.2.2 yamt
1154 1.4.2.2 yamt blocknr = diroffset / blocksize;
1155 1.4.2.2 yamt blkoff = diroffset % blocksize;
1156 1.4.2.2 yamt error = nilfs_bread(dir_node, blocknr, NOCRED, 0, &bp);
1157 1.4.2.2 yamt if (error)
1158 1.4.2.2 yamt return EIO;
1159 1.4.2.2 yamt
1160 1.4.2.2 yamt /* read in one dirent */
1161 1.4.2.2 yamt pos = (uint8_t *) bp->b_data + blkoff;
1162 1.4.2.2 yamt ndirent = (struct nilfs_dir_entry *) pos;
1163 1.4.2.2 yamt
1164 1.4.2.2 yamt DPRINTF(DIRHASH, ("dirhash_lookup\tchecking `%*.*s`\n",
1165 1.4.2.2 yamt ndirent->name_len, ndirent->name_len, ndirent->name));
1166 1.4.2.2 yamt
1167 1.4.2.2 yamt /* see if its our entry */
1168 1.4.2.2 yamt KASSERT(ndirent->name_len == namelen);
1169 1.4.2.2 yamt if (strncmp(ndirent->name, name, namelen) == 0) {
1170 1.4.2.2 yamt *found = 1;
1171 1.4.2.2 yamt *ino = nilfs_rw64(ndirent->inode);
1172 1.4.2.2 yamt brelse(bp, BC_AGE);
1173 1.4.2.2 yamt break;
1174 1.4.2.2 yamt }
1175 1.4.2.2 yamt brelse(bp, BC_AGE);
1176 1.4.2.2 yamt }
1177 1.4.2.2 yamt
1178 1.4.2.2 yamt dirhash_put(dir_node->dir_hash);
1179 1.4.2.2 yamt
1180 1.4.2.2 yamt return error;
1181 1.4.2.2 yamt }
1182 1.4.2.2 yamt
1183 1.4.2.2 yamt
1184 1.4.2.2 yamt int
1185 1.4.2.2 yamt nilfs_dir_detach(struct nilfs_mount *ump, struct nilfs_node *dir_node, struct nilfs_node *node, struct componentname *cnp)
1186 1.4.2.2 yamt {
1187 1.4.2.2 yamt return EROFS;
1188 1.4.2.2 yamt }
1189 1.4.2.2 yamt
1190 1.4.2.2 yamt
1191 1.4.2.2 yamt int
1192 1.4.2.2 yamt nilfs_dir_attach(struct nilfs_mount *ump, struct nilfs_node *dir_node, struct nilfs_node *node, struct vattr *vap, struct componentname *cnp)
1193 1.4.2.2 yamt {
1194 1.4.2.2 yamt return EROFS;
1195 1.4.2.2 yamt }
1196 1.4.2.2 yamt
1197 1.4.2.2 yamt
1198 1.4.2.2 yamt /* XXX return vnode? */
1199 1.4.2.2 yamt int
1200 1.4.2.2 yamt nilfs_create_node(struct vnode *dvp, struct vnode **vpp, struct vattr *vap, struct componentname *cnp)
1201 1.4.2.2 yamt {
1202 1.4.2.2 yamt return EROFS;
1203 1.4.2.2 yamt }
1204 1.4.2.2 yamt
1205 1.4.2.2 yamt
1206 1.4.2.2 yamt void
1207 1.4.2.2 yamt nilfs_delete_node(struct nilfs_node *node)
1208 1.4.2.2 yamt {
1209 1.4.2.2 yamt }
1210 1.4.2.2 yamt
1211 1.4.2.2 yamt
1212