xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51215)
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*51215Sbostic  *	@(#)lfs_alloc.c	7.30 (Berkeley) 10/02/91
823394Smckusick  */
94359Smckusick 
10*51215Sbostic #ifdef LOGFS
1117097Sbloom #include "param.h"
1251155Sbostic #include "kernel.h"
1317097Sbloom #include "buf.h"
1437735Smckusick #include "vnode.h"
1518307Sralph #include "syslog.h"
16*51215Sbostic #include "mount.h"
1751155Sbostic #include "../ufs/quota.h"
1851155Sbostic #include "../ufs/inode.h"
1951155Sbostic #include "../ufs/ufsmount.h"
2051155Sbostic #include "lfs.h"
2151155Sbostic #include "lfs_extern.h"
224359Smckusick 
23*51215Sbostic /* Read in the block containing a specific inode from the ifile. */
2451155Sbostic #define	LFS_IENTRY(I, F, IN, BP) \
2551155Sbostic 	if (bread((F)->lfs_ivnode, (IN) / IFPB(F) + (F)->lfs_segtabsz, \
2651155Sbostic 	    (F)->lfs_bsize, NOCRED, &BP)) \
27*51215Sbostic 		panic("lfs_ientry: read"); \
2851155Sbostic 	(I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F);
2947571Skarels 
30*51215Sbostic /*
31*51215Sbostic  * Allocate a new inode.
32*51215Sbostic  */
3351155Sbostic ino_t
3451155Sbostic lfs_ialloc(fs, pip, ipp, cred)
3551155Sbostic 	LFS *fs;
3651183Sbostic 	INODE *pip, **ipp;
3751183Sbostic 	UCRED *cred;
3851155Sbostic {
3951183Sbostic 	BUF *bp;
4051155Sbostic 	IFILE *ifp;
4151183Sbostic 	INODE *ip;
4251183Sbostic 	VNODE *vp;
4351155Sbostic 	ino_t new_ino;
4451155Sbostic 	int error;
454359Smckusick 
46*51215Sbostic 	/* Get the head of the freelist. */
4751155Sbostic 	new_ino = fs->lfs_free;
48*51215Sbostic 	if (new_ino == LFS_UNUSED_INUM) {
49*51215Sbostic 		/*
50*51215Sbostic 		 * XXX
51*51215Sbostic 		 * Currently, no more inodes are allocated if the ifile fills
52*51215Sbostic 		 * up.  The ifile should be extended instead.
53*51215Sbostic 		 */
5451155Sbostic 		uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
5551155Sbostic 		log(LOG_ERR, "uid %d on %s: out of inodes\n",
5651155Sbostic 		    cred->cr_uid, fs->lfs_fsmnt);
5751155Sbostic 		return (ENOSPC);
586716Smckusick 	}
59*51215Sbostic printf("lfs_ialloc: allocate inode %d\n", new_ino);
604359Smckusick 
61*51215Sbostic 	/* Read the appropriate block from the ifile. */
6251155Sbostic 	LFS_IENTRY(ifp, fs, new_ino, bp);
6351155Sbostic 
6451155Sbostic 	if (ifp->if_daddr != LFS_UNUSED_DADDR)
65*51215Sbostic 		panic("lfs_ialloc: inuse inode on the free list");
6651155Sbostic 
67*51215Sbostic 	/* Remove from the free list, set the access time, write it back. */
6851183Sbostic 	fs->lfs_free = ifp->if_nextfree;
6951155Sbostic 	ifp->if_st_atime = time.tv_sec;
70*51215Sbostic 	lfs_bwrite(bp);
714426Smckusic 
72*51215Sbostic 	/* Create a vnode to associate with the inode. */
7351155Sbostic 	error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp);
7451155Sbostic 	if (error)
7537735Smckusick 		return (error);
76*51215Sbostic 	*ipp = ip = VTOI(vp);
7751155Sbostic 
78*51215Sbostic 	/* Set a new generation number for this inode. */
7938255Smckusick 	if (++nextgennumber < (u_long)time.tv_sec)
8038255Smckusick 		nextgennumber = time.tv_sec;
8138255Smckusick 	ip->i_gen = nextgennumber;
824359Smckusick 
83*51215Sbostic 	/* Insert into the inode hash table. */
8451155Sbostic 	lfs_hqueue(ip);
854359Smckusick 
86*51215Sbostic 	/* Set superblock modified bit and increment file count. */
87*51215Sbostic 	fs->lfs_fmod = 1;
88*51215Sbostic 	++fs->lfs_nfiles;
8951155Sbostic 	return (0);
904359Smckusick }
914359Smckusick 
92*51215Sbostic /* Free an inode. */
9351155Sbostic void
9451155Sbostic lfs_ifree(ip)
9551183Sbostic 	INODE *ip;
969163Ssam {
9751183Sbostic 	BUF *bp;
9851155Sbostic 	IFILE *ifp;
9951155Sbostic 	LFS *fs;
10051155Sbostic 	ino_t ino;
1014651Smckusic 
10251155Sbostic printf("lfs_ifree: free %d\n", ip->i_number);
103*51215Sbostic 	/* Get the inode number and file system. */
10451155Sbostic 	fs = ip->i_lfs;
10551155Sbostic 	ino = ip->i_number;
106*51215Sbostic 
107*51215Sbostic 	/*
108*51215Sbostic 	 * Read the appropriate block from the ifile.  Set the inode entry to
109*51215Sbostic 	 * unused, increment its version number and link it into the free chain.
110*51215Sbostic 	 */
11151155Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
11251155Sbostic 	ifp->if_daddr = LFS_UNUSED_DADDR;
11351155Sbostic 	++ifp->if_version;
11451155Sbostic 	ifp->if_nextfree = fs->lfs_free;
11551155Sbostic 	fs->lfs_free = ino;
116*51215Sbostic 
117*51215Sbostic 	lfs_bwrite(bp);
118*51215Sbostic 
119*51215Sbostic 	/* Set superblock modified bit and decrement file count. */
12051155Sbostic 	fs->lfs_fmod = 1;
121*51215Sbostic 	--fs->lfs_nfiles;
1224359Smckusick }
1234359Smckusick 
124*51215Sbostic /* Translate an inode number to a disk address. */
1254359Smckusick daddr_t
12651155Sbostic itod(fs, ino)
12751155Sbostic 	LFS *fs;
12851155Sbostic 	ino_t ino;
1294426Smckusic {
13051183Sbostic 	BUF *bp;
13151155Sbostic 	IFILE *ifp;
13251155Sbostic 	daddr_t iaddr;
1334426Smckusic 
134*51215Sbostic 	/* Read the appropriate block from the ifile. */
13551155Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
1364426Smckusic 
13751155Sbostic 	if (ifp->if_daddr == LFS_UNUSED_DADDR)
138*51215Sbostic 		panic("itod: unused disk address");
13951183Sbostic 	iaddr = ifp->if_daddr;
14051183Sbostic 	brelse(bp);
14151183Sbostic 	return (iaddr);
1424463Smckusic }
1434463Smckusic 
144*51215Sbostic /* Search a block for a specific dinode. */
14551183Sbostic DINODE *
14651155Sbostic lfs_ifind(fs, ino, page)
14751155Sbostic 	LFS *fs;
14851155Sbostic 	ino_t ino;
14951155Sbostic 	void *page;
1504463Smckusic {
15151183Sbostic 	register DINODE *dip;
15251155Sbostic 	register int cnt;
1534463Smckusic 
15451155Sbostic printf("lfs_ifind: inode %d\n", ino);
15551155Sbostic 	dip = page;
15651155Sbostic 	for (cnt = INOPB(fs); cnt--; ++dip)
15751155Sbostic 		if (dip->di_inum == ino)
15851155Sbostic 			return (dip);
15934143Smckusick 
160*51215Sbostic 	panic("lfs_ifind: dinode %%u not found", ino);
16116784Smckusick 	/* NOTREACHED */
1624359Smckusick }
1634359Smckusick 
164*51215Sbostic /* Create a new vnode/inode pair and initialize what fields we can. */
16551155Sbostic lfs_vcreate(mp, ino, vpp)
16651183Sbostic 	MOUNT *mp;
16751155Sbostic 	ino_t ino;
16851183Sbostic 	VNODE **vpp;
1694359Smckusick {
17051183Sbostic 	INODE *ip;
17151183Sbostic 	UFSMOUNT *ump;
17251155Sbostic 	int error, i;
1734359Smckusick 
17451155Sbostic printf("lfs_vcreate: ino %d\n", ino);
175*51215Sbostic 	/* Create the vnode. */
176*51215Sbostic 	if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp))
17751155Sbostic 		return(error);
1784359Smckusick 
179*51215Sbostic 	/* Get a pointer to the private mount structure. */
18051155Sbostic 	ump = VFSTOUFS(mp);
1814651Smckusic 
18251155Sbostic 	/* Initialize the inode. */
18351155Sbostic 	ip = VTOI(*vpp);
18451155Sbostic 	ip->i_diroff = 0;
18551155Sbostic 	ip->i_devvp = ump->um_devvp;
18651155Sbostic 	ip->i_dev = ump->um_dev;
18751155Sbostic 	ip->i_flag = 0;
18851155Sbostic 	ip->i_lfs = ump->um_lfs;
18951155Sbostic 	ip->i_lockf = 0;
19051155Sbostic 	ip->i_mode = 0;
19151183Sbostic 	ip->i_number = ip->i_din.di_inum = ino;
19251155Sbostic 	ip->i_vnode = *vpp;
19351155Sbostic #ifdef QUOTA
19451155Sbostic 	for (i = 0; i < MAXQUOTAS; i++)
19551155Sbostic 		ip->i_dquot[i] = NODQUOT;
19651155Sbostic #endif
197*51215Sbostic 	VREF(ip->i_devvp);			/* XXX: Why? */
19851155Sbostic 	return (0);
1994651Smckusic }
20051183Sbostic 
201*51215Sbostic /* Return the current version number for a specific inode. */
20251183Sbostic u_long
20351183Sbostic lfs_getversion(fs, ino)
20451183Sbostic 	LFS *fs;
20551183Sbostic 	ino_t ino;
20651183Sbostic {
207*51215Sbostic 	BUF *bp;
20851183Sbostic 	IFILE *ifp;
209*51215Sbostic 	u_long version;
21051183Sbostic 
211*51215Sbostic 	/*
212*51215Sbostic 	 * Read the appropriate block from the ifile.  Return the version
213*51215Sbostic 	 * number.
214*51215Sbostic 	 */
21551183Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
21651183Sbostic 	version = ifp->if_version;
21751183Sbostic 	brelse(bp);
21851183Sbostic 	return(version);
21951183Sbostic }
220*51215Sbostic 
221*51215Sbostic /* Set values in the ifile for the inode. */
222*51215Sbostic void
223*51215Sbostic lfs_iset(ip, daddr, atime)
224*51215Sbostic 	INODE *ip;
225*51215Sbostic 	daddr_t daddr;
226*51215Sbostic 	time_t atime;
227*51215Sbostic {
228*51215Sbostic 	BUF *bp;
229*51215Sbostic 	IFILE *ifp;
230*51215Sbostic 	LFS *fs;
231*51215Sbostic 	ino_t ino;
232*51215Sbostic 
233*51215Sbostic printf("lfs_iset: setting ino %d daddr %lx time %lx\n", ip->i_number, daddr, atime);
234*51215Sbostic 
235*51215Sbostic 	fs = ip->i_lfs;
236*51215Sbostic 	ino = ip->i_number;
237*51215Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
238*51215Sbostic 
239*51215Sbostic 	ifp->if_daddr = daddr;
240*51215Sbostic 	ifp->if_st_atime = atime;
241*51215Sbostic 	lfs_bwrite(bp);
242*51215Sbostic }
243*51215Sbostic #endif /* LOGFS */
244