xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51183)
123394Smckusick /*
237735Smckusick  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
334432Sbostic  * All rights reserved.
423394Smckusick  *
544536Sbostic  * %sccs.include.redist.c%
634432Sbostic  *
7*51183Sbostic  *	@(#)lfs_alloc.c	7.29 (Berkeley) 09/25/91
823394Smckusick  */
94359Smckusick 
1017097Sbloom #include "param.h"
1151155Sbostic #include "kernel.h"
1217097Sbloom #include "buf.h"
1337735Smckusick #include "vnode.h"
1418307Sralph #include "syslog.h"
1551155Sbostic #include "../ufs/quota.h"
1651155Sbostic #include "../ufs/inode.h"
1751155Sbostic #include "mount.h"
1851155Sbostic #include "../ufs/ufsmount.h"
1951155Sbostic #include "lfs.h"
2051155Sbostic #include "lfs_extern.h"
214359Smckusick 
2251155Sbostic #define	LFS_IENTRY(I, F, IN, BP) \
2351155Sbostic 	if (bread((F)->lfs_ivnode, (IN) / IFPB(F) + (F)->lfs_segtabsz, \
2451155Sbostic 	    (F)->lfs_bsize, NOCRED, &BP)) \
2551155Sbostic 		panic("ifile read"); \
2651155Sbostic 	(I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F);
2747571Skarels 
2851155Sbostic ino_t
2951155Sbostic lfs_ialloc(fs, pip, ipp, cred)
3051155Sbostic 	LFS *fs;
31*51183Sbostic 	INODE *pip, **ipp;
32*51183Sbostic 	UCRED *cred;
3351155Sbostic {
34*51183Sbostic 	BUF *bp;
3551155Sbostic 	IFILE *ifp;
36*51183Sbostic 	INODE *ip;
37*51183Sbostic 	VNODE *vp;
3851155Sbostic 	ino_t new_ino;
3951155Sbostic 	int error;
404359Smckusick 
4151155Sbostic 	new_ino = fs->lfs_free;
4251155Sbostic printf("lfs_ialloc: next free %d\n", new_ino);
4351155Sbostic 	if (new_ino == LFS_UNUSED_INUM) {	/* XXX -- allocate more */
4451155Sbostic 		uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
4551155Sbostic 		log(LOG_ERR, "uid %d on %s: out of inodes\n",
4651155Sbostic 		    cred->cr_uid, fs->lfs_fsmnt);
4751155Sbostic 		return (ENOSPC);
486716Smckusick 	}
494359Smckusick 
5051155Sbostic 	/* Read the appropriate block from the ifile */
5151155Sbostic 	vp = fs->lfs_ivnode;
5251155Sbostic 	LFS_IENTRY(ifp, fs, new_ino, bp);
5351155Sbostic 
5451155Sbostic 	if (ifp->if_daddr != LFS_UNUSED_DADDR)
5551155Sbostic 		panic("lfs_ialloc: corrupt free list");
5651155Sbostic 
5751155Sbostic 	/* Remove from free list, set the access time. */
58*51183Sbostic 	fs->lfs_free = ifp->if_nextfree;
5951155Sbostic 	ifp->if_st_atime = time.tv_sec;
6039678Smckusick 	brelse(bp);
614426Smckusic 
6251155Sbostic 	error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp);
6351155Sbostic 	if (error)
6437735Smckusick 		return (error);
6551155Sbostic 
6651155Sbostic 	ip = VTOI(vp);
6751155Sbostic 	VREF(ip->i_devvp);
6851155Sbostic 
6938255Smckusick 	/*
7038255Smckusick 	 * Set up a new generation number for this inode.
7138255Smckusick 	 */
7238255Smckusick 	if (++nextgennumber < (u_long)time.tv_sec)
7338255Smckusick 		nextgennumber = time.tv_sec;
7438255Smckusick 	ip->i_gen = nextgennumber;
754359Smckusick 
7651155Sbostic 	lfs_hqueue(ip);
774359Smckusick 
7851155Sbostic 	*ipp = ip;
7951155Sbostic 	return (0);
804359Smckusick }
814359Smckusick 
8251155Sbostic void
8351155Sbostic lfs_ifree(ip)
84*51183Sbostic 	INODE *ip;
859163Ssam {
86*51183Sbostic 	BUF *bp;
8751155Sbostic 	IFILE *ifp;
8851155Sbostic 	LFS *fs;
8951155Sbostic 	ino_t ino;
904651Smckusic 
9151155Sbostic printf("lfs_ifree: free %d\n", ip->i_number);
9251155Sbostic 	fs = ip->i_lfs;
9351155Sbostic 	ino = ip->i_number;
9451155Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
954651Smckusic 
9651155Sbostic 	ifp->if_daddr = LFS_UNUSED_DADDR;
9751155Sbostic 	++ifp->if_version;
9851155Sbostic 	ifp->if_nextfree = fs->lfs_free;
9951155Sbostic 	brelse(bp);
10051155Sbostic 	fs->lfs_free = ino;
10151155Sbostic 	fs->lfs_fmod = 1;
1024359Smckusick }
1034359Smckusick 
1044359Smckusick daddr_t
10551155Sbostic itod(fs, ino)
10651155Sbostic 	LFS *fs;
10751155Sbostic 	ino_t ino;
1084426Smckusic {
109*51183Sbostic 	BUF *bp;
11051155Sbostic 	IFILE *ifp;
11151155Sbostic 	daddr_t iaddr;
1124426Smckusic 
11351155Sbostic printf("itod: ino %d\n", ino);
11451155Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
1154426Smckusic 
11651155Sbostic 	if (ifp->if_daddr == LFS_UNUSED_DADDR)
11751155Sbostic 		panic("itod: unused daddr");
118*51183Sbostic 	iaddr = ifp->if_daddr;
119*51183Sbostic 	brelse(bp);
120*51183Sbostic 	return (iaddr);
1214463Smckusic }
1224463Smckusic 
123*51183Sbostic DINODE *
12451155Sbostic lfs_ifind(fs, ino, page)
12551155Sbostic 	LFS *fs;
12651155Sbostic 	ino_t ino;
12751155Sbostic 	void *page;
1284463Smckusic {
129*51183Sbostic 	register DINODE *dip;
13051155Sbostic 	register int cnt;
1314463Smckusic 
13251155Sbostic printf("lfs_ifind: inode %d\n", ino);
13351155Sbostic 	dip = page;
13451155Sbostic 	for (cnt = INOPB(fs); cnt--; ++dip)
13551155Sbostic 		if (dip->di_inum == ino)
13651155Sbostic 			return (dip);
13734143Smckusick 
13851155Sbostic 	(void)printf("lfs_ifind: dinode %u not found", ino);
13951155Sbostic 	panic("lfs_ifind: inode not found");
14016784Smckusick 	/* NOTREACHED */
1414359Smckusick }
1424359Smckusick 
1435375Smckusic /*
14451155Sbostic  * Create a new vnode/inode and initialize the fields we can.
1455375Smckusic  */
14651155Sbostic lfs_vcreate(mp, ino, vpp)
147*51183Sbostic 	MOUNT *mp;
14851155Sbostic 	ino_t ino;
149*51183Sbostic 	VNODE **vpp;
1504359Smckusick {
151*51183Sbostic 	INODE *ip;
152*51183Sbostic 	UFSMOUNT *ump;
15351155Sbostic 	int error, i;
1544359Smckusick 
15551155Sbostic printf("lfs_vcreate: ino %d\n", ino);
15651155Sbostic 	error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp);
15751155Sbostic 	if (error)
15851155Sbostic 		return(error);
1594359Smckusick 
16051155Sbostic 	ump = VFSTOUFS(mp);
1614651Smckusic 
16251155Sbostic 	/* Initialize the inode. */
16351155Sbostic 	ip = VTOI(*vpp);
16451155Sbostic 	ip->i_diroff = 0;
16551155Sbostic 	ip->i_devvp = ump->um_devvp;
16651155Sbostic 	ip->i_dev = ump->um_dev;
16751155Sbostic 	ip->i_flag = 0;
16851155Sbostic 	ip->i_lfs = ump->um_lfs;
16951155Sbostic 	ip->i_lockf = 0;
17051155Sbostic 	ip->i_mode = 0;
171*51183Sbostic 	ip->i_number = ip->i_din.di_inum = ino;
17251155Sbostic 	ip->i_vnode = *vpp;
17351155Sbostic #ifdef QUOTA
17451155Sbostic 	for (i = 0; i < MAXQUOTAS; i++)
17551155Sbostic 		ip->i_dquot[i] = NODQUOT;
17651155Sbostic #endif
17751155Sbostic 	return (0);
1784651Smckusic }
179*51183Sbostic 
180*51183Sbostic /*
181*51183Sbostic  * Return the current version number for a specific inode.
182*51183Sbostic  */
183*51183Sbostic u_long
184*51183Sbostic lfs_getversion(fs, ino)
185*51183Sbostic 	LFS *fs;
186*51183Sbostic 	ino_t ino;
187*51183Sbostic {
188*51183Sbostic 	IFILE *ifp;
189*51183Sbostic 	BUF *bp;
190*51183Sbostic 	int version;
191*51183Sbostic 
192*51183Sbostic printf("lfs_getversion: %d\n", ino);
193*51183Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
194*51183Sbostic 	version = ifp->if_version;
195*51183Sbostic 	brelse(bp);
196*51183Sbostic 	return(version);
197*51183Sbostic }
198