xref: /csrg-svn/sys/ufs/lfs/lfs_inode.c (revision 7351)
1 /*	lfs_inode.c	4.17	82/07/03	*/
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_rdev = 0;
230 			ip->i_flag |= IUPD|ICHG;
231 			ifree(ip, ip->i_number, mode);
232 		}
233 		IUPDAT(ip, &time, &time, 0);
234 		iunlock(ip);
235 		ip->i_flag = 0;
236 		/*
237 		 * Put the inode on the end of the free list.
238 		 * Possibly in some cases it would be better to
239 		 * put the inode at the head of the free list,
240 		 * (eg: where i_mode == 0 || i_number == 0)
241 		 * but I will think about that later .. kre
242 		 * (i_number is rarely 0 - only after an i/o error in iget,
243 		 * where i_mode == 0, the inode will probably be wanted
244 		 * again soon for an ialloc, so possibly we should keep it)
245 		 */
246 		if (ifreeh) {
247 			*ifreet = ip;
248 			ip->i_freeb = ifreet;
249 		} else {
250 			ifreeh = ip;
251 			ip->i_freeb = &ifreeh;
252 		}
253 		ip->i_freef = NULL;
254 		ifreet = &ip->i_freef;
255 	}
256 	ip->i_count--;
257 }
258 
259 /*
260  * Check accessed and update flags on
261  * an inode structure.
262  * If any is on, update the inode
263  * with the current time.
264  * If waitfor is given, then must insure
265  * i/o order so wait for write to complete.
266  */
267 iupdat(ip, ta, tm, waitfor)
268 	register struct inode *ip;
269 	time_t *ta, *tm;
270 	int waitfor;
271 {
272 	register struct buf *bp;
273 	struct dinode *dp;
274 	register struct fs *fp;
275 
276 	fp = ip->i_fs;
277 	if ((ip->i_flag & (IUPD|IACC|ICHG)) != 0) {
278 		if (fp->fs_ronly)
279 			return;
280 		bp = bread(ip->i_dev, fsbtodb(fp, itod(fp, ip->i_number)),
281 			fp->fs_bsize);
282 		if (bp->b_flags & B_ERROR) {
283 			brelse(bp);
284 			return;
285 		}
286 		if (ip->i_flag&IACC)
287 			ip->i_atime = *ta;
288 		if (ip->i_flag&IUPD)
289 			ip->i_mtime = *tm;
290 		if (ip->i_flag&ICHG)
291 			ip->i_ctime = time;
292 		ip->i_flag &= ~(IUPD|IACC|ICHG);
293 		dp = bp->b_un.b_dino + itoo(fp, ip->i_number);
294 		dp->di_ic = ip->i_ic;
295 		if (waitfor)
296 			bwrite(bp);
297 		else
298 			bdwrite(bp);
299 	}
300 }
301 
302 /*
303  * Free all the disk blocks associated
304  * with the specified inode structure.
305  * The blocks of the file are removed
306  * in reverse order. This FILO
307  * algorithm will tend to maintain
308  * a contiguous free list much longer
309  * than FIFO.
310  */
311 itrunc(ip)
312 	register struct inode *ip;
313 {
314 	register i;
315 	dev_t dev;
316 	daddr_t bn;
317 	struct inode itmp;
318 	register struct fs *fs;
319 
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 	 * Only plain files, directories and symbolic
336 	 * links contain blocks.
337 	 */
338 	i = ip->i_mode & IFMT;
339 	if (i != IFREG && i != IFDIR && i != IFLNK)
340 		return;
341 	/*
342 	 * Now return blocks to free list... if machine
343 	 * crashes, they will be harmless MISSING blocks.
344 	 */
345 	dev = ip->i_dev;
346 	fs = ip->i_fs;
347 	/*
348 	 * release double indirect block first
349 	 */
350 	bn = ip->i_ib[NIADDR-1];
351 	if (bn != (daddr_t)0) {
352 		ip->i_ib[NIADDR - 1] = (daddr_t)0;
353 		tloop(ip, bn, 1);
354 	}
355 	/*
356 	 * release single indirect blocks second
357 	 */
358 	for (i = NIADDR - 2; i >= 0; i--) {
359 		bn = ip->i_ib[i];
360 		if (bn != (daddr_t)0) {
361 			ip->i_ib[i] = (daddr_t)0;
362 			tloop(ip, bn, 0);
363 		}
364 	}
365 	/*
366 	 * finally release direct blocks
367 	 */
368 	for (i = NDADDR - 1; i>=0; i--) {
369 		bn = ip->i_db[i];
370 		if (bn == (daddr_t)0)
371 			continue;
372 		ip->i_db[i] = (daddr_t)0;
373 		fre(ip, bn, (off_t)blksize(fs, ip, i));
374 	}
375 	ip->i_size = 0;
376 	/*
377 	 * Inode was written and flags updated above.
378 	 * No need to modify flags here.
379 	 */
380 }
381 
382 tloop(ip, bn, indflg)
383 	register struct inode *ip;
384 	daddr_t bn;
385 	int indflg;
386 {
387 	register i;
388 	register struct buf *bp;
389 	register daddr_t *bap;
390 	register struct fs *fs;
391 	daddr_t nb;
392 
393 	bp = NULL;
394 	fs = ip->i_fs;
395 	for (i = NINDIR(fs) - 1; i >= 0; i--) {
396 		if (bp == NULL) {
397 			bp = bread(ip->i_dev, fsbtodb(fs, bn), fs->fs_bsize);
398 			if (bp->b_flags & B_ERROR) {
399 				brelse(bp);
400 				return;
401 			}
402 			bap = bp->b_un.b_daddr;
403 		}
404 		nb = bap[i];
405 		if (nb == (daddr_t)0)
406 			continue;
407 		if (indflg)
408 			tloop(ip, nb, 0);
409 		else
410 			fre(ip, nb, fs->fs_bsize);
411 	}
412 	if (bp != NULL)
413 		brelse(bp);
414 	fre(ip, bn, fs->fs_bsize);
415 }
416 
417 /*
418  * Make a new file.
419  */
420 struct inode *
421 maknode(mode)
422 	int mode;
423 {
424 	register struct inode *ip;
425 	ino_t ipref;
426 
427 	if ((mode & IFMT) == IFDIR)
428 		ipref = dirpref(u.u_pdir->i_fs);
429 	else
430 		ipref = u.u_pdir->i_number;
431 	ip = ialloc(u.u_pdir, ipref, mode);
432 	if (ip == NULL) {
433 		iput(u.u_pdir);
434 		return(NULL);
435 	}
436 	ip->i_flag |= IACC|IUPD|ICHG;
437 	if ((mode & IFMT) == 0)
438 		mode |= IFREG;
439 	ip->i_mode = mode & ~u.u_cmask;
440 	ip->i_nlink = 1;
441 	ip->i_uid = u.u_uid;
442 	ip->i_gid = u.u_pdir->i_gid;
443 
444 	/*
445 	 * Make sure inode goes to disk before directory entry.
446 	 */
447 	iupdat(ip, &time, &time, 1);
448 	wdir(ip);
449 	if (u.u_error) {
450 		/*
451 		 * write error occurred trying to update directory
452 		 * so must deallocate the inode
453 		 */
454 		ip->i_nlink = 0;
455 		ip->i_flag |= ICHG;
456 		iput(ip);
457 		return(NULL);
458 	}
459 	return(ip);
460 }
461 
462 /*
463  * Write a directory entry with
464  * parameters left as side effects
465  * to a call to namei.
466  */
467 wdir(ip)
468 	struct inode *ip;
469 {
470 	register struct direct *dp, *ndp;
471 	struct fs *fs;
472 	struct buf *bp;
473 	int lbn, bn, base;
474 	int loc, dsize, spccnt, newsize;
475 	char *dirbuf;
476 
477 	u.u_dent.d_ino = ip->i_number;
478 	u.u_segflg = 1;
479 	newsize = DIRSIZ(&u.u_dent);
480 	/*
481 	 * if u.u_count == 0, a new directory block must be allocated.
482 	 */
483 	if (u.u_count == 0) {
484 		u.u_dent.d_reclen = DIRBLKSIZ;
485 		u.u_count = newsize;
486 		u.u_base = (caddr_t)&u.u_dent;
487 		writei(u.u_pdir);
488 		iput(u.u_pdir);
489 		return;
490 	}
491 	/*
492 	 * must read in an existing directory block
493 	 * to prepare to place the new entry into it.
494 	 */
495 	fs = u.u_pdir->i_fs;
496 	lbn = lblkno(fs, u.u_offset);
497 	base = blkoff(fs, u.u_offset);
498 	bn = fsbtodb(fs, bmap(u.u_pdir, lbn, B_WRITE, base + u.u_count));
499 	if (u.u_offset + u.u_count > u.u_pdir->i_size)
500 		u.u_pdir->i_size = u.u_offset + u.u_count;
501 	bp = bread(u.u_pdir->i_dev, bn, blksize(fs, u.u_pdir, lbn));
502 	if (bp->b_flags & B_ERROR) {
503 		brelse(bp);
504 		return;
505 	}
506 	dirbuf = bp->b_un.b_addr + base;
507 	dp = (struct direct *)dirbuf;
508 	dsize = DIRSIZ(dp);
509 	spccnt = dp->d_reclen - dsize;
510 	/*
511 	 * if there is insufficient room to make an entry at this point
512 	 * namei insures that compacting from u.u_offset for u.u_count
513 	 * bytes will provide the necessary space.
514 	 */
515 	for (loc = dp->d_reclen; loc < u.u_count; ) {
516 		ndp = (struct direct *)(dirbuf + loc);
517 		if (dp->d_ino == 0) {
518 			spccnt += dsize;
519 		} else {
520 			dp->d_reclen = dsize;
521 			dp = (struct direct *)((char *)dp + dsize);
522 		}
523 		dsize = DIRSIZ(ndp);
524 		spccnt += ndp->d_reclen - dsize;
525 		loc += ndp->d_reclen;
526 		bcopy(ndp, dp, dsize);
527 	}
528 	/*
529 	 * Update the pointer fields in the previous entry (if any),
530 	 * copy in the new entry, and write out the block.
531 	 */
532 	if (dp->d_ino == 0) {
533 		if (spccnt + dsize < newsize)
534 			panic("wdir: compact failed");
535 		u.u_dent.d_reclen = spccnt + dsize;
536 	} else {
537 		if (spccnt < newsize)
538 			panic("wdir: compact failed");
539 		u.u_dent.d_reclen = spccnt;
540 		dp->d_reclen = dsize;
541 		dp = (struct direct *)((char *)dp + dsize);
542 	}
543 	bcopy(&u.u_dent, dp, newsize);
544 	bwrite(bp);
545 	u.u_pdir->i_flag |= IUPD|ICHG;
546 	iput(u.u_pdir);
547 }
548 
549 /*
550  * remove any inodes in the inode cache belonging to dev
551  *
552  * There should not be any active ones, return error if any are found
553  * (nb: this is a user error, not a system err)
554  *
555  * Also, count the references to dev by block devices - this really
556  * has nothing to do with the object of the procedure, but as we have
557  * to scan the inode table here anyway, we might as well get the
558  * extra benefit.
559  *
560  * this is called from sumount()/sys3.c when dev is being unmounted
561  */
562 iflush(dev)
563 	dev_t dev;
564 {
565 	register struct inode *ip;
566 	register open = 0;
567 
568 	for (ip = inode; ip < inodeNINODE; ip++) {
569 		if (ip->i_dev == dev)
570 			if (ip->i_count)
571 				return(-1);
572 			else {
573 				remque(ip);
574 				ip->i_forw = ip;
575 				ip->i_back = ip;
576 				/*
577 				 * as i_count == 0, the inode was on the free
578 				 * list already, just leave it there, it will
579 				 * fall off the bottom eventually. We could
580 				 * perhaps move it to the head of the free
581 				 * list, but as umounts are done so
582 				 * infrequently, we would gain very little,
583 				 * while making the code bigger.
584 				 */
585 			}
586 		else if (ip->i_count && (ip->i_mode&IFMT)==IFBLK &&
587 		    ip->i_rdev == dev)
588 			open++;
589 	}
590 	return (open);
591 }
592 
593 #ifdef ilock
594 #undef ilock
595 #endif
596 #ifdef iunlock
597 #undef iunlock
598 #endif
599 /*
600  * Lock an inode. If its already locked, set the WANT bit and sleep.
601  */
602 ilock(ip)
603 	register struct inode *ip;
604 {
605 
606 	while (ip->i_flag&ILOCK) {
607 		ip->i_flag |= IWANT;
608 		sleep((caddr_t)ip, PINOD);
609 	}
610 	ip->i_flag |= ILOCK;
611 }
612 
613 /*
614  * Unlock an inode.  If WANT bit is on, wakeup.
615  */
616 iunlock(ip)
617 	register struct inode *ip;
618 {
619 
620 	ip->i_flag &= ~ILOCK;
621 	if (ip->i_flag&IWANT) {
622 		ip->i_flag &= ~IWANT;
623 		wakeup((caddr_t)ip);
624 	}
625 }
626