xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51933)
123394Smckusick /*
251492Sbostic  * Copyright (c) 1991 Regents of the University of California.
334432Sbostic  * All rights reserved.
423394Smckusick  *
544536Sbostic  * %sccs.include.redist.c%
634432Sbostic  *
7*51933Sbostic  *	@(#)lfs_alloc.c	7.37 (Berkeley) 12/14/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
2951560Smckusick lfs_valloc(pvp, notused, cred, vpp)
3051560Smckusick 	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 
4251854Sbostic #ifdef VERBOSE
4351854Sbostic 	printf("lfs_valloc\n");
4451854Sbostic #endif
4551215Sbostic 	/* Get the head of the freelist. */
4651560Smckusick 	fs = VTOI(pvp)->i_lfs;
4751155Sbostic 	new_ino = fs->lfs_free;
4851215Sbostic 	if (new_ino == LFS_UNUSED_INUM) {
4951215Sbostic 		/*
5051215Sbostic 		 * XXX
5151215Sbostic 		 * Currently, no more inodes are allocated if the ifile fills
5251215Sbostic 		 * up.  The ifile should be extended instead.
5351215Sbostic 		 */
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 	}
5951485Sbostic #ifdef ALLOCPRINT
6051485Sbostic 	printf("lfs_ialloc: allocate inode %d\n", new_ino);
6151485Sbostic #endif
624359Smckusick 
63*51933Sbostic 	/*
64*51933Sbostic 	 * Remove the inode from the free list and write the free list
65*51933Sbostic 	 * back.
66*51933Sbostic 	 */
6751155Sbostic 	LFS_IENTRY(ifp, fs, new_ino, bp);
6851155Sbostic 	if (ifp->if_daddr != LFS_UNUSED_DADDR)
6951215Sbostic 		panic("lfs_ialloc: inuse inode on the free list");
7051183Sbostic 	fs->lfs_free = ifp->if_nextfree;
7151155Sbostic 	ifp->if_st_atime = time.tv_sec;
72*51933Sbostic 	LFS_IWRITE(fs, bp);
734426Smckusic 
7451215Sbostic 	/* Create a vnode to associate with the inode. */
7551560Smckusick 	if (error = lfs_vcreate(pvp->v_mount, new_ino, &vp))
7637735Smckusick 		return (error);
7751560Smckusick 	*vpp = vp;
7851560Smckusick 	ip = VTOI(vp);
7951560Smckusick 	VREF(ip->i_devvp);
8051155Sbostic 
8151215Sbostic 	/* Set a new generation number for this inode. */
8238255Smckusick 	if (++nextgennumber < (u_long)time.tv_sec)
8338255Smckusick 		nextgennumber = time.tv_sec;
8438255Smckusick 	ip->i_gen = nextgennumber;
854359Smckusick 
8651215Sbostic 	/* Insert into the inode hash table. */
8751485Sbostic 	ufs_ihashins(ip);
884359Smckusick 
8951215Sbostic 	/* Set superblock modified bit and increment file count. */
9051215Sbostic 	fs->lfs_fmod = 1;
9151215Sbostic 	++fs->lfs_nfiles;
9251155Sbostic 	return (0);
934359Smckusick }
944359Smckusick 
9551215Sbostic /* Create a new vnode/inode pair and initialize what fields we can. */
9651347Sbostic int
9751155Sbostic lfs_vcreate(mp, ino, vpp)
9851183Sbostic 	MOUNT *mp;
9951155Sbostic 	ino_t ino;
10051183Sbostic 	VNODE **vpp;
1014359Smckusick {
10251560Smckusick 	extern struct vnodeops lfs_vnodeops;
10351183Sbostic 	INODE *ip;
10451183Sbostic 	UFSMOUNT *ump;
10551155Sbostic 	int error, i;
1064359Smckusick 
10751854Sbostic #ifdef VERBOSE
10851485Sbostic 	printf("lfs_vcreate: ino %d\n", ino);
10951485Sbostic #endif
11051215Sbostic 	/* Create the vnode. */
11151215Sbostic 	if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp))
11251311Sbostic 		return (error);
1134359Smckusick 
11451215Sbostic 	/* Get a pointer to the private mount structure. */
11551155Sbostic 	ump = VFSTOUFS(mp);
1164651Smckusic 
11751155Sbostic 	/* Initialize the inode. */
11851155Sbostic 	ip = VTOI(*vpp);
11951560Smckusick 	ip->i_vnode = *vpp;
12051560Smckusick 	ip->i_flag = 0;
12151560Smckusick 	ip->i_mode = 0;
12251155Sbostic 	ip->i_diroff = 0;
12351560Smckusick 	ip->i_lockf = 0;
12451155Sbostic 	ip->i_dev = ump->um_dev;
12551560Smckusick 	ip->i_number = ip->i_din.di_inum = ino;
12651155Sbostic 	ip->i_lfs = ump->um_lfs;
12751560Smckusick 	ip->i_devvp = ump->um_devvp;
12851155Sbostic #ifdef QUOTA
12951155Sbostic 	for (i = 0; i < MAXQUOTAS; i++)
13051155Sbostic 		ip->i_dquot[i] = NODQUOT;
13151155Sbostic #endif
13251155Sbostic 	return (0);
1334651Smckusic }
13451183Sbostic 
13551485Sbostic /* Free an inode. */
13651485Sbostic /* ARGUSED */
13751215Sbostic void
13851560Smckusick lfs_vfree(vp, notused1, notused2)
13951560Smckusick 	VNODE *vp;
14051485Sbostic 	ino_t notused1;
14151485Sbostic 	int notused2;
14251215Sbostic {
14351215Sbostic 	BUF *bp;
14451215Sbostic 	IFILE *ifp;
14551560Smckusick 	INODE *ip;
14651492Sbostic 	struct lfs *fs;
14751215Sbostic 	ino_t ino;
14851215Sbostic 
14951560Smckusick 	ip = VTOI(vp);
15051854Sbostic #ifdef VERBOSE
15151854Sbostic 	printf("lfs_vfree: free %d\n", ip->i_number);
15251485Sbostic #endif
15351485Sbostic 	/* Get the inode number and file system. */
15451215Sbostic 	fs = ip->i_lfs;
15551215Sbostic 	ino = ip->i_number;
15651485Sbostic 
15751485Sbostic 	/*
158*51933Sbostic 	 * Set the ifile's inode entry to unused, increment its version number
159*51933Sbostic 	 * and link it into the free chain.
16051485Sbostic 	 */
16151215Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
16251485Sbostic 	ifp->if_daddr = LFS_UNUSED_DADDR;
16351485Sbostic 	++ifp->if_version;
16451485Sbostic 	ifp->if_nextfree = fs->lfs_free;
16551485Sbostic 	fs->lfs_free = ino;
166*51933Sbostic 	LFS_IWRITE(fs, bp);
16751215Sbostic 
16851485Sbostic 	/* Set superblock modified bit and decrement file count. */
16951485Sbostic 	fs->lfs_fmod = 1;
17051485Sbostic 	--fs->lfs_nfiles;
17151215Sbostic }
172