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