header files to vax directories
[unix-history] / usr / src / sys / ufs / lfs / lfs_inode.c
CommitLineData
3e63ef5b 1/* lfs_inode.c 4.24 82/09/06 */
5d5124a1
BJ
2
3#include "../h/param.h"
4#include "../h/systm.h"
5#include "../h/mount.h"
6#include "../h/dir.h"
7#include "../h/user.h"
8#include "../h/inode.h"
6459ebe0 9#include "../h/fs.h"
5d5124a1
BJ
10#include "../h/conf.h"
11#include "../h/buf.h"
12#include "../h/inline.h"
b4567e9c 13#ifdef QUOTA
4147b3f6
BJ
14#include "../h/quota.h"
15#endif
3e63ef5b 16#include "../h/kernel.h"
5d5124a1
BJ
17
18#define INOHSZ 63
3ebac878
RE
19#if ((INOHSZ&(INOHSZ-1)) == 0)
20#define INOHASH(dev,ino) (((dev)+(ino))&(INOHSZ-1))
21#else
5d5124a1 22#define INOHASH(dev,ino) (((dev)+(ino))%INOHSZ)
3ebac878
RE
23#endif
24
25union ihead { /* inode LRU cache, Chris Maltby */
26 union ihead *ih_head[2];
27 struct inode *ih_chain[2];
28} ihead[INOHSZ];
29
30struct inode *ifreeh, **ifreet;
5d5124a1
BJ
31
32/*
33 * Initialize hash links for inodes
34 * and build inode free list.
35 */
36ihinit()
37{
38 register int i;
75105cf0 39 register struct inode *ip = inode;
3ebac878 40 register union ihead *ih = ihead;
5d5124a1 41
3ebac878
RE
42 for (i = INOHSZ; --i >= 0; ih++) {
43 ih->ih_head[0] = ih;
44 ih->ih_head[1] = ih;
45 }
46 ifreeh = ip;
47 ifreet = &ip->i_freef;
48 ip->i_freeb = &ifreeh;
49 ip->i_forw = ip;
50 ip->i_back = ip;
51 for (i = ninode; --i > 0; ) {
52 ++ip;
53 ip->i_forw = ip;
54 ip->i_back = ip;
55 *ifreet = ip;
56 ip->i_freeb = ifreet;
57 ifreet = &ip->i_freef;
58 }
59 ip->i_freef = NULL;
5d5124a1
BJ
60}
61
3ebac878
RE
62#ifdef notdef
63/*
64 * Find an inode if it is incore.
65 * This is the equivalent, for inodes,
66 * of ``incore'' in bio.c or ``pfind'' in subr.c.
67 */
68struct inode *
69ifind(dev, ino)
70 dev_t dev;
71 ino_t ino;
72{
73 register struct inode *ip;
74 register union ihead *ih;
75
76 ih = &ihead[INOHASH(dev, ino)];
77 for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
78 if (ino==ip->i_number && dev==ip->i_dev)
79 return (ip);
80 return ((struct inode *)0);
81}
82#endif notdef
83
5d5124a1
BJ
84/*
85 * Look up an inode by device,inumber.
86 * If it is in core (in the inode structure),
87 * honor the locking protocol.
88 * If it is not in core, read it in from the
89 * specified device.
90 * If the inode is mounted on, perform
91 * the indicated indirection.
92 * In all cases, a pointer to a locked
93 * inode structure is returned.
94 *
5d5124a1
BJ
95 * panic: no imt -- if the mounted file
96 * system is not in the mount table.
97 * "cannot happen"
98 */
99struct inode *
6459ebe0 100iget(dev, fs, ino)
7494ef16 101 dev_t dev;
6459ebe0 102 register struct fs *fs;
7494ef16 103 ino_t ino;
5d5124a1 104{
32dc2b7e
RE
105 register struct inode *ip;
106 register union ihead *ih;
5d5124a1
BJ
107 register struct mount *mp;
108 register struct buf *bp;
109 register struct dinode *dp;
3ebac878 110 register struct inode *iq;
5d5124a1
BJ
111
112loop:
6459ebe0
KM
113 if (getfs(dev) != fs)
114 panic("iget: bad fs");
3ebac878
RE
115 ih = &ihead[INOHASH(dev, ino)];
116 for (ip = ih->ih_chain[0]; ip != (struct inode *)ih; ip = ip->i_forw)
7494ef16
BJ
117 if (ino == ip->i_number && dev == ip->i_dev) {
118 if ((ip->i_flag&ILOCK) != 0) {
5d5124a1
BJ
119 ip->i_flag |= IWANT;
120 sleep((caddr_t)ip, PINOD);
121 goto loop;
122 }
7494ef16 123 if ((ip->i_flag&IMOUNT) != 0) {
6459ebe0 124 for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
3ebac878
RE
125 if(mp->m_inodp == ip) {
126 dev = mp->m_dev;
127 fs = mp->m_bufp->b_un.b_fs;
128 ino = ROOTINO;
129 goto loop;
130 }
5d5124a1
BJ
131 panic("no imt");
132 }
3ebac878
RE
133 if (ip->i_count == 0) { /* ino on free list */
134 if (iq = ip->i_freef)
135 iq->i_freeb = ip->i_freeb;
136 else
137 ifreet = ip->i_freeb;
138 *ip->i_freeb = iq;
139 ip->i_freef = NULL;
140 ip->i_freeb = NULL;
141 }
5d5124a1
BJ
142 ip->i_count++;
143 ip->i_flag |= ILOCK;
144 return(ip);
145 }
3ebac878
RE
146
147 if ((ip = ifreeh) == NULL) {
945fbb1b 148 tablefull("inode");
5d5124a1
BJ
149 u.u_error = ENFILE;
150 return(NULL);
151 }
3ebac878
RE
152 if (iq = ip->i_freef)
153 iq->i_freeb = &ifreeh;
154 ifreeh = iq;
155 ip->i_freef = NULL;
156 ip->i_freeb = NULL;
157 /*
158 * Now to take inode off the hash chain it was on
159 * (initially, or after an iflush, it is on a "hash chain"
160 * consisting entirely of itself, and pointed to by no-one,
161 * but that doesn't matter), and put it on the chain for
162 * its new (ino, dev) pair
163 */
32dc2b7e
RE
164 remque(ip);
165 insque(ip, ih);
b4567e9c 166#ifdef QUOTA
89045c38
RE
167 dqrele(ip->i_dquot);
168#endif
5d5124a1 169 ip->i_dev = dev;
6459ebe0 170 ip->i_fs = fs;
5d5124a1
BJ
171 ip->i_number = ino;
172 ip->i_flag = ILOCK;
173 ip->i_count++;
6459ebe0
KM
174 ip->i_lastr = 0;
175 bp = bread(dev, fsbtodb(fs, itod(fs, ino)), fs->fs_bsize);
5d5124a1
BJ
176 /*
177 * Check I/O errors
178 */
7494ef16 179 if ((bp->b_flags&B_ERROR) != 0) {
5d5124a1 180 brelse(bp);
3ebac878
RE
181 /*
182 * the inode doesn't contain anything useful, so it would
183 * be misleading to leave it on its hash chain.
184 * 'iput' will take care of putting it back on the free list.
185 */
32dc2b7e 186 remque(ip);
3ebac878
RE
187 ip->i_forw = ip;
188 ip->i_back = ip;
189 /*
190 * we also loose its inumber, just in case (as iput
191 * doesn't do that any more) - but as it isn't on its
192 * hash chain, I doubt if this is really necessary .. kre
193 * (probably the two methods are interchangable)
194 */
195 ip->i_number = 0;
b4567e9c 196#ifdef QUOTA
89045c38
RE
197 ip->i_dquot = NODQUOT;
198#endif
5d5124a1
BJ
199 iput(ip);
200 return(NULL);
201 }
202 dp = bp->b_un.b_dino;
6459ebe0
KM
203 dp += itoo(fs, ino);
204 ip->i_ic = dp->di_ic;
5d5124a1 205 brelse(bp);
b4567e9c 206#ifdef QUOTA
89045c38
RE
207 if (ip->i_mode == 0)
208 ip->i_dquot = NODQUOT;
209 else
210 ip->i_dquot = inoquota(ip);
211#endif
6459ebe0 212 return (ip);
5d5124a1
BJ
213}
214
215/*
216 * Decrement reference count of
217 * an inode structure.
218 * On the last reference,
219 * write the inode out and if necessary,
220 * truncate and deallocate the file.
221 */
222iput(ip)
7494ef16 223 register struct inode *ip;
5d5124a1 224{
ff56f48a
KM
225
226 if ((ip->i_flag & ILOCK) == 0)
227 panic("iput");
228 iunlock(ip);
229 irele(ip);
230}
231
232irele(ip)
233 register struct inode *ip;
234{
5d5124a1
BJ
235 register int i, x;
236 register struct inode *jp;
6459ebe0 237 int mode;
5d5124a1 238
7494ef16 239 if (ip->i_count == 1) {
5d5124a1 240 ip->i_flag |= ILOCK;
7494ef16 241 if (ip->i_nlink <= 0) {
528f664c 242 itrunc(ip, 0);
6459ebe0 243 mode = ip->i_mode;
5d5124a1 244 ip->i_mode = 0;
85f9cfb8 245 ip->i_rdev = 0;
5d5124a1 246 ip->i_flag |= IUPD|ICHG;
6459ebe0 247 ifree(ip, ip->i_number, mode);
b4567e9c 248#ifdef QUOTA
89045c38
RE
249 chkiq(ip->i_dev, ip, ip->i_uid, 0);
250 dqrele(ip->i_dquot);
251 ip->i_dquot = NODQUOT;
252#endif
5d5124a1 253 }
3e63ef5b 254 IUPDAT(ip, &time.tv_sec, &time.tv_sec, 0);
ff56f48a 255 iunlock(ip);
3ebac878
RE
256 ip->i_flag = 0;
257 /*
258 * Put the inode on the end of the free list.
259 * Possibly in some cases it would be better to
260 * put the inode at the head of the free list,
261 * (eg: where i_mode == 0 || i_number == 0)
262 * but I will think about that later .. kre
263 * (i_number is rarely 0 - only after an i/o error in iget,
264 * where i_mode == 0, the inode will probably be wanted
265 * again soon for an ialloc, so possibly we should keep it)
266 */
267 if (ifreeh) {
268 *ifreet = ip;
269 ip->i_freeb = ifreet;
5d5124a1 270 } else {
3ebac878
RE
271 ifreeh = ip;
272 ip->i_freeb = &ifreeh;
5d5124a1 273 }
3ebac878
RE
274 ip->i_freef = NULL;
275 ifreet = &ip->i_freef;
ff56f48a 276 }
5d5124a1
BJ
277 ip->i_count--;
278}
279
280/*
281 * Check accessed and update flags on
282 * an inode structure.
283 * If any is on, update the inode
284 * with the current time.
c0bb1685
BJ
285 * If waitfor is given, then must insure
286 * i/o order so wait for write to complete.
5d5124a1 287 */
c0bb1685 288iupdat(ip, ta, tm, waitfor)
7494ef16
BJ
289 register struct inode *ip;
290 time_t *ta, *tm;
291 int waitfor;
5d5124a1
BJ
292{
293 register struct buf *bp;
294 struct dinode *dp;
6459ebe0 295 register struct fs *fp;
5d5124a1 296
6459ebe0
KM
297 fp = ip->i_fs;
298 if ((ip->i_flag & (IUPD|IACC|ICHG)) != 0) {
299 if (fp->fs_ronly)
5d5124a1 300 return;
6459ebe0
KM
301 bp = bread(ip->i_dev, fsbtodb(fp, itod(fp, ip->i_number)),
302 fp->fs_bsize);
5d5124a1
BJ
303 if (bp->b_flags & B_ERROR) {
304 brelse(bp);
305 return;
306 }
7494ef16 307 if (ip->i_flag&IACC)
6459ebe0 308 ip->i_atime = *ta;
7494ef16 309 if (ip->i_flag&IUPD)
6459ebe0 310 ip->i_mtime = *tm;
7494ef16 311 if (ip->i_flag&ICHG)
3e63ef5b 312 ip->i_ctime = time.tv_sec;
5d5124a1 313 ip->i_flag &= ~(IUPD|IACC|ICHG);
c39ea692
RE
314 dp = bp->b_un.b_dino + itoo(fp, ip->i_number);
315 dp->di_ic = ip->i_ic;
c0bb1685
BJ
316 if (waitfor)
317 bwrite(bp);
318 else
319 bdwrite(bp);
5d5124a1
BJ
320 }
321}
322
323/*
528f664c
SL
324 * Truncate the inode ip to at most
325 * length size. Free affected disk
326 * blocks -- the blocks of the file
327 * are removed in reverse order.
5d5124a1 328 */
528f664c 329itrunc(ip, length)
7494ef16 330 register struct inode *ip;
528f664c 331 register int length;
5d5124a1
BJ
332{
333 register i;
334 dev_t dev;
335 daddr_t bn;
c0bb1685 336 struct inode itmp;
6459ebe0 337 register struct fs *fs;
b4567e9c 338#ifdef QUOTA
89045c38
RE
339 register long cnt = 0;
340 long tloop();
341#endif
4a0415d6
SL
342 /*
343 * Only plain files, directories and symbolic
344 * links contain blocks.
345 */
346 i = ip->i_mode & IFMT;
347 if (i != IFREG && i != IFDIR && i != IFLNK)
348 return;
528f664c
SL
349 if (ip->i_size <= length)
350 return;
5d5124a1 351
c0bb1685
BJ
352 /*
353 * Clean inode on disk before freeing blocks
354 * to insure no duplicates if system crashes.
355 */
356 itmp = *ip;
528f664c 357 itmp.i_size = length;
6459ebe0
KM
358 for (i = 0; i < NDADDR; i++)
359 itmp.i_db[i] = 0;
360 for (i = 0; i < NIADDR; i++)
361 itmp.i_ib[i] = 0;
c0bb1685 362 itmp.i_flag |= ICHG|IUPD;
3e63ef5b 363 iupdat(&itmp, &time.tv_sec, &time.tv_sec, 1);
c0bb1685
BJ
364 ip->i_flag &= ~(IUPD|IACC|ICHG);
365
366 /*
367 * Now return blocks to free list... if machine
368 * crashes, they will be harmless MISSING blocks.
369 */
5d5124a1 370 dev = ip->i_dev;
6459ebe0
KM
371 fs = ip->i_fs;
372 /*
373 * release double indirect block first
374 */
375 bn = ip->i_ib[NIADDR-1];
376 if (bn != (daddr_t)0) {
377 ip->i_ib[NIADDR - 1] = (daddr_t)0;
b4567e9c 378#ifdef QUOTA
89045c38
RE
379 cnt +=
380#endif
381 tloop(ip, bn, 1);
6459ebe0
KM
382 }
383 /*
384 * release single indirect blocks second
385 */
386 for (i = NIADDR - 2; i >= 0; i--) {
387 bn = ip->i_ib[i];
388 if (bn != (daddr_t)0) {
389 ip->i_ib[i] = (daddr_t)0;
b4567e9c 390#ifdef QUOTA
89045c38
RE
391 cnt +=
392#endif
393 tloop(ip, bn, 0);
6459ebe0
KM
394 }
395 }
396 /*
397 * finally release direct blocks
398 */
399 for (i = NDADDR - 1; i>=0; i--) {
89045c38
RE
400 register size;
401
6459ebe0 402 bn = ip->i_db[i];
7494ef16 403 if (bn == (daddr_t)0)
5d5124a1 404 continue;
6459ebe0 405 ip->i_db[i] = (daddr_t)0;
89045c38 406 fre(ip, bn, size = (off_t)blksize(fs, ip, i));
b4567e9c 407#ifdef QUOTA
89045c38
RE
408 cnt += size / DEV_BSIZE;
409#endif
5d5124a1
BJ
410 }
411 ip->i_size = 0;
c0bb1685
BJ
412 /*
413 * Inode was written and flags updated above.
414 * No need to modify flags here.
415 */
b4567e9c 416#ifdef QUOTA
89045c38
RE
417 (void) chkdq(ip, -cnt, 0);
418#endif
5d5124a1
BJ
419}
420
b4567e9c 421#ifdef QUOTA
89045c38
RE
422long
423#endif
6459ebe0
KM
424tloop(ip, bn, indflg)
425 register struct inode *ip;
426 daddr_t bn;
427 int indflg;
5d5124a1
BJ
428{
429 register i;
430 register struct buf *bp;
431 register daddr_t *bap;
6459ebe0 432 register struct fs *fs;
5d5124a1 433 daddr_t nb;
b4567e9c 434#ifdef QUOTA
89045c38
RE
435 register long cnt = 0;
436#endif
5d5124a1
BJ
437
438 bp = NULL;
6459ebe0
KM
439 fs = ip->i_fs;
440 for (i = NINDIR(fs) - 1; i >= 0; i--) {
7494ef16 441 if (bp == NULL) {
6459ebe0 442 bp = bread(ip->i_dev, fsbtodb(fs, bn), fs->fs_bsize);
5d5124a1
BJ
443 if (bp->b_flags & B_ERROR) {
444 brelse(bp);
445 return;
446 }
447 bap = bp->b_un.b_daddr;
448 }
449 nb = bap[i];
7494ef16 450 if (nb == (daddr_t)0)
5d5124a1 451 continue;
89045c38 452 if (indflg) {
b4567e9c 453#ifdef QUOTA
89045c38
RE
454 cnt +=
455#endif
456 tloop(ip, nb, 0);
457 } else {
6459ebe0 458 fre(ip, nb, fs->fs_bsize);
b4567e9c 459#ifdef QUOTA
89045c38
RE
460 cnt += fs->fs_bsize / DEV_BSIZE;
461#endif
462 }
5d5124a1 463 }
7494ef16 464 if (bp != NULL)
5d5124a1 465 brelse(bp);
6459ebe0 466 fre(ip, bn, fs->fs_bsize);
b4567e9c 467#ifdef QUOTA
89045c38
RE
468 cnt += fs->fs_bsize / DEV_BSIZE;
469 return(cnt);
470#endif
5d5124a1
BJ
471}
472
3ebac878
RE
473/*
474 * remove any inodes in the inode cache belonging to dev
475 *
476 * There should not be any active ones, return error if any are found
477 * (nb: this is a user error, not a system err)
478 *
479 * Also, count the references to dev by block devices - this really
480 * has nothing to do with the object of the procedure, but as we have
481 * to scan the inode table here anyway, we might as well get the
482 * extra benefit.
483 *
484 * this is called from sumount()/sys3.c when dev is being unmounted
485 */
b4567e9c 486#ifdef QUOTA
4147b3f6 487iflush(dev, iq)
89045c38 488 dev_t dev;
4147b3f6 489 struct inode *iq;
89045c38 490#else
3ebac878
RE
491iflush(dev)
492 dev_t dev;
89045c38 493#endif
3ebac878 494{
32dc2b7e 495 register struct inode *ip;
3ebac878
RE
496 register open = 0;
497
498 for (ip = inode; ip < inodeNINODE; ip++) {
b4567e9c 499#ifdef QUOTA
89045c38
RE
500 if (ip != iq && ip->i_dev == dev)
501#else
3ebac878 502 if (ip->i_dev == dev)
89045c38 503#endif
3ebac878
RE
504 if (ip->i_count)
505 return(-1);
506 else {
32dc2b7e 507 remque(ip);
3ebac878
RE
508 ip->i_forw = ip;
509 ip->i_back = ip;
510 /*
511 * as i_count == 0, the inode was on the free
512 * list already, just leave it there, it will
513 * fall off the bottom eventually. We could
514 * perhaps move it to the head of the free
515 * list, but as umounts are done so
516 * infrequently, we would gain very little,
517 * while making the code bigger.
518 */
b4567e9c 519#ifdef QUOTA
89045c38
RE
520 dqrele(ip->i_dquot);
521 ip->i_dquot = NODQUOT;
522#endif
3ebac878
RE
523 }
524 else if (ip->i_count && (ip->i_mode&IFMT)==IFBLK &&
525 ip->i_rdev == dev)
526 open++;
527 }
528 return (open);
529}
530
7494ef16
BJ
531#ifdef ilock
532#undef ilock
d6a210b8 533#endif
ff56f48a
KM
534#ifdef iunlock
535#undef iunlock
d6a210b8
BJ
536#endif
537/*
7494ef16 538 * Lock an inode. If its already locked, set the WANT bit and sleep.
d6a210b8 539 */
7494ef16
BJ
540ilock(ip)
541 register struct inode *ip;
d6a210b8
BJ
542{
543
7494ef16 544 while (ip->i_flag&ILOCK) {
d6a210b8
BJ
545 ip->i_flag |= IWANT;
546 sleep((caddr_t)ip, PINOD);
547 }
548 ip->i_flag |= ILOCK;
549}
550
551/*
7494ef16 552 * Unlock an inode. If WANT bit is on, wakeup.
d6a210b8 553 */
ff56f48a 554iunlock(ip)
7494ef16 555 register struct inode *ip;
d6a210b8
BJ
556{
557
558 ip->i_flag &= ~ILOCK;
7494ef16 559 if (ip->i_flag&IWANT) {
d6a210b8
BJ
560 ip->i_flag &= ~IWANT;
561 wakeup((caddr_t)ip);
562 }
563}