lfs_syscalls.c revision 1.80 1 /* $NetBSD: lfs_syscalls.c,v 1.80 2003/02/17 23:48:20 perseant Exp $ */
2
3 /*-
4 * Copyright (c) 1999, 2000, 2001, 2002, 2003 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Konrad E. Schroder <perseant (at) hhhh.org>.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
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 the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the NetBSD
21 * Foundation, Inc. and its contributors.
22 * 4. Neither the name of The NetBSD Foundation nor the names of its
23 * contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
27 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
28 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
30 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
31 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
32 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
33 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
34 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
35 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 * POSSIBILITY OF SUCH DAMAGE.
37 */
38 /*-
39 * Copyright (c) 1991, 1993, 1994
40 * The Regents of the University of California. All rights reserved.
41 *
42 * Redistribution and use in source and binary forms, with or without
43 * modification, are permitted provided that the following conditions
44 * are met:
45 * 1. Redistributions of source code must retain the above copyright
46 * notice, this list of conditions and the following disclaimer.
47 * 2. Redistributions in binary form must reproduce the above copyright
48 * notice, this list of conditions and the following disclaimer in the
49 * documentation and/or other materials provided with the distribution.
50 * 3. All advertising materials mentioning features or use of this software
51 * must display the following acknowledgement:
52 * This product includes software developed by the University of
53 * California, Berkeley and its contributors.
54 * 4. Neither the name of the University nor the names of its contributors
55 * may be used to endorse or promote products derived from this software
56 * without specific prior written permission.
57 *
58 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
59 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
60 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
61 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
62 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
63 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
64 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
65 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
66 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
67 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
68 * SUCH DAMAGE.
69 *
70 * @(#)lfs_syscalls.c 8.10 (Berkeley) 5/14/95
71 */
72
73 #include <sys/cdefs.h>
74 __KERNEL_RCSID(0, "$NetBSD: lfs_syscalls.c,v 1.80 2003/02/17 23:48:20 perseant Exp $");
75
76 #define LFS /* for prototypes in syscallargs.h */
77
78 #include <sys/param.h>
79 #include <sys/systm.h>
80 #include <sys/proc.h>
81 #include <sys/buf.h>
82 #include <sys/mount.h>
83 #include <sys/vnode.h>
84 #include <sys/malloc.h>
85 #include <sys/kernel.h>
86
87 #include <sys/sa.h>
88 #include <sys/syscallargs.h>
89
90 #include <ufs/ufs/inode.h>
91 #include <ufs/ufs/ufsmount.h>
92 #include <ufs/ufs/ufs_extern.h>
93
94 #include <ufs/lfs/lfs.h>
95 #include <ufs/lfs/lfs_extern.h>
96
97 /* Max block count for lfs_markv() */
98 #define MARKV_MAXBLKCNT 65536
99
100 struct buf *lfs_fakebuf(struct lfs *, struct vnode *, int, size_t, caddr_t);
101 int lfs_fasthashget(dev_t, ino_t, struct vnode **);
102
103 int debug_cleaner = 0;
104 int clean_vnlocked = 0;
105 int clean_inlocked = 0;
106 int verbose_debug = 0;
107
108 pid_t lfs_cleaner_pid = 0;
109
110 extern int lfs_subsys_pages;
111 extern struct simplelock lfs_subsys_lock;
112
113 /*
114 * Definitions for the buffer free lists.
115 */
116 #define BQUEUES 4 /* number of free buffer queues */
117
118 #define BQ_LOCKED 0 /* super-blocks &c */
119 #define BQ_LRU 1 /* lru, useful buffers */
120 #define BQ_AGE 2 /* rubbish */
121 #define BQ_EMPTY 3 /* buffer headers with no memory */
122
123 extern TAILQ_HEAD(bqueues, buf) bufqueues[BQUEUES];
124
125 #define LFS_FORCE_WRITE UNASSIGNED
126
127 #define LFS_VREF_THRESHOLD 128
128
129 static int lfs_bmapv(struct proc *, fsid_t *, BLOCK_INFO *, int);
130 static int lfs_markv(struct proc *, fsid_t *, BLOCK_INFO *, int);
131 static void lfs_fakebuf_iodone(struct buf *);
132
133 /*
134 * sys_lfs_markv:
135 *
136 * This will mark inodes and blocks dirty, so they are written into the log.
137 * It will block until all the blocks have been written. The segment create
138 * time passed in the block_info and inode_info structures is used to decide
139 * if the data is valid for each block (in case some process dirtied a block
140 * or inode that is being cleaned between the determination that a block is
141 * live and the lfs_markv call).
142 *
143 * 0 on success
144 * -1/errno is return on error.
145 */
146 #ifdef USE_64BIT_SYSCALLS
147 int
148 sys_lfs_markv(struct proc *p, void *v, register_t *retval)
149 {
150 struct sys_lfs_markv_args /* {
151 syscallarg(fsid_t *) fsidp;
152 syscallarg(struct block_info *) blkiov;
153 syscallarg(int) blkcnt;
154 } */ *uap = v;
155 BLOCK_INFO *blkiov;
156 int blkcnt, error;
157 fsid_t fsid;
158
159 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
160 return (error);
161
162 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
163 return (error);
164
165 blkcnt = SCARG(uap, blkcnt);
166 if ((u_int) blkcnt > MARKV_MAXBLKCNT)
167 return (EINVAL);
168
169 blkiov = malloc(blkcnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
170 if ((error = copyin(SCARG(uap, blkiov), blkiov,
171 blkcnt * sizeof(BLOCK_INFO))) != 0)
172 goto out;
173
174 if ((error = lfs_markv(p, &fsid, blkiov, blkcnt)) == 0)
175 copyout(blkiov, SCARG(uap, blkiov),
176 blkcnt * sizeof(BLOCK_INFO));
177 out:
178 free(blkiov, M_SEGMENT);
179 return error;
180 }
181 #else
182 int
183 sys_lfs_markv(struct lwp *l, void *v, register_t *retval)
184 {
185 struct sys_lfs_markv_args /* {
186 syscallarg(fsid_t *) fsidp;
187 syscallarg(struct block_info *) blkiov;
188 syscallarg(int) blkcnt;
189 } */ *uap = v;
190 BLOCK_INFO *blkiov;
191 BLOCK_INFO_15 *blkiov15;
192 int i, blkcnt, error;
193 fsid_t fsid;
194
195 if ((error = suser(l->l_proc->p_ucred, &l->l_proc->p_acflag)) != 0)
196 return (error);
197
198 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
199 return (error);
200
201 blkcnt = SCARG(uap, blkcnt);
202 if ((u_int) blkcnt > MARKV_MAXBLKCNT)
203 return (EINVAL);
204
205 blkiov = malloc(blkcnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
206 blkiov15 = malloc(blkcnt * sizeof(BLOCK_INFO_15), M_SEGMENT, M_WAITOK);
207 if ((error = copyin(SCARG(uap, blkiov), blkiov15,
208 blkcnt * sizeof(BLOCK_INFO_15))) != 0)
209 goto out;
210
211 for (i = 0; i < blkcnt; i++) {
212 blkiov[i].bi_inode = blkiov15[i].bi_inode;
213 blkiov[i].bi_lbn = blkiov15[i].bi_lbn;
214 blkiov[i].bi_daddr = blkiov15[i].bi_daddr;
215 blkiov[i].bi_segcreate = blkiov15[i].bi_segcreate;
216 blkiov[i].bi_version = blkiov15[i].bi_version;
217 blkiov[i].bi_bp = blkiov15[i].bi_bp;
218 blkiov[i].bi_size = blkiov15[i].bi_size;
219 }
220
221 if ((error = lfs_markv(l->l_proc, &fsid, blkiov, blkcnt)) == 0) {
222 for (i = 0; i < blkcnt; i++) {
223 blkiov15[i].bi_inode = blkiov[i].bi_inode;
224 blkiov15[i].bi_lbn = blkiov[i].bi_lbn;
225 blkiov15[i].bi_daddr = blkiov[i].bi_daddr;
226 blkiov15[i].bi_segcreate = blkiov[i].bi_segcreate;
227 blkiov15[i].bi_version = blkiov[i].bi_version;
228 blkiov15[i].bi_bp = blkiov[i].bi_bp;
229 blkiov15[i].bi_size = blkiov[i].bi_size;
230 }
231 copyout(blkiov15, SCARG(uap, blkiov),
232 blkcnt * sizeof(BLOCK_INFO_15));
233 }
234 out:
235 free(blkiov, M_SEGMENT);
236 free(blkiov15, M_SEGMENT);
237 return error;
238 }
239 #endif
240
241 #define LFS_MARKV_MAX_BLOCKS (LFS_MAX_BUFS)
242
243 static int
244 lfs_markv(struct proc *p, fsid_t *fsidp, BLOCK_INFO *blkiov, int blkcnt)
245 {
246 BLOCK_INFO *blkp;
247 IFILE *ifp;
248 struct buf *bp, *nbp;
249 struct inode *ip = NULL;
250 struct lfs *fs;
251 struct mount *mntp;
252 struct vnode *vp;
253 #ifdef DEBUG_LFS
254 int vputc = 0, iwritten = 0;
255 #endif
256 ino_t lastino;
257 daddr_t b_daddr, v_daddr;
258 int cnt, error;
259 int do_again = 0;
260 int s;
261 #ifdef CHECK_COPYIN
262 int i;
263 #endif /* CHECK_COPYIN */
264 int numrefed = 0;
265 ino_t maxino;
266 size_t obsize;
267
268 /* number of blocks/inodes that we have already bwrite'ed */
269 int nblkwritten, ninowritten;
270
271 if ((mntp = vfs_getvfs(fsidp)) == NULL)
272 return (ENOENT);
273
274 fs = VFSTOUFS(mntp)->um_lfs;
275 maxino = (fragstoblks(fs, fsbtofrags(fs, VTOI(fs->lfs_ivnode)->i_ffs_blocks)) -
276 fs->lfs_cleansz - fs->lfs_segtabsz) * fs->lfs_ifpb;
277
278 cnt = blkcnt;
279
280 if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0)
281 return (error);
282
283 /*
284 * This seglock is just to prevent the fact that we might have to sleep
285 * from allowing the possibility that our blocks might become
286 * invalid.
287 *
288 * It is also important to note here that unless we specify SEGM_CKP,
289 * any Ifile blocks that we might be asked to clean will never get
290 * to the disk.
291 */
292 lfs_seglock(fs, SEGM_CLEAN | SEGM_CKP | SEGM_SYNC);
293
294 /* Mark blocks/inodes dirty. */
295 error = 0;
296
297 #ifdef DEBUG_LFS
298 /* Run through and count the inodes */
299 lastino = LFS_UNUSED_INUM;
300 for (blkp = blkiov; cnt--; ++blkp) {
301 if (lastino != blkp->bi_inode) {
302 lastino = blkp->bi_inode;
303 vputc++;
304 }
305 }
306 cnt = blkcnt;
307 printf("[%d/",vputc);
308 iwritten = 0;
309 #endif /* DEBUG_LFS */
310 /* these were inside the initialization for the for loop */
311 v_daddr = LFS_UNUSED_DADDR;
312 lastino = LFS_UNUSED_INUM;
313 nblkwritten = ninowritten = 0;
314 for (blkp = blkiov; cnt--; ++blkp)
315 {
316 if (blkp->bi_daddr == LFS_FORCE_WRITE)
317 printf("lfs_markv: warning: force-writing ino %d "
318 "lbn %lld\n",
319 blkp->bi_inode, (long long)blkp->bi_lbn);
320 /* Bounds-check incoming data, avoid panic for failed VGET */
321 if (blkp->bi_inode <= 0 || blkp->bi_inode >= maxino) {
322 error = EINVAL;
323 goto again;
324 }
325 /*
326 * Get the IFILE entry (only once) and see if the file still
327 * exists.
328 */
329 if (lastino != blkp->bi_inode) {
330 /*
331 * Finish the old file, if there was one. The presence
332 * of a usable vnode in vp is signaled by a valid v_daddr.
333 */
334 if (v_daddr != LFS_UNUSED_DADDR) {
335 #ifdef DEBUG_LFS
336 if (ip->i_flag & (IN_MODIFIED|IN_CLEANING))
337 iwritten++;
338 #endif
339 lfs_vunref(vp);
340 numrefed--;
341 }
342
343 /*
344 * Start a new file
345 */
346 lastino = blkp->bi_inode;
347 if (blkp->bi_inode == LFS_IFILE_INUM)
348 v_daddr = fs->lfs_idaddr;
349 else {
350 LFS_IENTRY(ifp, fs, blkp->bi_inode, bp);
351 /* XXX fix for force write */
352 v_daddr = ifp->if_daddr;
353 brelse(bp);
354 }
355 /* Don't force-write the ifile */
356 if (blkp->bi_inode == LFS_IFILE_INUM
357 && blkp->bi_daddr == LFS_FORCE_WRITE)
358 {
359 continue;
360 }
361 if (v_daddr == LFS_UNUSED_DADDR
362 && blkp->bi_daddr != LFS_FORCE_WRITE)
363 {
364 continue;
365 }
366
367 /* Get the vnode/inode. */
368 error = lfs_fastvget(mntp, blkp->bi_inode, v_daddr,
369 &vp,
370 (blkp->bi_lbn == LFS_UNUSED_LBN
371 ? blkp->bi_bp
372 : NULL));
373
374 if (!error) {
375 numrefed++;
376 }
377 if (error) {
378 #ifdef DEBUG_LFS
379 printf("lfs_markv: lfs_fastvget failed with %d (ino %d, segment %d)\n",
380 error, blkp->bi_inode,
381 dtosn(fs, blkp->bi_daddr));
382 #endif /* DEBUG_LFS */
383 /*
384 * If we got EAGAIN, that means that the
385 * Inode was locked. This is
386 * recoverable: just clean the rest of
387 * this segment, and let the cleaner try
388 * again with another. (When the
389 * cleaner runs again, this segment will
390 * sort high on the list, since it is
391 * now almost entirely empty.) But, we
392 * still set v_daddr = LFS_UNUSED_ADDR
393 * so as not to test this over and over
394 * again.
395 */
396 if (error == EAGAIN) {
397 error = 0;
398 do_again++;
399 }
400 #ifdef DIAGNOSTIC
401 else if (error != ENOENT)
402 panic("lfs_markv VFS_VGET FAILED");
403 #endif
404 /* lastino = LFS_UNUSED_INUM; */
405 v_daddr = LFS_UNUSED_DADDR;
406 vp = NULL;
407 ip = NULL;
408 continue;
409 }
410 ip = VTOI(vp);
411 ninowritten++;
412 } else if (v_daddr == LFS_UNUSED_DADDR) {
413 /*
414 * This can only happen if the vnode is dead (or
415 * in any case we can't get it...e.g., it is
416 * inlocked). Keep going.
417 */
418 continue;
419 }
420
421 /* Past this point we are guaranteed that vp, ip are valid. */
422
423 /* If this BLOCK_INFO didn't contain a block, keep going. */
424 if (blkp->bi_lbn == LFS_UNUSED_LBN) {
425 /* XXX need to make sure that the inode gets written in this case */
426 /* XXX but only write the inode if it's the right one */
427 if (blkp->bi_inode != LFS_IFILE_INUM) {
428 LFS_IENTRY(ifp, fs, blkp->bi_inode, bp);
429 if (ifp->if_daddr == blkp->bi_daddr
430 || blkp->bi_daddr == LFS_FORCE_WRITE)
431 {
432 LFS_SET_UINO(ip, IN_CLEANING);
433 }
434 brelse(bp);
435 }
436 continue;
437 }
438
439 b_daddr = 0;
440 if (blkp->bi_daddr != LFS_FORCE_WRITE) {
441 if (VOP_BMAP(vp, blkp->bi_lbn, NULL, &b_daddr, NULL) ||
442 dbtofsb(fs, b_daddr) != blkp->bi_daddr)
443 {
444 if (dtosn(fs,dbtofsb(fs, b_daddr))
445 == dtosn(fs,blkp->bi_daddr))
446 {
447 printf("lfs_markv: wrong da same seg: %llx vs %llx\n",
448 (long long)blkp->bi_daddr, (long long)dbtofsb(fs, b_daddr));
449 }
450 do_again++;
451 continue;
452 }
453 }
454
455 /*
456 * Check block sizes. The blocks being cleaned come from
457 * disk, so they should have the same size as their on-disk
458 * counterparts.
459 */
460 if (blkp->bi_lbn >= 0)
461 obsize = blksize(fs, ip, blkp->bi_lbn);
462 else
463 obsize = fs->lfs_bsize;
464 /* Check for fragment size change */
465 if (blkp->bi_lbn >= 0 && blkp->bi_lbn < NDADDR) {
466 obsize = ip->i_lfs_fragsize[blkp->bi_lbn];
467 }
468 if (obsize != blkp->bi_size) {
469 printf("lfs_markv: ino %d lbn %lld wrong size (%ld != %d), try again\n",
470 blkp->bi_inode, (long long)blkp->bi_lbn,
471 (long) obsize, blkp->bi_size);
472 do_again++;
473 continue;
474 }
475
476 /*
477 * If we get to here, then we are keeping the block. If
478 * it is an indirect block, we want to actually put it
479 * in the buffer cache so that it can be updated in the
480 * finish_meta section. If it's not, we need to
481 * allocate a fake buffer so that writeseg can perform
482 * the copyin and write the buffer.
483 */
484 if (ip->i_number != LFS_IFILE_INUM && blkp->bi_lbn >= 0) {
485 /* Data Block */
486 bp = lfs_fakebuf(fs, vp, blkp->bi_lbn,
487 blkp->bi_size, blkp->bi_bp);
488 /* Pretend we used bread() to get it */
489 bp->b_blkno = fsbtodb(fs, blkp->bi_daddr);
490 } else {
491 /* Indirect block or ifile */
492 if (blkp->bi_size != fs->lfs_bsize &&
493 ip->i_number != LFS_IFILE_INUM)
494 panic("lfs_markv: partial indirect block?"
495 " size=%d\n", blkp->bi_size);
496 bp = getblk(vp, blkp->bi_lbn, blkp->bi_size, 0, 0);
497 if (!(bp->b_flags & (B_DONE|B_DELWRI))) { /* B_CACHE */
498 /*
499 * The block in question was not found
500 * in the cache; i.e., the block that
501 * getblk() returned is empty. So, we
502 * can (and should) copy in the
503 * contents, because we've already
504 * determined that this was the right
505 * version of this block on disk.
506 *
507 * And, it can't have changed underneath
508 * us, because we have the segment lock.
509 */
510 error = copyin(blkp->bi_bp, bp->b_data, blkp->bi_size);
511 if (error)
512 goto err2;
513 }
514 }
515 if ((error = lfs_bwrite_ext(bp,BW_CLEAN)) != 0)
516 goto err2;
517
518 nblkwritten++;
519 /*
520 * XXX should account indirect blocks and ifile pages as well
521 */
522 if (nblkwritten + lblkno(fs, ninowritten * DINODE_SIZE)
523 > LFS_MARKV_MAX_BLOCKS) {
524 #ifdef DEBUG_LFS
525 printf("lfs_markv: writing %d blks %d inos\n",
526 nblkwritten, ninowritten);
527 #endif
528 lfs_segwrite(mntp, SEGM_CLEAN);
529 nblkwritten = ninowritten = 0;
530 }
531 }
532
533 /*
534 * Finish the old file, if there was one
535 */
536 if (v_daddr != LFS_UNUSED_DADDR) {
537 #ifdef DEBUG_LFS
538 if (ip->i_flag & (IN_MODIFIED|IN_CLEANING))
539 iwritten++;
540 #endif
541 lfs_vunref(vp);
542 numrefed--;
543 }
544
545 #ifdef DEBUG_LFS
546 printf("%d]",iwritten);
547 if (numrefed != 0) {
548 panic("lfs_markv: numrefed=%d", numrefed);
549 }
550 #endif
551
552 #ifdef DEBUG_LFS
553 printf("lfs_markv: writing %d blks %d inos (check point)\n",
554 nblkwritten, ninowritten);
555 #endif
556 /*
557 * The last write has to be SEGM_SYNC, because of calling semantics.
558 * It also has to be SEGM_CKP, because otherwise we could write
559 * over the newly cleaned data contained in a checkpoint, and then
560 * we'd be unhappy at recovery time.
561 */
562 lfs_segwrite(mntp, SEGM_CLEAN | SEGM_CKP | SEGM_SYNC);
563
564 lfs_segunlock(fs);
565
566 vfs_unbusy(mntp);
567 if (error)
568 return (error);
569 else if (do_again)
570 return EAGAIN;
571
572 return 0;
573
574 err2:
575 printf("lfs_markv err2\n");
576 lfs_vunref(vp);
577 --numrefed;
578
579 /* Free up fakebuffers -- have to take these from the LOCKED list */
580 again:
581 s = splbio();
582 for (bp = bufqueues[BQ_LOCKED].tqh_first; bp; bp = nbp) {
583 nbp = bp->b_freelist.tqe_next;
584 if (LFS_IS_MALLOC_BUF(bp)) {
585 if (bp->b_flags & B_BUSY) { /* not bloody likely */
586 bp->b_flags |= B_WANTED;
587 tsleep(bp, PRIBIO+1, "markv", 0);
588 splx(s);
589 goto again;
590 }
591 if (bp->b_flags & B_DELWRI)
592 fs->lfs_avail += btofsb(fs, bp->b_bcount);
593 bremfree(bp);
594 splx(s);
595 brelse(bp);
596 s = splbio();
597 }
598 }
599 splx(s);
600 lfs_segunlock(fs);
601 vfs_unbusy(mntp);
602 #ifdef DEBUG_LFS
603 if (numrefed != 0) {
604 panic("lfs_markv: numrefed=%d", numrefed);
605 }
606 #endif
607
608 return (error);
609 }
610
611 /*
612 * sys_lfs_bmapv:
613 *
614 * This will fill in the current disk address for arrays of blocks.
615 *
616 * 0 on success
617 * -1/errno is return on error.
618 */
619 #ifdef USE_64BIT_SYSCALLS
620 int
621 sys_lfs_bmapv(struct proc *p, void *v, register_t *retval)
622 {
623 struct sys_lfs_bmapv_args /* {
624 syscallarg(fsid_t *) fsidp;
625 syscallarg(struct block_info *) blkiov;
626 syscallarg(int) blkcnt;
627 } */ *uap = v;
628 BLOCK_INFO *blkiov;
629 int blkcnt, error;
630 fsid_t fsid;
631
632 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
633 return (error);
634
635 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
636 return (error);
637
638 blkcnt = SCARG(uap, blkcnt);
639 if ((u_int) blkcnt > SIZE_T_MAX / sizeof(BLOCK_INFO))
640 return (EINVAL);
641 blkiov = malloc(blkcnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
642 if ((error = copyin(SCARG(uap, blkiov), blkiov,
643 blkcnt * sizeof(BLOCK_INFO))) != 0)
644 goto out;
645
646 if ((error = lfs_bmapv(p, &fsid, blkiov, blkcnt)) == 0)
647 copyout(blkiov, SCARG(uap, blkiov),
648 blkcnt * sizeof(BLOCK_INFO));
649 out:
650 free(blkiov, M_SEGMENT);
651 return error;
652 }
653 #else
654 int
655 sys_lfs_bmapv(struct lwp *l, void *v, register_t *retval)
656 {
657 struct sys_lfs_bmapv_args /* {
658 syscallarg(fsid_t *) fsidp;
659 syscallarg(struct block_info *) blkiov;
660 syscallarg(int) blkcnt;
661 } */ *uap = v;
662 struct proc *p = l->l_proc;
663 BLOCK_INFO *blkiov;
664 BLOCK_INFO_15 *blkiov15;
665 int i, blkcnt, error;
666 fsid_t fsid;
667
668 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
669 return (error);
670
671 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
672 return (error);
673
674 blkcnt = SCARG(uap, blkcnt);
675 if ((u_int) blkcnt > SIZE_T_MAX / sizeof(BLOCK_INFO))
676 return (EINVAL);
677 blkiov = malloc(blkcnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
678 blkiov15 = malloc(blkcnt * sizeof(BLOCK_INFO_15), M_SEGMENT, M_WAITOK);
679 if ((error = copyin(SCARG(uap, blkiov), blkiov15,
680 blkcnt * sizeof(BLOCK_INFO_15))) != 0)
681 goto out;
682
683 for (i = 0; i < blkcnt; i++) {
684 blkiov[i].bi_inode = blkiov15[i].bi_inode;
685 blkiov[i].bi_lbn = blkiov15[i].bi_lbn;
686 blkiov[i].bi_daddr = blkiov15[i].bi_daddr;
687 blkiov[i].bi_segcreate = blkiov15[i].bi_segcreate;
688 blkiov[i].bi_version = blkiov15[i].bi_version;
689 blkiov[i].bi_bp = blkiov15[i].bi_bp;
690 blkiov[i].bi_size = blkiov15[i].bi_size;
691 }
692
693 if ((error = lfs_bmapv(p, &fsid, blkiov, blkcnt)) == 0) {
694 for (i = 0; i < blkcnt; i++) {
695 blkiov15[i].bi_inode = blkiov[i].bi_inode;
696 blkiov15[i].bi_lbn = blkiov[i].bi_lbn;
697 blkiov15[i].bi_daddr = blkiov[i].bi_daddr;
698 blkiov15[i].bi_segcreate = blkiov[i].bi_segcreate;
699 blkiov15[i].bi_version = blkiov[i].bi_version;
700 blkiov15[i].bi_bp = blkiov[i].bi_bp;
701 blkiov15[i].bi_size = blkiov[i].bi_size;
702 }
703 copyout(blkiov15, SCARG(uap, blkiov),
704 blkcnt * sizeof(BLOCK_INFO_15));
705 }
706 out:
707 free(blkiov, M_SEGMENT);
708 free(blkiov15, M_SEGMENT);
709 return error;
710 }
711 #endif
712
713 static int
714 lfs_bmapv(struct proc *p, fsid_t *fsidp, BLOCK_INFO *blkiov, int blkcnt)
715 {
716 BLOCK_INFO *blkp;
717 IFILE *ifp;
718 struct buf *bp;
719 struct inode *ip = NULL;
720 struct lfs *fs;
721 struct mount *mntp;
722 struct ufsmount *ump;
723 struct vnode *vp;
724 ino_t lastino;
725 daddr_t v_daddr;
726 int cnt, error;
727 int numrefed = 0;
728
729 lfs_cleaner_pid = p->p_pid;
730
731 if ((mntp = vfs_getvfs(fsidp)) == NULL)
732 return (ENOENT);
733
734 ump = VFSTOUFS(mntp);
735 if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0)
736 return (error);
737
738 cnt = blkcnt;
739
740 fs = VFSTOUFS(mntp)->um_lfs;
741
742 error = 0;
743
744 /* these were inside the initialization for the for loop */
745 v_daddr = LFS_UNUSED_DADDR;
746 lastino = LFS_UNUSED_INUM;
747 for (blkp = blkiov; cnt--; ++blkp)
748 {
749 /*
750 * Get the IFILE entry (only once) and see if the file still
751 * exists.
752 */
753 if (lastino != blkp->bi_inode) {
754 /*
755 * Finish the old file, if there was one. The presence
756 * of a usable vnode in vp is signaled by a valid
757 * v_daddr.
758 */
759 if (v_daddr != LFS_UNUSED_DADDR) {
760 lfs_vunref(vp);
761 numrefed--;
762 }
763
764 /*
765 * Start a new file
766 */
767 lastino = blkp->bi_inode;
768 if (blkp->bi_inode == LFS_IFILE_INUM)
769 v_daddr = fs->lfs_idaddr;
770 else {
771 LFS_IENTRY(ifp, fs, blkp->bi_inode, bp);
772 v_daddr = ifp->if_daddr;
773 brelse(bp);
774 }
775 if (v_daddr == LFS_UNUSED_DADDR) {
776 blkp->bi_daddr = LFS_UNUSED_DADDR;
777 continue;
778 }
779 /*
780 * A regular call to VFS_VGET could deadlock
781 * here. Instead, we try an unlocked access.
782 */
783 vp = ufs_ihashlookup(ump->um_dev, blkp->bi_inode);
784 if (vp != NULL && !(vp->v_flag & VXLOCK)) {
785 ip = VTOI(vp);
786 if (lfs_vref(vp)) {
787 v_daddr = LFS_UNUSED_DADDR;
788 continue;
789 }
790 numrefed++;
791 } else {
792 error = VFS_VGET(mntp, blkp->bi_inode, &vp);
793 if (error) {
794 #ifdef DEBUG_LFS
795 printf("lfs_bmapv: vget of ino %d failed with %d",blkp->bi_inode,error);
796 #endif
797 v_daddr = LFS_UNUSED_DADDR;
798 continue;
799 } else {
800 KASSERT(VOP_ISLOCKED(vp));
801 VOP_UNLOCK(vp, 0);
802 numrefed++;
803 }
804 }
805 ip = VTOI(vp);
806 } else if (v_daddr == LFS_UNUSED_DADDR) {
807 /*
808 * This can only happen if the vnode is dead.
809 * Keep going. Note that we DO NOT set the
810 * bi_addr to anything -- if we failed to get
811 * the vnode, for example, we want to assume
812 * conservatively that all of its blocks *are*
813 * located in the segment in question.
814 * lfs_markv will throw them out if we are
815 * wrong.
816 */
817 /* blkp->bi_daddr = LFS_UNUSED_DADDR; */
818 continue;
819 }
820
821 /* Past this point we are guaranteed that vp, ip are valid. */
822
823 if (blkp->bi_lbn == LFS_UNUSED_LBN) {
824 /*
825 * We just want the inode address, which is
826 * conveniently in v_daddr.
827 */
828 blkp->bi_daddr = v_daddr;
829 } else {
830 daddr_t bi_daddr;
831
832 /* XXX ondisk32 */
833 error = VOP_BMAP(vp, blkp->bi_lbn, NULL,
834 &bi_daddr, NULL);
835 if (error)
836 {
837 blkp->bi_daddr = LFS_UNUSED_DADDR;
838 continue;
839 }
840 blkp->bi_daddr = dbtofsb(fs, bi_daddr);
841 /* Fill in the block size, too */
842 if (blkp->bi_lbn >= 0)
843 blkp->bi_size = blksize(fs, ip, blkp->bi_lbn);
844 else
845 blkp->bi_size = fs->lfs_bsize;
846 }
847 }
848
849 /*
850 * Finish the old file, if there was one. The presence
851 * of a usable vnode in vp is signaled by a valid v_daddr.
852 */
853 if (v_daddr != LFS_UNUSED_DADDR) {
854 lfs_vunref(vp);
855 numrefed--;
856 }
857
858 #ifdef DEBUG_LFS
859 if (numrefed != 0) {
860 panic("lfs_bmapv: numrefed=%d", numrefed);
861 }
862 #endif
863
864 vfs_unbusy(mntp);
865
866 return 0;
867 }
868
869 /*
870 * sys_lfs_segclean:
871 *
872 * Mark the segment clean.
873 *
874 * 0 on success
875 * -1/errno is return on error.
876 */
877 int
878 sys_lfs_segclean(struct lwp *l, void *v, register_t *retval)
879 {
880 struct sys_lfs_segclean_args /* {
881 syscallarg(fsid_t *) fsidp;
882 syscallarg(u_long) segment;
883 } */ *uap = v;
884 struct lfs *fs;
885 struct mount *mntp;
886 fsid_t fsid;
887 int error;
888 unsigned long segnum;
889 struct proc *p = l->l_proc;
890
891 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0)
892 return (error);
893
894 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
895 return (error);
896 if ((mntp = vfs_getvfs(&fsid)) == NULL)
897 return (ENOENT);
898
899 fs = VFSTOUFS(mntp)->um_lfs;
900 segnum = SCARG(uap, segment);
901
902 if ((error = vfs_busy(mntp, LK_NOWAIT, NULL)) != 0)
903 return (error);
904
905 lfs_seglock(fs, SEGM_PROT);
906 error = lfs_do_segclean(fs, segnum);
907 lfs_segunlock(fs);
908 vfs_unbusy(mntp);
909 return error;
910 }
911
912 /*
913 * Actually mark the segment clean.
914 * Must be called with the segment lock held.
915 */
916 int
917 lfs_do_segclean(struct lfs *fs, unsigned long segnum)
918 {
919 struct buf *bp;
920 CLEANERINFO *cip;
921 SEGUSE *sup;
922
923 if (dtosn(fs, fs->lfs_curseg) == segnum) {
924 return (EBUSY);
925 }
926
927 LFS_SEGENTRY(sup, fs, segnum, bp);
928 if (sup->su_nbytes) {
929 printf("lfs_segclean: not cleaning segment %lu: %d live bytes\n",
930 segnum, sup->su_nbytes);
931 brelse(bp);
932 return (EBUSY);
933 }
934 if (sup->su_flags & SEGUSE_ACTIVE) {
935 brelse(bp);
936 return (EBUSY);
937 }
938 if (!(sup->su_flags & SEGUSE_DIRTY)) {
939 brelse(bp);
940 return (EALREADY);
941 }
942
943 fs->lfs_avail += segtod(fs, 1);
944 if (sup->su_flags & SEGUSE_SUPERBLOCK)
945 fs->lfs_avail -= btofsb(fs, LFS_SBPAD);
946 if (fs->lfs_version > 1 && segnum == 0 &&
947 fs->lfs_start < btofsb(fs, LFS_LABELPAD))
948 fs->lfs_avail -= btofsb(fs, LFS_LABELPAD) - fs->lfs_start;
949 fs->lfs_bfree += sup->su_nsums * btofsb(fs, fs->lfs_sumsize) +
950 btofsb(fs, sup->su_ninos * fs->lfs_ibsize);
951 fs->lfs_dmeta -= sup->su_nsums * btofsb(fs, fs->lfs_sumsize) +
952 btofsb(fs, sup->su_ninos * fs->lfs_ibsize);
953 if (fs->lfs_dmeta < 0)
954 fs->lfs_dmeta = 0;
955 sup->su_flags &= ~SEGUSE_DIRTY;
956 LFS_WRITESEGENTRY(sup, fs, segnum, bp);
957
958 LFS_CLEANERINFO(cip, fs, bp);
959 ++cip->clean;
960 --cip->dirty;
961 fs->lfs_nclean = cip->clean;
962 cip->bfree = fs->lfs_bfree;
963 cip->avail = fs->lfs_avail - fs->lfs_ravail;
964 (void) LFS_BWRITE_LOG(bp);
965 wakeup(&fs->lfs_avail);
966
967 return (0);
968 }
969
970 /*
971 * sys_lfs_segwait:
972 *
973 * This will block until a segment in file system fsid is written. A timeout
974 * in milliseconds may be specified which will awake the cleaner automatically.
975 * An fsid of -1 means any file system, and a timeout of 0 means forever.
976 *
977 * 0 on success
978 * 1 on timeout
979 * -1/errno is return on error.
980 */
981 int
982 sys_lfs_segwait(struct lwp *l, void *v, register_t *retval)
983 {
984 struct sys_lfs_segwait_args /* {
985 syscallarg(fsid_t *) fsidp;
986 syscallarg(struct timeval *) tv;
987 } */ *uap = v;
988 struct proc *p = l->l_proc;
989 struct mount *mntp;
990 struct timeval atv;
991 fsid_t fsid;
992 void *addr;
993 u_long timeout;
994 int error, s;
995
996 if ((error = suser(p->p_ucred, &p->p_acflag)) != 0) {
997 return (error);
998 }
999 if ((error = copyin(SCARG(uap, fsidp), &fsid, sizeof(fsid_t))) != 0)
1000 return (error);
1001 if ((mntp = vfs_getvfs(&fsid)) == NULL)
1002 addr = &lfs_allclean_wakeup;
1003 else
1004 addr = &VFSTOUFS(mntp)->um_lfs->lfs_nextseg;
1005
1006 if (SCARG(uap, tv)) {
1007 error = copyin(SCARG(uap, tv), &atv, sizeof(struct timeval));
1008 if (error)
1009 return (error);
1010 if (itimerfix(&atv))
1011 return (EINVAL);
1012 /*
1013 * XXX THIS COULD SLEEP FOREVER IF TIMEOUT IS {0,0}!
1014 * XXX IS THAT WHAT IS INTENDED?
1015 */
1016 s = splclock();
1017 timeradd(&atv, &time, &atv);
1018 timeout = hzto(&atv);
1019 splx(s);
1020 } else
1021 timeout = 0;
1022
1023 error = tsleep(addr, PCATCH | PUSER, "segment", timeout);
1024 return (error == ERESTART ? EINTR : 0);
1025 }
1026
1027 /*
1028 * VFS_VGET call specialized for the cleaner. The cleaner already knows the
1029 * daddr from the ifile, so don't look it up again. If the cleaner is
1030 * processing IINFO structures, it may have the ondisk inode already, so
1031 * don't go retrieving it again.
1032 *
1033 * we lfs_vref, and it is the caller's responsibility to lfs_vunref
1034 * when finished.
1035 */
1036 extern struct lock ufs_hashlock;
1037
1038 int
1039 lfs_fasthashget(dev_t dev, ino_t ino, struct vnode **vpp)
1040 {
1041 struct inode *ip;
1042
1043 /*
1044 * This is playing fast and loose. Someone may have the inode
1045 * locked, in which case they are going to be distinctly unhappy
1046 * if we trash something.
1047 */
1048 if ((*vpp = ufs_ihashlookup(dev, ino)) != NULL) {
1049 if ((*vpp)->v_flag & VXLOCK) {
1050 printf("lfs_fastvget: vnode VXLOCKed for ino %d\n",
1051 ino);
1052 clean_vnlocked++;
1053 #ifdef LFS_EAGAIN_FAIL
1054 return EAGAIN;
1055 #endif
1056 }
1057 ip = VTOI(*vpp);
1058 if (lfs_vref(*vpp)) {
1059 clean_inlocked++;
1060 return EAGAIN;
1061 }
1062 } else
1063 *vpp = NULL;
1064
1065 return (0);
1066 }
1067
1068 int
1069 lfs_fastvget(struct mount *mp, ino_t ino, daddr_t daddr, struct vnode **vpp, struct dinode *dinp)
1070 {
1071 struct inode *ip;
1072 struct dinode *dip;
1073 struct vnode *vp;
1074 struct ufsmount *ump;
1075 dev_t dev;
1076 int i, error, retries;
1077 struct buf *bp;
1078 struct lfs *fs;
1079
1080 ump = VFSTOUFS(mp);
1081 dev = ump->um_dev;
1082 fs = ump->um_lfs;
1083
1084 /*
1085 * Wait until the filesystem is fully mounted before allowing vget
1086 * to complete. This prevents possible problems with roll-forward.
1087 */
1088 while (fs->lfs_flags & LFS_NOTYET) {
1089 tsleep(&fs->lfs_flags, PRIBIO+1, "lfs_fnotyet", 0);
1090 }
1091 /*
1092 * This is playing fast and loose. Someone may have the inode
1093 * locked, in which case they are going to be distinctly unhappy
1094 * if we trash something.
1095 */
1096
1097 error = lfs_fasthashget(dev, ino, vpp);
1098 if (error != 0 || *vpp != NULL)
1099 return (error);
1100
1101 if ((error = getnewvnode(VT_LFS, mp, lfs_vnodeop_p, &vp)) != 0) {
1102 *vpp = NULL;
1103 return (error);
1104 }
1105
1106 do {
1107 error = lfs_fasthashget(dev, ino, vpp);
1108 if (error != 0 || *vpp != NULL) {
1109 ungetnewvnode(vp);
1110 return (error);
1111 }
1112 } while (lockmgr(&ufs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
1113
1114 /* Allocate new vnode/inode. */
1115 lfs_vcreate(mp, ino, vp);
1116
1117 /*
1118 * Put it onto its hash chain and lock it so that other requests for
1119 * this inode will block if they arrive while we are sleeping waiting
1120 * for old data structures to be purged or for the contents of the
1121 * disk portion of this inode to be read.
1122 */
1123 ip = VTOI(vp);
1124 ufs_ihashins(ip);
1125 lockmgr(&ufs_hashlock, LK_RELEASE, 0);
1126
1127 /*
1128 * XXX
1129 * This may not need to be here, logically it should go down with
1130 * the i_devvp initialization.
1131 * Ask Kirk.
1132 */
1133 ip->i_lfs = fs;
1134
1135 /* Read in the disk contents for the inode, copy into the inode. */
1136 if (dinp) {
1137 error = copyin(dinp, &ip->i_din.ffs_din, DINODE_SIZE);
1138 if (error) {
1139 printf("lfs_fastvget: dinode copyin failed for ino %d\n", ino);
1140 ufs_ihashrem(ip);
1141
1142 /* Unlock and discard unneeded inode. */
1143 lockmgr(&vp->v_lock, LK_RELEASE, &vp->v_interlock);
1144 lfs_vunref(vp);
1145 *vpp = NULL;
1146 return (error);
1147 }
1148 if (ip->i_number != ino)
1149 panic("lfs_fastvget: I was fed the wrong inode!");
1150 } else {
1151 retries = 0;
1152 again:
1153 error = bread(ump->um_devvp, fsbtodb(fs, daddr), fs->lfs_ibsize,
1154 NOCRED, &bp);
1155 if (error) {
1156 printf("lfs_fastvget: bread failed with %d\n",error);
1157 /*
1158 * The inode does not contain anything useful, so it
1159 * would be misleading to leave it on its hash chain.
1160 * Iput() will return it to the free list.
1161 */
1162 ufs_ihashrem(ip);
1163
1164 /* Unlock and discard unneeded inode. */
1165 lockmgr(&vp->v_lock, LK_RELEASE, &vp->v_interlock);
1166 lfs_vunref(vp);
1167 brelse(bp);
1168 *vpp = NULL;
1169 return (error);
1170 }
1171 dip = lfs_ifind(ump->um_lfs, ino, bp);
1172 if (dip == NULL) {
1173 /* Assume write has not completed yet; try again */
1174 bp->b_flags |= B_INVAL;
1175 brelse(bp);
1176 ++retries;
1177 if (retries > LFS_IFIND_RETRIES)
1178 panic("lfs_fastvget: dinode not found");
1179 printf("lfs_fastvget: dinode not found, retrying...\n");
1180 goto again;
1181 }
1182 ip->i_din.ffs_din = *dip;
1183 brelse(bp);
1184 }
1185 ip->i_ffs_effnlink = ip->i_ffs_nlink;
1186 ip->i_lfs_effnblks = ip->i_ffs_blocks;
1187 ip->i_lfs_osize = ip->i_ffs_size;
1188
1189 memset(ip->i_lfs_fragsize, 0, NDADDR * sizeof(*ip->i_lfs_fragsize));
1190 for (i = 0; i < NDADDR; i++)
1191 if (ip->i_ffs_db[i] != 0)
1192 ip->i_lfs_fragsize[i] = blksize(fs, ip, i);
1193
1194 /*
1195 * Initialize the vnode from the inode, check for aliases. In all
1196 * cases re-init ip, the underlying vnode/inode may have changed.
1197 */
1198 ufs_vinit(mp, lfs_specop_p, lfs_fifoop_p, &vp);
1199 #ifdef DEBUG_LFS
1200 if (vp->v_type == VNON) {
1201 printf("lfs_fastvget: ino %d is type VNON! (ifmt=%o, dinp=%p)\n",
1202 ip->i_number, (ip->i_ffs_mode & IFMT) >> 12, dinp);
1203 lfs_dump_dinode(&ip->i_din.ffs_din);
1204 #ifdef DDB
1205 Debugger();
1206 #endif
1207 }
1208 #endif /* DEBUG_LFS */
1209 /*
1210 * Finish inode initialization now that aliasing has been resolved.
1211 */
1212
1213 genfs_node_init(vp, &lfs_genfsops);
1214 ip->i_devvp = ump->um_devvp;
1215 VREF(ip->i_devvp);
1216 *vpp = vp;
1217 KASSERT(VOP_ISLOCKED(vp));
1218 VOP_UNLOCK(vp, 0);
1219
1220 uvm_vnp_setsize(vp, ip->i_ffs_size);
1221
1222 return (0);
1223 }
1224
1225 static void
1226 lfs_fakebuf_iodone(struct buf *bp)
1227 {
1228 struct buf *obp = bp->b_saveaddr;
1229
1230 if (!(obp->b_flags & (B_DELWRI | B_DONE)))
1231 obp->b_flags |= B_INVAL;
1232 bp->b_saveaddr = (caddr_t)(VTOI(obp->b_vp)->i_lfs);
1233 brelse(obp);
1234 lfs_callback(bp);
1235 }
1236
1237 struct buf *
1238 lfs_fakebuf(struct lfs *fs, struct vnode *vp, int lbn, size_t size, caddr_t uaddr)
1239 {
1240 struct buf *bp;
1241 int error;
1242
1243 struct buf *obp;
1244
1245 KASSERT(VTOI(vp)->i_number != LFS_IFILE_INUM);
1246
1247 /*
1248 * make corresponding buffer busy to avoid
1249 * reading blocks that isn't written yet.
1250 * it's needed because we'll update metadatas in lfs_updatemeta
1251 * before data pointed by them is actually written to disk.
1252 *
1253 * XXX no need to allocbuf.
1254 *
1255 * XXX this can cause buf starvation.
1256 */
1257 obp = getblk(vp, lbn, size, 0, 0);
1258 if (obp == NULL)
1259 panic("lfs_fakebuf: getblk failed");
1260
1261 bp = lfs_newbuf(VTOI(vp)->i_lfs, vp, lbn, size, LFS_NB_CLEAN);
1262 error = copyin(uaddr, bp->b_data, size);
1263 if (error) {
1264 lfs_freebuf(fs, bp);
1265 return NULL;
1266 }
1267 bp->b_saveaddr = obp;
1268 KDASSERT(bp->b_iodone == lfs_callback);
1269 bp->b_iodone = lfs_fakebuf_iodone;
1270
1271 #ifdef DIAGNOSTIC
1272 if (obp->b_flags & B_GATHERED)
1273 panic("lfs_fakebuf: gathered bp: %p, ino=%u, lbn=%d",
1274 bp, VTOI(vp)->i_number, lbn);
1275 #endif
1276 #if 0
1277 bp->b_saveaddr = (caddr_t)fs;
1278 ++fs->lfs_iocount;
1279 #endif
1280 bp->b_bufsize = size;
1281 bp->b_bcount = size;
1282 return (bp);
1283 }
1284