xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51990)
123394Smckusick /*
251492Sbostic  * Copyright (c) 1991 Regents of the University of California.
334432Sbostic  * All rights reserved.
423394Smckusick  *
544536Sbostic  * %sccs.include.redist.c%
634432Sbostic  *
7*51990Smckusick  *	@(#)lfs_alloc.c	7.38 (Berkeley) 12/16/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>
16*51990Smckusick #include <sys/malloc.h>
174359Smckusick 
1851492Sbostic #include <ufs/ufs/quota.h>
1951492Sbostic #include <ufs/ufs/inode.h>
2051492Sbostic #include <ufs/ufs/ufsmount.h>
2147571Skarels 
2251492Sbostic #include <ufs/lfs/lfs.h>
2351492Sbostic #include <ufs/lfs/lfs_extern.h>
2451485Sbostic 
2551492Sbostic extern u_long nextgennumber;
2651492Sbostic 
2751485Sbostic /* Allocate a new inode. */
2851485Sbostic /* ARGSUSED */
2951485Sbostic int
3051560Smckusick lfs_valloc(pvp, notused, cred, vpp)
3151560Smckusick 	VNODE *pvp, **vpp;
3251485Sbostic 	int notused;
3351183Sbostic 	UCRED *cred;
3451155Sbostic {
3551492Sbostic 	struct lfs *fs;
3651183Sbostic 	BUF *bp;
3751155Sbostic 	IFILE *ifp;
3851183Sbostic 	INODE *ip;
3951183Sbostic 	VNODE *vp;
4051155Sbostic 	ino_t new_ino;
4151155Sbostic 	int error;
424359Smckusick 
4351854Sbostic #ifdef VERBOSE
4451854Sbostic 	printf("lfs_valloc\n");
4551854Sbostic #endif
4651215Sbostic 	/* Get the head of the freelist. */
4751560Smckusick 	fs = VTOI(pvp)->i_lfs;
4851155Sbostic 	new_ino = fs->lfs_free;
4951215Sbostic 	if (new_ino == LFS_UNUSED_INUM) {
5051215Sbostic 		/*
5151215Sbostic 		 * XXX
5251215Sbostic 		 * Currently, no more inodes are allocated if the ifile fills
5351215Sbostic 		 * up.  The ifile should be extended instead.
5451215Sbostic 		 */
5551155Sbostic 		uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
5651155Sbostic 		log(LOG_ERR, "uid %d on %s: out of inodes\n",
5751155Sbostic 		    cred->cr_uid, fs->lfs_fsmnt);
5851155Sbostic 		return (ENOSPC);
596716Smckusick 	}
6051485Sbostic #ifdef ALLOCPRINT
6151485Sbostic 	printf("lfs_ialloc: allocate inode %d\n", new_ino);
6251485Sbostic #endif
634359Smckusick 
6451933Sbostic 	/*
6551933Sbostic 	 * Remove the inode from the free list and write the free list
6651933Sbostic 	 * back.
6751933Sbostic 	 */
6851155Sbostic 	LFS_IENTRY(ifp, fs, new_ino, bp);
6951155Sbostic 	if (ifp->if_daddr != LFS_UNUSED_DADDR)
7051215Sbostic 		panic("lfs_ialloc: inuse inode on the free list");
7151183Sbostic 	fs->lfs_free = ifp->if_nextfree;
7251155Sbostic 	ifp->if_st_atime = time.tv_sec;
7351933Sbostic 	LFS_IWRITE(fs, bp);
744426Smckusic 
7551215Sbostic 	/* Create a vnode to associate with the inode. */
7651560Smckusick 	if (error = lfs_vcreate(pvp->v_mount, new_ino, &vp))
7737735Smckusick 		return (error);
7851560Smckusick 	*vpp = vp;
7951560Smckusick 	ip = VTOI(vp);
8051560Smckusick 	VREF(ip->i_devvp);
8151155Sbostic 
8251215Sbostic 	/* Set a new generation number for this inode. */
8338255Smckusick 	if (++nextgennumber < (u_long)time.tv_sec)
8438255Smckusick 		nextgennumber = time.tv_sec;
8538255Smckusick 	ip->i_gen = nextgennumber;
864359Smckusick 
8751215Sbostic 	/* Insert into the inode hash table. */
8851485Sbostic 	ufs_ihashins(ip);
894359Smckusick 
9051215Sbostic 	/* Set superblock modified bit and increment file count. */
9151215Sbostic 	fs->lfs_fmod = 1;
9251215Sbostic 	++fs->lfs_nfiles;
9351155Sbostic 	return (0);
944359Smckusick }
954359Smckusick 
9651215Sbostic /* Create a new vnode/inode pair and initialize what fields we can. */
9751347Sbostic int
9851155Sbostic lfs_vcreate(mp, ino, vpp)
9951183Sbostic 	MOUNT *mp;
10051155Sbostic 	ino_t ino;
10151183Sbostic 	VNODE **vpp;
1024359Smckusick {
10351560Smckusick 	extern struct vnodeops lfs_vnodeops;
10451183Sbostic 	INODE *ip;
10551183Sbostic 	UFSMOUNT *ump;
10651155Sbostic 	int error, i;
1074359Smckusick 
10851854Sbostic #ifdef VERBOSE
10951485Sbostic 	printf("lfs_vcreate: ino %d\n", ino);
11051485Sbostic #endif
11151215Sbostic 	/* Create the vnode. */
112*51990Smckusick 	if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp)) {
113*51990Smckusick 		*vpp = NULL;
11451311Sbostic 		return (error);
115*51990Smckusick 	}
1164359Smckusick 
11751215Sbostic 	/* Get a pointer to the private mount structure. */
11851155Sbostic 	ump = VFSTOUFS(mp);
1194651Smckusic 
12051155Sbostic 	/* Initialize the inode. */
121*51990Smckusick 	MALLOC(ip, struct inode *, sizeof(struct inode), M_LFSNODE, M_WAITOK);
122*51990Smckusick 	(*vpp)->v_data = ip;
12351560Smckusick 	ip->i_vnode = *vpp;
12451560Smckusick 	ip->i_flag = 0;
12551560Smckusick 	ip->i_mode = 0;
12651155Sbostic 	ip->i_diroff = 0;
12751560Smckusick 	ip->i_lockf = 0;
12851155Sbostic 	ip->i_dev = ump->um_dev;
12951560Smckusick 	ip->i_number = ip->i_din.di_inum = ino;
13051155Sbostic 	ip->i_lfs = ump->um_lfs;
13151560Smckusick 	ip->i_devvp = ump->um_devvp;
13251155Sbostic #ifdef QUOTA
13351155Sbostic 	for (i = 0; i < MAXQUOTAS; i++)
13451155Sbostic 		ip->i_dquot[i] = NODQUOT;
13551155Sbostic #endif
13651155Sbostic 	return (0);
1374651Smckusic }
13851183Sbostic 
13951485Sbostic /* Free an inode. */
14051485Sbostic /* ARGUSED */
14151215Sbostic void
14251560Smckusick lfs_vfree(vp, notused1, notused2)
14351560Smckusick 	VNODE *vp;
14451485Sbostic 	ino_t notused1;
14551485Sbostic 	int notused2;
14651215Sbostic {
14751215Sbostic 	BUF *bp;
14851215Sbostic 	IFILE *ifp;
14951560Smckusick 	INODE *ip;
15051492Sbostic 	struct lfs *fs;
15151215Sbostic 	ino_t ino;
15251215Sbostic 
15351560Smckusick 	ip = VTOI(vp);
15451854Sbostic #ifdef VERBOSE
15551854Sbostic 	printf("lfs_vfree: free %d\n", ip->i_number);
15651485Sbostic #endif
15751485Sbostic 	/* Get the inode number and file system. */
15851215Sbostic 	fs = ip->i_lfs;
15951215Sbostic 	ino = ip->i_number;
16051485Sbostic 
16151485Sbostic 	/*
16251933Sbostic 	 * Set the ifile's inode entry to unused, increment its version number
16351933Sbostic 	 * and link it into the free chain.
16451485Sbostic 	 */
16551215Sbostic 	LFS_IENTRY(ifp, fs, ino, bp);
16651485Sbostic 	ifp->if_daddr = LFS_UNUSED_DADDR;
16751485Sbostic 	++ifp->if_version;
16851485Sbostic 	ifp->if_nextfree = fs->lfs_free;
16951485Sbostic 	fs->lfs_free = ino;
17051933Sbostic 	LFS_IWRITE(fs, bp);
17151215Sbostic 
17251485Sbostic 	/* Set superblock modified bit and decrement file count. */
17351485Sbostic 	fs->lfs_fmod = 1;
17451485Sbostic 	--fs->lfs_nfiles;
17551215Sbostic }
176