Commit | Line | Data |
---|---|---|
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 | 28 | int |
0b4d6502 | 29 | lfs_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 | 39 | int |
29ad237c KB |
40 | lfs_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 | 111 | int |
29ad237c KB |
112 | lfs_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 */ |
131 | int | |
0b4d6502 | 132 | lfs_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 | } |