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