xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51933)
1 /*
2  * Copyright (c) 1991 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)lfs_alloc.c	7.37 (Berkeley) 12/14/91
8  */
9 
10 #include <sys/param.h>
11 #include <sys/kernel.h>
12 #include <sys/buf.h>
13 #include <sys/vnode.h>
14 #include <sys/syslog.h>
15 #include <sys/mount.h>
16 
17 #include <ufs/ufs/quota.h>
18 #include <ufs/ufs/inode.h>
19 #include <ufs/ufs/ufsmount.h>
20 
21 #include <ufs/lfs/lfs.h>
22 #include <ufs/lfs/lfs_extern.h>
23 
24 extern u_long nextgennumber;
25 
26 /* Allocate a new inode. */
27 /* ARGSUSED */
28 int
29 lfs_valloc(pvp, notused, cred, vpp)
30 	VNODE *pvp, **vpp;
31 	int notused;
32 	UCRED *cred;
33 {
34 	struct lfs *fs;
35 	BUF *bp;
36 	IFILE *ifp;
37 	INODE *ip;
38 	VNODE *vp;
39 	ino_t new_ino;
40 	int error;
41 
42 #ifdef VERBOSE
43 	printf("lfs_valloc\n");
44 #endif
45 	/* Get the head of the freelist. */
46 	fs = VTOI(pvp)->i_lfs;
47 	new_ino = fs->lfs_free;
48 	if (new_ino == LFS_UNUSED_INUM) {
49 		/*
50 		 * XXX
51 		 * Currently, no more inodes are allocated if the ifile fills
52 		 * up.  The ifile should be extended instead.
53 		 */
54 		uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
55 		log(LOG_ERR, "uid %d on %s: out of inodes\n",
56 		    cred->cr_uid, fs->lfs_fsmnt);
57 		return (ENOSPC);
58 	}
59 #ifdef ALLOCPRINT
60 	printf("lfs_ialloc: allocate inode %d\n", new_ino);
61 #endif
62 
63 	/*
64 	 * Remove the inode from the free list and write the free list
65 	 * back.
66 	 */
67 	LFS_IENTRY(ifp, fs, new_ino, bp);
68 	if (ifp->if_daddr != LFS_UNUSED_DADDR)
69 		panic("lfs_ialloc: inuse inode on the free list");
70 	fs->lfs_free = ifp->if_nextfree;
71 	ifp->if_st_atime = time.tv_sec;
72 	LFS_IWRITE(fs, bp);
73 
74 	/* Create a vnode to associate with the inode. */
75 	if (error = lfs_vcreate(pvp->v_mount, new_ino, &vp))
76 		return (error);
77 	*vpp = vp;
78 	ip = VTOI(vp);
79 	VREF(ip->i_devvp);
80 
81 	/* Set a new generation number for this inode. */
82 	if (++nextgennumber < (u_long)time.tv_sec)
83 		nextgennumber = time.tv_sec;
84 	ip->i_gen = nextgennumber;
85 
86 	/* Insert into the inode hash table. */
87 	ufs_ihashins(ip);
88 
89 	/* Set superblock modified bit and increment file count. */
90 	fs->lfs_fmod = 1;
91 	++fs->lfs_nfiles;
92 	return (0);
93 }
94 
95 /* Create a new vnode/inode pair and initialize what fields we can. */
96 int
97 lfs_vcreate(mp, ino, vpp)
98 	MOUNT *mp;
99 	ino_t ino;
100 	VNODE **vpp;
101 {
102 	extern struct vnodeops lfs_vnodeops;
103 	INODE *ip;
104 	UFSMOUNT *ump;
105 	int error, i;
106 
107 #ifdef VERBOSE
108 	printf("lfs_vcreate: ino %d\n", ino);
109 #endif
110 	/* Create the vnode. */
111 	if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp))
112 		return (error);
113 
114 	/* Get a pointer to the private mount structure. */
115 	ump = VFSTOUFS(mp);
116 
117 	/* Initialize the inode. */
118 	ip = VTOI(*vpp);
119 	ip->i_vnode = *vpp;
120 	ip->i_flag = 0;
121 	ip->i_mode = 0;
122 	ip->i_diroff = 0;
123 	ip->i_lockf = 0;
124 	ip->i_dev = ump->um_dev;
125 	ip->i_number = ip->i_din.di_inum = ino;
126 	ip->i_lfs = ump->um_lfs;
127 	ip->i_devvp = ump->um_devvp;
128 #ifdef QUOTA
129 	for (i = 0; i < MAXQUOTAS; i++)
130 		ip->i_dquot[i] = NODQUOT;
131 #endif
132 	return (0);
133 }
134 
135 /* Free an inode. */
136 /* ARGUSED */
137 void
138 lfs_vfree(vp, notused1, notused2)
139 	VNODE *vp;
140 	ino_t notused1;
141 	int notused2;
142 {
143 	BUF *bp;
144 	IFILE *ifp;
145 	INODE *ip;
146 	struct lfs *fs;
147 	ino_t ino;
148 
149 	ip = VTOI(vp);
150 #ifdef VERBOSE
151 	printf("lfs_vfree: free %d\n", ip->i_number);
152 #endif
153 	/* Get the inode number and file system. */
154 	fs = ip->i_lfs;
155 	ino = ip->i_number;
156 
157 	/*
158 	 * Set the ifile's inode entry to unused, increment its version number
159 	 * and link it into the free chain.
160 	 */
161 	LFS_IENTRY(ifp, fs, ino, bp);
162 	ifp->if_daddr = LFS_UNUSED_DADDR;
163 	++ifp->if_version;
164 	ifp->if_nextfree = fs->lfs_free;
165 	fs->lfs_free = ino;
166 	LFS_IWRITE(fs, bp);
167 
168 	/* Set superblock modified bit and decrement file count. */
169 	fs->lfs_fmod = 1;
170 	--fs->lfs_nfiles;
171 }
172