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