xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51492)
123394Smckusick /*
2*51492Sbostic  * Copyright (c) 1991 Regents of the University of California.
334432Sbostic  * All rights reserved.
423394Smckusick  *
544536Sbostic  * %sccs.include.redist.c%
634432Sbostic  *
7*51492Sbostic  *	@(#)lfs_alloc.c	7.34 (Berkeley) 11/01/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 
17*51492Sbostic #include <ufs/ufs/quota.h>
18*51492Sbostic #include <ufs/ufs/inode.h>
19*51492Sbostic #include <ufs/ufs/ufsmount.h>
2047571Skarels 
21*51492Sbostic #include <ufs/lfs/lfs.h>
22*51492Sbostic #include <ufs/lfs/lfs_extern.h>
2351485Sbostic 
24*51492Sbostic extern u_long nextgennumber;
25*51492Sbostic 
2651485Sbostic /* Allocate a new inode. */
2751485Sbostic /* ARGSUSED */
2851485Sbostic int
2951485Sbostic lfs_ialloc(pip, notused, cred, ipp)
3051183Sbostic 	INODE *pip, **ipp;
3151485Sbostic 	int notused;
3251183Sbostic 	UCRED *cred;
3351155Sbostic {
34*51492Sbostic 	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. */
4351485Sbostic 	fs = pip->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. */
7251155Sbostic 	error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp);
7351155Sbostic 	if (error)
7437735Smckusick 		return (error);
7551215Sbostic 	*ipp = ip = VTOI(vp);
7651155Sbostic 
7751215Sbostic 	/* Set a new generation number for this inode. */
7838255Smckusick 	if (++nextgennumber < (u_long)time.tv_sec)
7938255Smckusick 		nextgennumber = time.tv_sec;
8038255Smckusick 	ip->i_gen = nextgennumber;
814359Smckusick 
8251215Sbostic 	/* Insert into the inode hash table. */
8351485Sbostic 	ufs_ihashins(ip);
844359Smckusick 
8551215Sbostic 	/* Set superblock modified bit and increment file count. */
8651215Sbostic 	fs->lfs_fmod = 1;
8751215Sbostic 	++fs->lfs_nfiles;
8851155Sbostic 	return (0);
894359Smckusick }
904359Smckusick 
9151215Sbostic /* Create a new vnode/inode pair and initialize what fields we can. */
9251347Sbostic int
9351155Sbostic lfs_vcreate(mp, ino, vpp)
9451183Sbostic 	MOUNT *mp;
9551155Sbostic 	ino_t ino;
9651183Sbostic 	VNODE **vpp;
974359Smckusick {
9851183Sbostic 	INODE *ip;
9951183Sbostic 	UFSMOUNT *ump;
10051155Sbostic 	int error, i;
1014359Smckusick 
10251485Sbostic #ifdef ALLOCPRINT
10351485Sbostic 	printf("lfs_vcreate: ino %d\n", ino);
10451485Sbostic #endif
10551215Sbostic 	/* Create the vnode. */
10651215Sbostic 	if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp))
10751311Sbostic 		return (error);
1084359Smckusick 
10951215Sbostic 	/* Get a pointer to the private mount structure. */
11051155Sbostic 	ump = VFSTOUFS(mp);
1114651Smckusic 
11251155Sbostic 	/* Initialize the inode. */
11351155Sbostic 	ip = VTOI(*vpp);
11451155Sbostic 	ip->i_diroff = 0;
11551155Sbostic 	ip->i_devvp = ump->um_devvp;
11651155Sbostic 	ip->i_dev = ump->um_dev;
11751155Sbostic 	ip->i_flag = 0;
11851155Sbostic 	ip->i_lfs = ump->um_lfs;
11951155Sbostic 	ip->i_lockf = 0;
12051155Sbostic 	ip->i_mode = 0;
12151183Sbostic 	ip->i_number = ip->i_din.di_inum = ino;
12251155Sbostic 	ip->i_vnode = *vpp;
12351155Sbostic #ifdef QUOTA
12451155Sbostic 	for (i = 0; i < MAXQUOTAS; i++)
12551155Sbostic 		ip->i_dquot[i] = NODQUOT;
12651155Sbostic #endif
12751215Sbostic 	VREF(ip->i_devvp);			/* XXX: Why? */
12851155Sbostic 	return (0);
1294651Smckusic }
13051183Sbostic 
13151485Sbostic /* Free an inode. */
13251485Sbostic /* ARGUSED */
13351215Sbostic void
13451485Sbostic lfs_ifree(ip, notused1, notused2)
13551215Sbostic 	INODE *ip;
13651485Sbostic 	ino_t notused1;
13751485Sbostic 	int notused2;
13851215Sbostic {
13951215Sbostic 	BUF *bp;
14051215Sbostic 	IFILE *ifp;
141*51492Sbostic 	struct lfs *fs;
14251215Sbostic 	ino_t ino;
14351215Sbostic 
14451485Sbostic #ifdef ALLOCPRINT
14551485Sbostic 	printf("lfs_ifree: free %d\n", ip->i_number);
14651485Sbostic #endif
14751485Sbostic 	/* Get the inode number and file system. */
14851215Sbostic 	fs = ip->i_lfs;
14951215Sbostic 	ino = ip->i_number;
15051485Sbostic 
15151485Sbostic 	/*
15251485Sbostic 	 * Read the appropriate block from the ifile.  Set the inode entry to
15351485Sbostic 	 * unused, increment its version number and link it into the free chain.
15451485Sbostic 	 */
15551215Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
15651485Sbostic 	ifp->if_daddr = LFS_UNUSED_DADDR;
15751485Sbostic 	++ifp->if_version;
15851485Sbostic 	ifp->if_nextfree = fs->lfs_free;
15951485Sbostic 	fs->lfs_free = ino;
16051215Sbostic 
16151215Sbostic 	lfs_bwrite(bp);
16251485Sbostic 
16351485Sbostic 	/* Set superblock modified bit and decrement file count. */
16451485Sbostic 	fs->lfs_fmod = 1;
16551485Sbostic 	--fs->lfs_nfiles;
16651215Sbostic }
167