xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51560)
123394Smckusick /*
251492Sbostic  * Copyright (c) 1991 Regents of the University of California.
334432Sbostic  * All rights reserved.
423394Smckusick  *
544536Sbostic  * %sccs.include.redist.c%
634432Sbostic  *
7*51560Smckusick  *	@(#)lfs_alloc.c	7.35 (Berkeley) 11/05/91
823394Smckusick  */
94359Smckusick 
1051485Sbostic #include <sys/param.h>
1151485Sbostic #include <sys/kernel.h>
1251485Sbostic #include <sys/buf.h>
1351485Sbostic #include <sys/vnode.h>
1451485Sbostic #include <sys/syslog.h>
1551485Sbostic #include <sys/mount.h>
164359Smckusick 
1751492Sbostic #include <ufs/ufs/quota.h>
1851492Sbostic #include <ufs/ufs/inode.h>
1951492Sbostic #include <ufs/ufs/ufsmount.h>
2047571Skarels 
2151492Sbostic #include <ufs/lfs/lfs.h>
2251492Sbostic #include <ufs/lfs/lfs_extern.h>
2351485Sbostic 
2451492Sbostic extern u_long nextgennumber;
2551492Sbostic 
2651485Sbostic /* Allocate a new inode. */
2751485Sbostic /* ARGSUSED */
2851485Sbostic int
29*51560Smckusick lfs_valloc(pvp, notused, cred, vpp)
30*51560Smckusick 	VNODE *pvp, **vpp;
3151485Sbostic 	int notused;
3251183Sbostic 	UCRED *cred;
3351155Sbostic {
3451492Sbostic 	struct lfs *fs;
3551183Sbostic 	BUF *bp;
3651155Sbostic 	IFILE *ifp;
3751183Sbostic 	INODE *ip;
3851183Sbostic 	VNODE *vp;
3951155Sbostic 	ino_t new_ino;
4051155Sbostic 	int error;
414359Smckusick 
4251215Sbostic 	/* Get the head of the freelist. */
43*51560Smckusick 	fs = VTOI(pvp)->i_lfs;
4451155Sbostic 	new_ino = fs->lfs_free;
4551215Sbostic 	if (new_ino == LFS_UNUSED_INUM) {
4651215Sbostic 		/*
4751215Sbostic 		 * XXX
4851215Sbostic 		 * Currently, no more inodes are allocated if the ifile fills
4951215Sbostic 		 * up.  The ifile should be extended instead.
5051215Sbostic 		 */
5151155Sbostic 		uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
5251155Sbostic 		log(LOG_ERR, "uid %d on %s: out of inodes\n",
5351155Sbostic 		    cred->cr_uid, fs->lfs_fsmnt);
5451155Sbostic 		return (ENOSPC);
556716Smckusick 	}
5651485Sbostic #ifdef ALLOCPRINT
5751485Sbostic 	printf("lfs_ialloc: allocate inode %d\n", new_ino);
5851485Sbostic #endif
594359Smckusick 
6051215Sbostic 	/* Read the appropriate block from the ifile. */
6151155Sbostic 	LFS_IENTRY(ifp, fs, new_ino, bp);
6251155Sbostic 
6351155Sbostic 	if (ifp->if_daddr != LFS_UNUSED_DADDR)
6451215Sbostic 		panic("lfs_ialloc: inuse inode on the free list");
6551155Sbostic 
6651215Sbostic 	/* Remove from the free list, set the access time, write it back. */
6751183Sbostic 	fs->lfs_free = ifp->if_nextfree;
6851155Sbostic 	ifp->if_st_atime = time.tv_sec;
6951215Sbostic 	lfs_bwrite(bp);
704426Smckusic 
7151215Sbostic 	/* Create a vnode to associate with the inode. */
72*51560Smckusick 	if (error = lfs_vcreate(pvp->v_mount, new_ino, &vp))
7337735Smckusick 		return (error);
74*51560Smckusick 	*vpp = vp;
75*51560Smckusick 	ip = VTOI(vp);
76*51560Smckusick 	VREF(ip->i_devvp);
7751155Sbostic 
7851215Sbostic 	/* 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 
8351215Sbostic 	/* Insert into the inode hash table. */
8451485Sbostic 	ufs_ihashins(ip);
854359Smckusick 
8651215Sbostic 	/* Set superblock modified bit and increment file count. */
8751215Sbostic 	fs->lfs_fmod = 1;
8851215Sbostic 	++fs->lfs_nfiles;
8951155Sbostic 	return (0);
904359Smckusick }
914359Smckusick 
9251215Sbostic /* Create a new vnode/inode pair and initialize what fields we can. */
9351347Sbostic int
9451155Sbostic lfs_vcreate(mp, ino, vpp)
9551183Sbostic 	MOUNT *mp;
9651155Sbostic 	ino_t ino;
9751183Sbostic 	VNODE **vpp;
984359Smckusick {
99*51560Smckusick 	extern struct vnodeops lfs_vnodeops;
10051183Sbostic 	INODE *ip;
10151183Sbostic 	UFSMOUNT *ump;
10251155Sbostic 	int error, i;
1034359Smckusick 
10451485Sbostic #ifdef ALLOCPRINT
10551485Sbostic 	printf("lfs_vcreate: ino %d\n", ino);
10651485Sbostic #endif
10751215Sbostic 	/* Create the vnode. */
10851215Sbostic 	if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp))
10951311Sbostic 		return (error);
1104359Smckusick 
11151215Sbostic 	/* Get a pointer to the private mount structure. */
11251155Sbostic 	ump = VFSTOUFS(mp);
1134651Smckusic 
11451155Sbostic 	/* Initialize the inode. */
11551155Sbostic 	ip = VTOI(*vpp);
116*51560Smckusick 	ip->i_vnode = *vpp;
117*51560Smckusick 	ip->i_flag = 0;
118*51560Smckusick 	ip->i_mode = 0;
11951155Sbostic 	ip->i_diroff = 0;
120*51560Smckusick 	ip->i_lockf = 0;
12151155Sbostic 	ip->i_dev = ump->um_dev;
122*51560Smckusick 	ip->i_number = ip->i_din.di_inum = ino;
12351155Sbostic 	ip->i_lfs = ump->um_lfs;
124*51560Smckusick 	ip->i_devvp = ump->um_devvp;
12551155Sbostic #ifdef QUOTA
12651155Sbostic 	for (i = 0; i < MAXQUOTAS; i++)
12751155Sbostic 		ip->i_dquot[i] = NODQUOT;
12851155Sbostic #endif
12951155Sbostic 	return (0);
1304651Smckusic }
13151183Sbostic 
13251485Sbostic /* Free an inode. */
13351485Sbostic /* ARGUSED */
13451215Sbostic void
135*51560Smckusick lfs_vfree(vp, notused1, notused2)
136*51560Smckusick 	VNODE *vp;
13751485Sbostic 	ino_t notused1;
13851485Sbostic 	int notused2;
13951215Sbostic {
14051215Sbostic 	BUF *bp;
14151215Sbostic 	IFILE *ifp;
142*51560Smckusick 	INODE *ip;
14351492Sbostic 	struct lfs *fs;
14451215Sbostic 	ino_t ino;
14551215Sbostic 
146*51560Smckusick 	ip = VTOI(vp);
14751485Sbostic #ifdef ALLOCPRINT
14851485Sbostic 	printf("lfs_ifree: free %d\n", ip->i_number);
14951485Sbostic #endif
15051485Sbostic 	/* Get the inode number and file system. */
15151215Sbostic 	fs = ip->i_lfs;
15251215Sbostic 	ino = ip->i_number;
15351485Sbostic 
15451485Sbostic 	/*
15551485Sbostic 	 * Read the appropriate block from the ifile.  Set the inode entry to
15651485Sbostic 	 * unused, increment its version number and link it into the free chain.
15751485Sbostic 	 */
15851215Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
15951485Sbostic 	ifp->if_daddr = LFS_UNUSED_DADDR;
16051485Sbostic 	++ifp->if_version;
16151485Sbostic 	ifp->if_nextfree = fs->lfs_free;
16251485Sbostic 	fs->lfs_free = ino;
16351215Sbostic 
16451215Sbostic 	lfs_bwrite(bp);
16551485Sbostic 
16651485Sbostic 	/* Set superblock modified bit and decrement file count. */
16751485Sbostic 	fs->lfs_fmod = 1;
16851485Sbostic 	--fs->lfs_nfiles;
16951215Sbostic }
170