reorganization to move ufsmount ops to be vnode ops; blkatoff
[unix-history] / usr / src / sys / ufs / lfs / lfs_inode.c
CommitLineData
da7c5cc6 1/*
7795cb4d 2 * Copyright (c) 1986, 1989, 1991 Regents of the University of California.
7188ac27 3 * All rights reserved.
da7c5cc6 4 *
b702c21d 5 * %sccs.include.redist.c%
7188ac27 6 *
7795cb4d 7 * @(#)lfs_inode.c 7.46 (Berkeley) %G%
da7c5cc6 8 */
5d5124a1 9
29ad237c
KB
10#include <sys/param.h>
11#include <sys/systm.h>
12#include <sys/mount.h>
13#include <sys/proc.h>
14#include <sys/file.h>
15#include <sys/buf.h>
16#include <sys/vnode.h>
17#include <sys/kernel.h>
18#include <sys/malloc.h>
5d5124a1 19
7795cb4d
KB
20#include <ufs/ufs/quota.h>
21#include <ufs/ufs/inode.h>
22#include <ufs/ufs/ufsmount.h>
23#include <ufs/ufs/ufs_extern.h>
c6f5111d 24
7795cb4d
KB
25#include <ufs/lfs/lfs.h>
26#include <ufs/lfs/lfs_extern.h>
2bf2d153 27
0a0d4fba 28int
0b4d6502 29lfs_init()
5d5124a1 30{
29ad237c 31 return (ufs_init());
5d5124a1
BJ
32}
33
3ebac878 34/*
29ad237c
KB
35 * Look up an LFS dinode number to find its incore vnode. If not already
36 * in core, read it in from the specified device. Return the inode locked.
37 * Detection and handling of mount points must be done by the calling routine.
5d5124a1 38 */
0a0d4fba 39int
29ad237c
KB
40lfs_iget(pip, ino, ipp)
41 struct inode *pip;
7494ef16 42 ino_t ino;
7188ac27 43 struct inode **ipp;
5d5124a1 44{
7795cb4d 45 register struct lfs *fs;
29ad237c 46 register struct inode *ip;
7188ac27 47 struct buf *bp;
29ad237c 48 struct mount *mntp;
7795cb4d 49 struct vnode *vp;
29ad237c 50 dev_t dev;
0a0d4fba 51 int error;
2e64ab65 52
7795cb4d
KB
53 mntp = ITOV(pip)->v_mount;
54 fs = VFSTOUFS(mntp)->um_lfs;
29ad237c
KB
55 if (ino < ROOTINO)
56 return (EINVAL);
57
58 dev = pip->i_dev;
59 if ((*ipp = ufs_ihashget(dev, ino)) != NULL)
60 return (0);
0b4d6502
KB
61
62 /* Allocate new vnode/inode. */
7795cb4d 63 if (error = lfs_vcreate(mntp, ino, &vp)) {
29ad237c 64 *ipp = NULL;
7188ac27
KM
65 return (error);
66 }
7795cb4d 67 ip = VTOI(vp);
0b4d6502 68
1259a9f9
KM
69 /*
70 * Put it onto its hash chain and lock it so that other requests for
71 * this inode will block if they arrive while we are sleeping waiting
72 * for old data structures to be purged or for the contents of the
73 * disk portion of this inode to be read.
74 */
29ad237c 75 ufs_ihashins(ip);
0b4d6502 76
29ad237c 77 /* Read in the disk contents for the inode, copy into the inode. */
29ad237c
KB
78 if (error = bread(VFSTOUFS(mntp)->um_devvp, lfs_itod(fs, ino),
79 (int)fs->lfs_bsize, NOCRED, &bp)) {
bd4160ab
KM
80 /*
81 * The inode does not contain anything useful, so it would
29ad237c 82 * be misleading to leave it on its hash chain. Iput() will
7795cb4d 83 * return it to the free list.
bd4160ab
KM
84 */
85 remque(ip);
86 ip->i_forw = ip;
87 ip->i_back = ip;
29ad237c
KB
88
89 /* Unlock and discard unneeded inode. */
90 ufs_iput(ip);
7188ac27 91 brelse(bp);
29ad237c 92 *ipp = NULL;
1259a9f9 93 return (error);
7188ac27 94 }
0b4d6502 95 ip->i_din = *lfs_ifind(fs, ino, bp->b_un.b_dino);
1259a9f9 96 brelse(bp);
0b4d6502 97
7795cb4d
KB
98 /*
99 * Initialize the vnode from the inode, check for aliases. In all
100 * cases re-init ip, the underlying vnode/inode may have changed.
101 */
102 if (error = ufs_vinit(mntp, &vp)) {
29ad237c
KB
103 ufs_iput(ip);
104 *ipp = NULL;
105 return (error);
7188ac27 106 }
7795cb4d 107 *ipp = VTOI(vp);
7188ac27
KM
108 return (0);
109}
3ebac878 110
0a0d4fba 111int
29ad237c
KB
112lfs_iupdat(ip, ta, tm, waitfor)
113 register struct inode *ip;
114 struct timeval *ta, *tm;
115 int waitfor;
ff56f48a 116{
b5ea418e 117 /*
29ad237c
KB
118 * XXX
119 * This isn't right, but ufs_iupdat() isn't either.
b5ea418e 120 */
29ad237c
KB
121 ITIMES(ip, ta, tm);
122 return (0);
5d5124a1
BJ
123}
124
5d5124a1 125/*
29ad237c 126 * Truncate the inode ip to at most length size.
9c03b2c0
SL
127 *
128 * NB: triple indirect blocks are untested.
5d5124a1 129 */
29ad237c
KB
130/* ARGSUSED */
131int
0b4d6502 132lfs_itrunc(oip, length, flags)
28821bc5 133 register struct inode *oip;
4f083fd7 134 u_long length;
e038406d 135 int flags;
5d5124a1 136{
7795cb4d 137 register struct lfs *fs;
28821bc5 138 struct buf *bp;
29ad237c
KB
139 daddr_t lbn;
140 int error, offset, size;
4f083fd7 141
8986c97c 142 vnode_pager_setsize(ITOV(oip), length);
29ad237c
KB
143
144 /* If length is larger than the file, just update the times. */
7b2e4f05
SL
145 if (oip->i_size <= length) {
146 oip->i_flag |= ICHG|IUPD;
d5075120
KB
147 ITIMES(oip, &time, &time);
148 return (0);
7b2e4f05 149 }
29ad237c 150
c0bb1685 151 /*
29ad237c
KB
152 * Update the size of the file. If the file is not being truncated to
153 * a block boundry, the contents of the partial block following the end
154 * of the file must be zero'ed in case it ever become accessable again
155 * because of subsequent file growth.
28821bc5 156 */
29ad237c 157 fs = oip->i_lfs;
28821bc5 158 offset = blkoff(fs, length);
29ad237c 159 if (offset == 0)
28821bc5 160 oip->i_size = length;
29ad237c 161 else {
28821bc5 162 lbn = lblkno(fs, length);
4b61628b
KM
163#ifdef QUOTA
164 if (error = getinoquota(oip))
165 return (error);
d5075120
KB
166#endif
167 if (error = bread(ITOV(oip), lbn, fs->lfs_bsize, NOCRED, &bp))
7188ac27 168 return (error);
28821bc5 169 oip->i_size = length;
0b4d6502 170 size = blksize(fs); /* LFS */
8986c97c 171 (void) vnode_pager_uncache(ITOV(oip));
a5e62f37 172 bzero(bp->b_un.b_addr + offset, (unsigned)(size - offset));
9cf42d55 173 allocbuf(bp, size);
d5075120 174 lfs_bwrite(bp);
5d5124a1 175 }
29ad237c 176 /* BZERO INODE BLOCK POINTERS HERE, FOR CONSISTENCY XXX */
7188ac27 177}