151882Sbostic /*-
267037Sbostic * Copyright (c) 1991, 1993, 1994
363375Sbostic * The Regents of the University of California. All rights reserved.
451882Sbostic *
551882Sbostic * %sccs.include.redist.c%
651882Sbostic *
7*69420Smckusick * @(#)lfs_syscalls.c 8.10 (Berkeley) 05/14/95
851882Sbostic */
951882Sbostic
1051882Sbostic #include <sys/param.h>
1151882Sbostic #include <sys/proc.h>
1251882Sbostic #include <sys/buf.h>
1351882Sbostic #include <sys/mount.h>
1451882Sbostic #include <sys/vnode.h>
1551882Sbostic #include <sys/malloc.h>
1651882Sbostic #include <sys/kernel.h>
1751882Sbostic
1851882Sbostic #include <ufs/ufs/quota.h>
1951882Sbostic #include <ufs/ufs/inode.h>
2051882Sbostic #include <ufs/ufs/ufsmount.h>
2155941Sbostic #include <ufs/ufs/ufs_extern.h>
2251882Sbostic
2351882Sbostic #include <ufs/lfs/lfs.h>
2451882Sbostic #include <ufs/lfs/lfs_extern.h>
2556479Smargo #define BUMP_FIP(SP) \
2656479Smargo (SP)->fip = (FINFO *) (&(SP)->fip->fi_blocks[(SP)->fip->fi_nblocks])
2751882Sbostic
2856479Smargo #define INC_FINFO(SP) ++((SEGSUM *)((SP)->segsum))->ss_nfinfo
2956479Smargo #define DEC_FINFO(SP) --((SEGSUM *)((SP)->segsum))->ss_nfinfo
3056479Smargo
3156479Smargo /*
3256479Smargo * Before committing to add something to a segment summary, make sure there
3356479Smargo * is enough room. S is the bytes added to the summary.
3456479Smargo */
3556479Smargo #define CHECK_SEG(s) \
3656479Smargo if (sp->sum_bytes_left < (s)) { \
3756479Smargo (void) lfs_writeseg(fs, sp); \
3856479Smargo }
3955941Sbostic struct buf *lfs_fakebuf __P((struct vnode *, int, size_t, caddr_t));
4055941Sbostic
4169292Smckusick int debug_cleaner = 0;
4269292Smckusick int clean_vnlocked = 0;
4369292Smckusick int clean_inlocked = 0;
4469292Smckusick
4551882Sbostic /*
4651882Sbostic * lfs_markv:
4751882Sbostic *
4851882Sbostic * This will mark inodes and blocks dirty, so they are written into the log.
4951882Sbostic * It will block until all the blocks have been written. The segment create
5051882Sbostic * time passed in the block_info and inode_info structures is used to decide
5151882Sbostic * if the data is valid for each block (in case some process dirtied a block
5251882Sbostic * or inode that is being cleaned between the determination that a block is
5351882Sbostic * live and the lfs_markv call).
5451882Sbostic *
5551882Sbostic * 0 on success
5651882Sbostic * -1/errno is return on error.
5751882Sbostic */
5857770Smargo struct lfs_markv_args {
5965738Sbostic fsid_t *fsidp; /* file system */
6057770Smargo BLOCK_INFO *blkiov; /* block array */
6157770Smargo int blkcnt; /* count of block array entries */
6257770Smargo };
6351882Sbostic int
lfs_markv(p,uap,retval)6451882Sbostic lfs_markv(p, uap, retval)
6551882Sbostic struct proc *p;
6657770Smargo struct lfs_markv_args *uap;
6751882Sbostic int *retval;
6851882Sbostic {
6955941Sbostic struct segment *sp;
7051882Sbostic BLOCK_INFO *blkp;
7151882Sbostic IFILE *ifp;
7255941Sbostic struct buf *bp, **bpp;
7352087Sbostic struct inode *ip;
7451882Sbostic struct lfs *fs;
7551882Sbostic struct mount *mntp;
7651882Sbostic struct vnode *vp;
7765738Sbostic fsid_t fsid;
7852173Sbostic void *start;
7952087Sbostic ino_t lastino;
8068550Smckusick ufs_daddr_t b_daddr, v_daddr;
8151882Sbostic u_long bsize;
8251882Sbostic int cnt, error;
8351882Sbostic
8451882Sbostic if (error = suser(p->p_ucred, &p->p_acflag))
8551882Sbostic return (error);
8665738Sbostic
8765738Sbostic if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
8865738Sbostic return (error);
8968614Smckusick if ((mntp = vfs_getvfs(&fsid)) == NULL)
9051882Sbostic return (EINVAL);
9151882Sbostic
9251882Sbostic cnt = uap->blkcnt;
9352996Sbostic start = malloc(cnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
9455941Sbostic if (error = copyin(uap->blkiov, start, cnt * sizeof(BLOCK_INFO)))
9555941Sbostic goto err1;
9651882Sbostic
9755941Sbostic /* Mark blocks/inodes dirty. */
9852087Sbostic fs = VFSTOUFS(mntp)->um_lfs;
9952820Sbostic bsize = fs->lfs_bsize;
10055941Sbostic error = 0;
10155941Sbostic
10257073Smargo lfs_seglock(fs, SEGM_SYNC | SEGM_CLEAN);
10357073Smargo sp = fs->lfs_sp;
10455941Sbostic for (v_daddr = LFS_UNUSED_DADDR, lastino = LFS_UNUSED_INUM,
10555941Sbostic blkp = start; cnt--; ++blkp) {
10652087Sbostic /*
10752087Sbostic * Get the IFILE entry (only once) and see if the file still
10852087Sbostic * exists.
10952087Sbostic */
11052087Sbostic if (lastino != blkp->bi_inode) {
11155941Sbostic if (lastino != LFS_UNUSED_INUM) {
11256479Smargo /* Finish up last file */
11367037Sbostic if (sp->fip->fi_nblocks == 0) {
11456479Smargo DEC_FINFO(sp);
11556479Smargo sp->sum_bytes_left +=
11668550Smckusick sizeof(FINFO) - sizeof(ufs_daddr_t);
11767037Sbostic } else {
11867037Sbostic lfs_updatemeta(sp);
11967037Sbostic BUMP_FIP(sp);
12067037Sbostic }
12156479Smargo
12267037Sbostic lfs_writeinode(fs, sp, ip);
12367037Sbostic lfs_vunref(vp);
12455941Sbostic }
12556479Smargo
12656479Smargo /* Start a new file */
12756479Smargo CHECK_SEG(sizeof(FINFO));
12868550Smckusick sp->sum_bytes_left -= sizeof(FINFO) - sizeof(ufs_daddr_t);
12956479Smargo INC_FINFO(sp);
13056479Smargo sp->start_lbp = &sp->fip->fi_blocks[0];
13156479Smargo sp->vp = NULL;
13256369Smargo sp->fip->fi_version = blkp->bi_version;
13356369Smargo sp->fip->fi_nblocks = 0;
13456369Smargo sp->fip->fi_ino = blkp->bi_inode;
13552087Sbostic lastino = blkp->bi_inode;
13656161Sbostic if (blkp->bi_inode == LFS_IFILE_INUM)
13756161Sbostic v_daddr = fs->lfs_idaddr;
13856161Sbostic else {
13956161Sbostic LFS_IENTRY(ifp, fs, blkp->bi_inode, bp);
14056161Sbostic v_daddr = ifp->if_daddr;
14156161Sbostic brelse(bp);
14256161Sbostic }
14355941Sbostic if (v_daddr == LFS_UNUSED_DADDR)
14452087Sbostic continue;
14556479Smargo
14655941Sbostic /* Get the vnode/inode. */
14755941Sbostic if (lfs_fastvget(mntp, blkp->bi_inode, v_daddr, &vp,
14856369Smargo blkp->bi_lbn == LFS_UNUSED_LBN ?
14956369Smargo blkp->bi_bp : NULL)) {
15055941Sbostic #ifdef DIAGNOSTIC
15155941Sbostic printf("lfs_markv: VFS_VGET failed (%d)\n",
15255941Sbostic blkp->bi_inode);
15369292Smckusick panic("lfs_markv VFS_VGET FAILED");
15455941Sbostic #endif
15556029Sbostic lastino = LFS_UNUSED_INUM;
15656479Smargo v_daddr = LFS_UNUSED_DADDR;
15755941Sbostic continue;
15855941Sbostic }
15956029Sbostic sp->vp = vp;
16055941Sbostic ip = VTOI(vp);
16155941Sbostic } else if (v_daddr == LFS_UNUSED_DADDR)
16255941Sbostic continue;
16352087Sbostic
16455941Sbostic /* If this BLOCK_INFO didn't contain a block, keep going. */
16555941Sbostic if (blkp->bi_lbn == LFS_UNUSED_LBN)
16651882Sbostic continue;
16756479Smargo if (VOP_BMAP(vp, blkp->bi_lbn, NULL, &b_daddr, NULL) ||
16856161Sbostic b_daddr != blkp->bi_daddr)
16952173Sbostic continue;
17055941Sbostic /*
17155941Sbostic * If we got to here, then we are keeping the block. If it
17255941Sbostic * is an indirect block, we want to actually put it in the
17355941Sbostic * buffer cache so that it can be updated in the finish_meta
17455941Sbostic * section. If it's not, we need to allocate a fake buffer
17555941Sbostic * so that writeseg can perform the copyin and write the buffer.
17655941Sbostic */
17755941Sbostic if (blkp->bi_lbn >= 0) /* Data Block */
17855941Sbostic bp = lfs_fakebuf(vp, blkp->bi_lbn, bsize,
17955941Sbostic blkp->bi_bp);
18055941Sbostic else {
18157806Smckusick bp = getblk(vp, blkp->bi_lbn, bsize, 0, 0);
18256625Smargo if (!(bp->b_flags & (B_DELWRI | B_DONE | B_CACHE)) &&
18364527Sbostic (error = copyin(blkp->bi_bp, bp->b_data,
18469292Smckusick blkp->bi_size)))
18555941Sbostic goto err2;
18655941Sbostic if (error = VOP_BWRITE(bp))
18755941Sbostic goto err2;
18852087Sbostic }
18956029Sbostic while (lfs_gatherblock(sp, bp, NULL));
19051882Sbostic }
19156029Sbostic if (sp->vp) {
19267037Sbostic if (sp->fip->fi_nblocks == 0) {
19367037Sbostic DEC_FINFO(sp);
19467037Sbostic sp->sum_bytes_left +=
19568550Smckusick sizeof(FINFO) - sizeof(ufs_daddr_t);
19667037Sbostic } else
19767037Sbostic lfs_updatemeta(sp);
19867037Sbostic
19956029Sbostic lfs_writeinode(fs, sp, ip);
20057073Smargo lfs_vunref(vp);
20156029Sbostic }
20255941Sbostic (void) lfs_writeseg(fs, sp);
20355941Sbostic lfs_segunlock(fs);
20452173Sbostic free(start, M_SEGMENT);
20555941Sbostic return (error);
20667037Sbostic
20755941Sbostic /*
20867037Sbostic * XXX
20967037Sbostic * If we come in to error 2, we might have indirect blocks that were
21055941Sbostic * updated and now have bad block pointers. I don't know what to do
21155941Sbostic * about this.
21255941Sbostic */
21351882Sbostic
21457073Smargo err2: lfs_vunref(vp);
21555941Sbostic /* Free up fakebuffers */
21655941Sbostic for (bpp = --sp->cbpp; bpp >= sp->bpp; --bpp)
21755941Sbostic if ((*bpp)->b_flags & B_CALL) {
21855941Sbostic brelvp(*bpp);
21955941Sbostic free(*bpp, M_SEGMENT);
22055941Sbostic } else
22155941Sbostic brelse(*bpp);
22255941Sbostic lfs_segunlock(fs);
22365738Sbostic err1:
22452173Sbostic free(start, M_SEGMENT);
22567037Sbostic return (error);
22651882Sbostic }
22751882Sbostic
22851882Sbostic /*
22951882Sbostic * lfs_bmapv:
23051882Sbostic *
23152087Sbostic * This will fill in the current disk address for arrays of blocks.
23251882Sbostic *
23351882Sbostic * 0 on success
23451882Sbostic * -1/errno is return on error.
23551882Sbostic */
23657770Smargo struct lfs_bmapv_args {
23765738Sbostic fsid_t *fsidp; /* file system */
23857770Smargo BLOCK_INFO *blkiov; /* block array */
23957770Smargo int blkcnt; /* count of block array entries */
24057770Smargo };
24151882Sbostic int
lfs_bmapv(p,uap,retval)24251882Sbostic lfs_bmapv(p, uap, retval)
24351882Sbostic struct proc *p;
24457770Smargo struct lfs_bmapv_args *uap;
24551882Sbostic int *retval;
24651882Sbostic {
24751882Sbostic BLOCK_INFO *blkp;
24851882Sbostic struct mount *mntp;
24969292Smckusick struct ufsmount *ump;
25051882Sbostic struct vnode *vp;
25165738Sbostic fsid_t fsid;
25252173Sbostic void *start;
25368550Smckusick ufs_daddr_t daddr;
25452173Sbostic int cnt, error, step;
25551882Sbostic
25651882Sbostic if (error = suser(p->p_ucred, &p->p_acflag))
25751882Sbostic return (error);
25865738Sbostic
25965738Sbostic if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
26065738Sbostic return (error);
26168614Smckusick if ((mntp = vfs_getvfs(&fsid)) == NULL)
26251882Sbostic return (EINVAL);
26351882Sbostic
26451882Sbostic cnt = uap->blkcnt;
26552173Sbostic start = blkp = malloc(cnt * sizeof(BLOCK_INFO), M_SEGMENT, M_WAITOK);
26651882Sbostic if (error = copyin(uap->blkiov, blkp, cnt * sizeof(BLOCK_INFO))) {
26751882Sbostic free(blkp, M_SEGMENT);
26851882Sbostic return (error);
26951882Sbostic }
27051882Sbostic
27152173Sbostic for (step = cnt; step--; ++blkp) {
27256161Sbostic if (blkp->bi_lbn == LFS_UNUSED_LBN)
27356161Sbostic continue;
27469292Smckusick /*
27569292Smckusick * A regular call to VFS_VGET could deadlock
27669292Smckusick * here. Instead, we try an unlocked access.
27769292Smckusick */
27869292Smckusick ump = VFSTOUFS(mntp);
27969292Smckusick if ((vp =
28069292Smckusick ufs_ihashlookup(ump->um_dev, blkp->bi_inode)) != NULL) {
28169292Smckusick if (VOP_BMAP(vp, blkp->bi_lbn, NULL, &daddr, NULL))
28269292Smckusick daddr = LFS_UNUSED_DADDR;
28369292Smckusick } else if (VFS_VGET(mntp, blkp->bi_inode, &vp))
28452173Sbostic daddr = LFS_UNUSED_DADDR;
28569292Smckusick else {
28656479Smargo if (VOP_BMAP(vp, blkp->bi_lbn, NULL, &daddr, NULL))
28752173Sbostic daddr = LFS_UNUSED_DADDR;
28852173Sbostic vput(vp);
28952173Sbostic }
29052173Sbostic blkp->bi_daddr = daddr;
29152173Sbostic }
29252173Sbostic copyout(start, uap->blkiov, cnt * sizeof(BLOCK_INFO));
29352173Sbostic free(start, M_SEGMENT);
29451882Sbostic return (0);
29551882Sbostic }
29651882Sbostic
29751882Sbostic /*
29851882Sbostic * lfs_segclean:
29951882Sbostic *
30051882Sbostic * Mark the segment clean.
30151882Sbostic *
30251882Sbostic * 0 on success
30351882Sbostic * -1/errno is return on error.
30451882Sbostic */
30557770Smargo struct lfs_segclean_args {
30665738Sbostic fsid_t *fsidp; /* file system */
30757770Smargo u_long segment; /* segment number */
30857770Smargo };
30951882Sbostic int
lfs_segclean(p,uap,retval)31051882Sbostic lfs_segclean(p, uap, retval)
31151882Sbostic struct proc *p;
31257770Smargo struct lfs_segclean_args *uap;
31351882Sbostic int *retval;
31451882Sbostic {
31551928Sbostic CLEANERINFO *cip;
31651882Sbostic SEGUSE *sup;
31751882Sbostic struct buf *bp;
31851882Sbostic struct mount *mntp;
31951882Sbostic struct lfs *fs;
32065738Sbostic fsid_t fsid;
32151882Sbostic int error;
32251882Sbostic
32351882Sbostic if (error = suser(p->p_ucred, &p->p_acflag))
32451882Sbostic return (error);
32565738Sbostic
32665738Sbostic if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
32765738Sbostic return (error);
32868614Smckusick if ((mntp = vfs_getvfs(&fsid)) == NULL)
32951882Sbostic return (EINVAL);
33051882Sbostic
33151882Sbostic fs = VFSTOUFS(mntp)->um_lfs;
33251928Sbostic
33356369Smargo if (datosn(fs, fs->lfs_curseg) == uap->segment)
33456369Smargo return (EBUSY);
33556369Smargo
33651882Sbostic LFS_SEGENTRY(sup, fs, uap->segment, bp);
33756369Smargo if (sup->su_flags & SEGUSE_ACTIVE) {
33856369Smargo brelse(bp);
33967037Sbostic return (EBUSY);
34056369Smargo }
34155941Sbostic fs->lfs_avail += fsbtodb(fs, fs->lfs_ssize) - 1;
34255593Sbostic fs->lfs_bfree += (sup->su_nsums * LFS_SUMMARY_SIZE / DEV_BSIZE) +
34355593Sbostic sup->su_ninos * btodb(fs->lfs_bsize);
34451882Sbostic sup->su_flags &= ~SEGUSE_DIRTY;
34555941Sbostic (void) VOP_BWRITE(bp);
34651928Sbostic
34751928Sbostic LFS_CLEANERINFO(cip, fs, bp);
34851928Sbostic ++cip->clean;
34951928Sbostic --cip->dirty;
35055941Sbostic (void) VOP_BWRITE(bp);
35155941Sbostic wakeup(&fs->lfs_avail);
35251882Sbostic return (0);
35351882Sbostic }
35451882Sbostic
35551882Sbostic /*
35651882Sbostic * lfs_segwait:
35751882Sbostic *
35851882Sbostic * This will block until a segment in file system fsid is written. A timeout
35951882Sbostic * in milliseconds may be specified which will awake the cleaner automatically.
36051882Sbostic * An fsid of -1 means any file system, and a timeout of 0 means forever.
36151882Sbostic *
36251882Sbostic * 0 on success
36351882Sbostic * 1 on timeout
36451882Sbostic * -1/errno is return on error.
36551882Sbostic */
36657770Smargo struct lfs_segwait_args {
36765738Sbostic fsid_t *fsidp; /* file system */
36857770Smargo struct timeval *tv; /* timeout */
36957770Smargo };
37051882Sbostic int
lfs_segwait(p,uap,retval)37151882Sbostic lfs_segwait(p, uap, retval)
37251882Sbostic struct proc *p;
37357770Smargo struct lfs_segwait_args *uap;
37451882Sbostic int *retval;
37551882Sbostic {
37651882Sbostic extern int lfs_allclean_wakeup;
37751882Sbostic struct mount *mntp;
37851882Sbostic struct timeval atv;
37965738Sbostic fsid_t fsid;
38051882Sbostic void *addr;
38151882Sbostic u_long timeout;
38251882Sbostic int error, s;
38351882Sbostic
38455941Sbostic if (error = suser(p->p_ucred, &p->p_acflag)) {
38551882Sbostic return (error);
38655941Sbostic }
38751882Sbostic #ifdef WHEN_QUADS_WORK
38865738Sbostic if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
38965738Sbostic return (error);
39065738Sbostic if (fsid == (fsid_t)-1)
39151882Sbostic addr = &lfs_allclean_wakeup;
39251882Sbostic else {
39368614Smckusick if ((mntp = vfs_getvfs(&fsid)) == NULL)
39451882Sbostic return (EINVAL);
39551882Sbostic addr = &VFSTOUFS(mntp)->um_lfs->lfs_nextseg;
39651882Sbostic }
39751882Sbostic #else
39865738Sbostic if (error = copyin(uap->fsidp, &fsid, sizeof(fsid_t)))
39965738Sbostic return (error);
40068614Smckusick if ((mntp = vfs_getvfs(&fsid)) == NULL)
40151882Sbostic addr = &lfs_allclean_wakeup;
40251882Sbostic else
40351882Sbostic addr = &VFSTOUFS(mntp)->um_lfs->lfs_nextseg;
40451882Sbostic #endif
40551882Sbostic
40651882Sbostic if (uap->tv) {
40751882Sbostic if (error = copyin(uap->tv, &atv, sizeof(struct timeval)))
40851882Sbostic return (error);
40951882Sbostic if (itimerfix(&atv))
41051882Sbostic return (EINVAL);
41154764Smckusick s = splclock();
41254764Smckusick timevaladd(&atv, (struct timeval *)&time);
41351882Sbostic timeout = hzto(&atv);
41454277Sbostic splx(s);
41551882Sbostic } else
41651882Sbostic timeout = 0;
41751882Sbostic
41851882Sbostic error = tsleep(addr, PCATCH | PUSER, "segment", timeout);
41951882Sbostic return (error == ERESTART ? EINTR : 0);
42051882Sbostic }
42155941Sbostic
42255941Sbostic /*
42355941Sbostic * VFS_VGET call specialized for the cleaner. The cleaner already knows the
42455941Sbostic * daddr from the ifile, so don't look it up again. If the cleaner is
42555941Sbostic * processing IINFO structures, it may have the ondisk inode already, so
42655941Sbostic * don't go retrieving it again.
42755941Sbostic */
42855941Sbostic int
lfs_fastvget(mp,ino,daddr,vpp,dinp)42955941Sbostic lfs_fastvget(mp, ino, daddr, vpp, dinp)
43055941Sbostic struct mount *mp;
43155941Sbostic ino_t ino;
43268550Smckusick ufs_daddr_t daddr;
43355941Sbostic struct vnode **vpp;
43455941Sbostic struct dinode *dinp;
43555941Sbostic {
43655941Sbostic register struct inode *ip;
43755941Sbostic struct vnode *vp;
43855941Sbostic struct ufsmount *ump;
43955941Sbostic struct buf *bp;
44055941Sbostic dev_t dev;
44155941Sbostic int error;
44255941Sbostic
44355941Sbostic ump = VFSTOUFS(mp);
44455941Sbostic dev = ump->um_dev;
44557073Smargo /*
44657073Smargo * This is playing fast and loose. Someone may have the inode
44757073Smargo * locked, in which case they are going to be distinctly unhappy
44857073Smargo * if we trash something.
44957073Smargo */
45057073Smargo if ((*vpp = ufs_ihashlookup(dev, ino)) != NULL) {
45157073Smargo lfs_vref(*vpp);
45257073Smargo if ((*vpp)->v_flag & VXLOCK)
45369292Smckusick clean_vnlocked++;
45456191Smargo ip = VTOI(*vpp);
455*69420Smckusick if (lockstatus(&ip->i_lock))
45669292Smckusick clean_inlocked++;
45769292Smckusick if (!(ip->i_flag & IN_MODIFIED))
45856369Smargo ++ump->um_lfs->lfs_uinodes;
45964612Sbostic ip->i_flag |= IN_MODIFIED;
46055941Sbostic return (0);
46156191Smargo }
46255941Sbostic
46355941Sbostic /* Allocate new vnode/inode. */
46455941Sbostic if (error = lfs_vcreate(mp, ino, &vp)) {
46555941Sbostic *vpp = NULL;
46655941Sbostic return (error);
46755941Sbostic }
46855941Sbostic
46955941Sbostic /*
47055941Sbostic * Put it onto its hash chain and lock it so that other requests for
47155941Sbostic * this inode will block if they arrive while we are sleeping waiting
47255941Sbostic * for old data structures to be purged or for the contents of the
47355941Sbostic * disk portion of this inode to be read.
47455941Sbostic */
47555941Sbostic ip = VTOI(vp);
47655941Sbostic ufs_ihashins(ip);
47755941Sbostic
47855941Sbostic /*
47955941Sbostic * XXX
48055941Sbostic * This may not need to be here, logically it should go down with
48155941Sbostic * the i_devvp initialization.
48255941Sbostic * Ask Kirk.
48355941Sbostic */
48455941Sbostic ip->i_lfs = ump->um_lfs;
48555941Sbostic
48655941Sbostic /* Read in the disk contents for the inode, copy into the inode. */
48755941Sbostic if (dinp)
48855941Sbostic if (error = copyin(dinp, &ip->i_din, sizeof(struct dinode)))
48955941Sbostic return (error);
49055941Sbostic else {
49155941Sbostic if (error = bread(ump->um_devvp, daddr,
49255941Sbostic (int)ump->um_lfs->lfs_bsize, NOCRED, &bp)) {
49355941Sbostic /*
49455941Sbostic * The inode does not contain anything useful, so it
49555941Sbostic * would be misleading to leave it on its hash chain.
49655941Sbostic * Iput() will return it to the free list.
49755941Sbostic */
49855941Sbostic ufs_ihashrem(ip);
49955941Sbostic
50055941Sbostic /* Unlock and discard unneeded inode. */
50157073Smargo lfs_vunref(vp);
50255941Sbostic brelse(bp);
50355941Sbostic *vpp = NULL;
50455941Sbostic return (error);
50555941Sbostic }
50664527Sbostic ip->i_din =
50764527Sbostic *lfs_ifind(ump->um_lfs, ino, (struct dinode *)bp->b_data);
50855941Sbostic brelse(bp);
50955941Sbostic }
51055941Sbostic
51155941Sbostic /*
51255941Sbostic * Initialize the vnode from the inode, check for aliases. In all
51355941Sbostic * cases re-init ip, the underlying vnode/inode may have changed.
51455941Sbostic */
51555941Sbostic if (error = ufs_vinit(mp, lfs_specop_p, LFS_FIFOOPS, &vp)) {
51657073Smargo lfs_vunref(vp);
51755941Sbostic *vpp = NULL;
51855941Sbostic return (error);
51955941Sbostic }
52055941Sbostic /*
52155941Sbostic * Finish inode initialization now that aliasing has been resolved.
52255941Sbostic */
52355941Sbostic ip->i_devvp = ump->um_devvp;
52464612Sbostic ip->i_flag |= IN_MODIFIED;
52555941Sbostic ++ump->um_lfs->lfs_uinodes;
52655941Sbostic VREF(ip->i_devvp);
52755941Sbostic *vpp = vp;
52855941Sbostic return (0);
52955941Sbostic }
53055941Sbostic struct buf *
lfs_fakebuf(vp,lbn,size,uaddr)53155941Sbostic lfs_fakebuf(vp, lbn, size, uaddr)
53255941Sbostic struct vnode *vp;
53355941Sbostic int lbn;
53455941Sbostic size_t size;
53555941Sbostic caddr_t uaddr;
53655941Sbostic {
53755941Sbostic struct buf *bp;
53855941Sbostic
53955941Sbostic bp = lfs_newbuf(vp, lbn, 0);
54055941Sbostic bp->b_saveaddr = uaddr;
54155941Sbostic bp->b_bufsize = size;
54255941Sbostic bp->b_bcount = size;
54355941Sbostic bp->b_flags |= B_INVAL;
54467037Sbostic return (bp);
54555941Sbostic }
546