xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51155)
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*51155Sbostic  *	@(#)lfs_alloc.c	7.28 (Berkeley) 09/20/91
823394Smckusick  */
94359Smckusick 
1017097Sbloom #include "param.h"
11*51155Sbostic #include "kernel.h"
1217097Sbloom #include "buf.h"
1337735Smckusick #include "vnode.h"
1418307Sralph #include "syslog.h"
15*51155Sbostic #include "../ufs/quota.h"
16*51155Sbostic #include "../ufs/inode.h"
17*51155Sbostic #include "mount.h"
18*51155Sbostic #include "../ufs/ufsmount.h"
19*51155Sbostic #include "lfs.h"
20*51155Sbostic #include "lfs_extern.h"
214359Smckusick 
22*51155Sbostic #define	LFS_IENTRY(I, F, IN, BP) \
23*51155Sbostic 	if (bread((F)->lfs_ivnode, (IN) / IFPB(F) + (F)->lfs_segtabsz, \
24*51155Sbostic 	    (F)->lfs_bsize, NOCRED, &BP)) \
25*51155Sbostic 		panic("ifile read"); \
26*51155Sbostic 	(I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F);
2747571Skarels 
28*51155Sbostic ino_t
29*51155Sbostic lfs_ialloc(fs, pip, ipp, cred)
30*51155Sbostic 	LFS *fs;
31*51155Sbostic 	struct inode *pip, **ipp;
32*51155Sbostic 	struct ucred *cred;
33*51155Sbostic {
34*51155Sbostic 	IFILE *ifp;
35*51155Sbostic 	struct buf *bp;
36*51155Sbostic 	struct inode *ip;
37*51155Sbostic 	struct vnode *vp;
38*51155Sbostic 	ino_t new_ino;
39*51155Sbostic 	int error;
404359Smckusick 
41*51155Sbostic 	new_ino = fs->lfs_free;
42*51155Sbostic printf("lfs_ialloc: next free %d\n", new_ino);
43*51155Sbostic 	if (new_ino == LFS_UNUSED_INUM) {	/* XXX -- allocate more */
44*51155Sbostic 		uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
45*51155Sbostic 		log(LOG_ERR, "uid %d on %s: out of inodes\n",
46*51155Sbostic 		    cred->cr_uid, fs->lfs_fsmnt);
47*51155Sbostic 		return (ENOSPC);
486716Smckusick 	}
494359Smckusick 
50*51155Sbostic 	/* Read the appropriate block from the ifile */
51*51155Sbostic 	vp = fs->lfs_ivnode;
52*51155Sbostic 	LFS_IENTRY(ifp, fs, new_ino, bp);
53*51155Sbostic 
54*51155Sbostic 	if (ifp->if_daddr != LFS_UNUSED_DADDR)
55*51155Sbostic 		panic("lfs_ialloc: corrupt free list");
56*51155Sbostic 
57*51155Sbostic 	/* Remove from free list, set the access time. */
58*51155Sbostic 	ifp->if_st_atime = time.tv_sec;
59*51155Sbostic 	fs->lfs_free = ifp->if_nextfree;
6039678Smckusick 	brelse(bp);
614426Smckusic 
62*51155Sbostic 	error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp);
63*51155Sbostic 	if (error)
6437735Smckusick 		return (error);
65*51155Sbostic 
66*51155Sbostic 	ip = VTOI(vp);
67*51155Sbostic 	VREF(ip->i_devvp);
68*51155Sbostic 
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 
76*51155Sbostic 	lfs_hqueue(ip);
774359Smckusick 
78*51155Sbostic 	*ipp = ip;
79*51155Sbostic 	return (0);
804359Smckusick }
814359Smckusick 
82*51155Sbostic void
83*51155Sbostic lfs_ifree(ip)
849163Ssam 	struct inode *ip;
859163Ssam {
86*51155Sbostic 	IFILE *ifp;
87*51155Sbostic 	LFS *fs;
88*51155Sbostic 	struct buf *bp;
89*51155Sbostic 	ino_t ino;
904651Smckusic 
91*51155Sbostic printf("lfs_ifree: free %d\n", ip->i_number);
92*51155Sbostic 	fs = ip->i_lfs;
93*51155Sbostic 	ino = ip->i_number;
94*51155Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
954651Smckusic 
96*51155Sbostic 	ifp->if_daddr = LFS_UNUSED_DADDR;
97*51155Sbostic 	++ifp->if_version;
98*51155Sbostic 	ifp->if_nextfree = fs->lfs_free;
99*51155Sbostic 	brelse(bp);
100*51155Sbostic 	fs->lfs_free = ino;
101*51155Sbostic 	fs->lfs_fmod = 1;
1024359Smckusick }
1034359Smckusick 
1044359Smckusick daddr_t
105*51155Sbostic itod(fs, ino)
106*51155Sbostic 	LFS *fs;
107*51155Sbostic 	ino_t ino;
1084426Smckusic {
10937735Smckusick 	struct buf *bp;
110*51155Sbostic 	IFILE *ifp;
111*51155Sbostic 	daddr_t iaddr;
1124426Smckusic 
113*51155Sbostic printf("itod: ino %d\n", ino);
114*51155Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
1154426Smckusic 
116*51155Sbostic 	if (ifp->if_daddr == LFS_UNUSED_DADDR)
117*51155Sbostic 		panic("itod: unused daddr");
118*51155Sbostic printf("itod: about to return %lx\n", ifp->if_daddr);
119*51155Sbostic 	return (ifp->if_daddr);
1204463Smckusic }
1214463Smckusic 
122*51155Sbostic struct dinode *
123*51155Sbostic lfs_ifind(fs, ino, page)
124*51155Sbostic 	LFS *fs;
125*51155Sbostic 	ino_t ino;
126*51155Sbostic 	void *page;
1274463Smckusic {
128*51155Sbostic 	register struct dinode *dip;
129*51155Sbostic 	register int cnt;
1304463Smckusic 
131*51155Sbostic printf("lfs_ifind: inode %d\n", ino);
132*51155Sbostic 	dip = page;
133*51155Sbostic 	for (cnt = INOPB(fs); cnt--; ++dip)
134*51155Sbostic 		if (dip->di_inum == ino)
135*51155Sbostic 			return (dip);
13634143Smckusick 
137*51155Sbostic 	(void)printf("lfs_ifind: dinode %u not found", ino);
138*51155Sbostic 	panic("lfs_ifind: inode not found");
13916784Smckusick 	/* NOTREACHED */
1404359Smckusick }
1414359Smckusick 
1425375Smckusic /*
143*51155Sbostic  * Create a new vnode/inode and initialize the fields we can.
1445375Smckusic  */
145*51155Sbostic lfs_vcreate(mp, ino, vpp)
146*51155Sbostic 	struct mount *mp;
147*51155Sbostic 	ino_t ino;
148*51155Sbostic 	struct vnode **vpp;
1494359Smckusick {
1505965Smckusic 	struct inode *ip;
151*51155Sbostic 	struct ufsmount *ump;
152*51155Sbostic 	int error, i;
1534359Smckusick 
154*51155Sbostic printf("lfs_vcreate: ino %d\n", ino);
155*51155Sbostic 	error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp);
156*51155Sbostic 	if (error)
157*51155Sbostic 		return(error);
1584359Smckusick 
159*51155Sbostic 	ump = VFSTOUFS(mp);
1604651Smckusic 
161*51155Sbostic 	/* Initialize the inode. */
162*51155Sbostic 	ip = VTOI(*vpp);
163*51155Sbostic 	ip->i_diroff = 0;
164*51155Sbostic 	ip->i_devvp = ump->um_devvp;
165*51155Sbostic 	ip->i_dev = ump->um_dev;
166*51155Sbostic 	ip->i_flag = 0;
167*51155Sbostic 	ip->i_lfs = ump->um_lfs;
168*51155Sbostic 	ip->i_lockf = 0;
169*51155Sbostic 	ip->i_mode = 0;
170*51155Sbostic 	ip->i_number = ino;
171*51155Sbostic 	ip->i_vnode = *vpp;
172*51155Sbostic #ifdef QUOTA
173*51155Sbostic 	for (i = 0; i < MAXQUOTAS; i++)
174*51155Sbostic 		ip->i_dquot[i] = NODQUOT;
175*51155Sbostic #endif
176*51155Sbostic 	return (0);
1774651Smckusic }
178