xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51183)
1 /*
2  * Copyright (c) 1982, 1986, 1989 Regents of the University of California.
3  * All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  *
7  *	@(#)lfs_alloc.c	7.29 (Berkeley) 09/25/91
8  */
9 
10 #include "param.h"
11 #include "kernel.h"
12 #include "buf.h"
13 #include "vnode.h"
14 #include "syslog.h"
15 #include "../ufs/quota.h"
16 #include "../ufs/inode.h"
17 #include "mount.h"
18 #include "../ufs/ufsmount.h"
19 #include "lfs.h"
20 #include "lfs_extern.h"
21 
22 #define	LFS_IENTRY(I, F, IN, BP) \
23 	if (bread((F)->lfs_ivnode, (IN) / IFPB(F) + (F)->lfs_segtabsz, \
24 	    (F)->lfs_bsize, NOCRED, &BP)) \
25 		panic("ifile read"); \
26 	(I) = (IFILE *)BP->b_un.b_addr + IN % IFPB(F);
27 
28 ino_t
29 lfs_ialloc(fs, pip, ipp, cred)
30 	LFS *fs;
31 	INODE *pip, **ipp;
32 	UCRED *cred;
33 {
34 	BUF *bp;
35 	IFILE *ifp;
36 	INODE *ip;
37 	VNODE *vp;
38 	ino_t new_ino;
39 	int error;
40 
41 	new_ino = fs->lfs_free;
42 printf("lfs_ialloc: next free %d\n", new_ino);
43 	if (new_ino == LFS_UNUSED_INUM) {	/* XXX -- allocate more */
44 		uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
45 		log(LOG_ERR, "uid %d on %s: out of inodes\n",
46 		    cred->cr_uid, fs->lfs_fsmnt);
47 		return (ENOSPC);
48 	}
49 
50 	/* Read the appropriate block from the ifile */
51 	vp = fs->lfs_ivnode;
52 	LFS_IENTRY(ifp, fs, new_ino, bp);
53 
54 	if (ifp->if_daddr != LFS_UNUSED_DADDR)
55 		panic("lfs_ialloc: corrupt free list");
56 
57 	/* Remove from free list, set the access time. */
58 	fs->lfs_free = ifp->if_nextfree;
59 	ifp->if_st_atime = time.tv_sec;
60 	brelse(bp);
61 
62 	error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp);
63 	if (error)
64 		return (error);
65 
66 	ip = VTOI(vp);
67 	VREF(ip->i_devvp);
68 
69 	/*
70 	 * Set up a new generation number for this inode.
71 	 */
72 	if (++nextgennumber < (u_long)time.tv_sec)
73 		nextgennumber = time.tv_sec;
74 	ip->i_gen = nextgennumber;
75 
76 	lfs_hqueue(ip);
77 
78 	*ipp = ip;
79 	return (0);
80 }
81 
82 void
83 lfs_ifree(ip)
84 	INODE *ip;
85 {
86 	BUF *bp;
87 	IFILE *ifp;
88 	LFS *fs;
89 	ino_t ino;
90 
91 printf("lfs_ifree: free %d\n", ip->i_number);
92 	fs = ip->i_lfs;
93 	ino = ip->i_number;
94 	LFS_IENTRY(ifp, fs, ino, bp);
95 
96 	ifp->if_daddr = LFS_UNUSED_DADDR;
97 	++ifp->if_version;
98 	ifp->if_nextfree = fs->lfs_free;
99 	brelse(bp);
100 	fs->lfs_free = ino;
101 	fs->lfs_fmod = 1;
102 }
103 
104 daddr_t
105 itod(fs, ino)
106 	LFS *fs;
107 	ino_t ino;
108 {
109 	BUF *bp;
110 	IFILE *ifp;
111 	daddr_t iaddr;
112 
113 printf("itod: ino %d\n", ino);
114 	LFS_IENTRY(ifp, fs, ino, bp);
115 
116 	if (ifp->if_daddr == LFS_UNUSED_DADDR)
117 		panic("itod: unused daddr");
118 	iaddr = ifp->if_daddr;
119 	brelse(bp);
120 	return (iaddr);
121 }
122 
123 DINODE *
124 lfs_ifind(fs, ino, page)
125 	LFS *fs;
126 	ino_t ino;
127 	void *page;
128 {
129 	register DINODE *dip;
130 	register int cnt;
131 
132 printf("lfs_ifind: inode %d\n", ino);
133 	dip = page;
134 	for (cnt = INOPB(fs); cnt--; ++dip)
135 		if (dip->di_inum == ino)
136 			return (dip);
137 
138 	(void)printf("lfs_ifind: dinode %u not found", ino);
139 	panic("lfs_ifind: inode not found");
140 	/* NOTREACHED */
141 }
142 
143 /*
144  * Create a new vnode/inode and initialize the fields we can.
145  */
146 lfs_vcreate(mp, ino, vpp)
147 	MOUNT *mp;
148 	ino_t ino;
149 	VNODE **vpp;
150 {
151 	INODE *ip;
152 	UFSMOUNT *ump;
153 	int error, i;
154 
155 printf("lfs_vcreate: ino %d\n", ino);
156 	error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp);
157 	if (error)
158 		return(error);
159 
160 	ump = VFSTOUFS(mp);
161 
162 	/* Initialize the inode. */
163 	ip = VTOI(*vpp);
164 	ip->i_diroff = 0;
165 	ip->i_devvp = ump->um_devvp;
166 	ip->i_dev = ump->um_dev;
167 	ip->i_flag = 0;
168 	ip->i_lfs = ump->um_lfs;
169 	ip->i_lockf = 0;
170 	ip->i_mode = 0;
171 	ip->i_number = ip->i_din.di_inum = ino;
172 	ip->i_vnode = *vpp;
173 #ifdef QUOTA
174 	for (i = 0; i < MAXQUOTAS; i++)
175 		ip->i_dquot[i] = NODQUOT;
176 #endif
177 	return (0);
178 }
179 
180 /*
181  * Return the current version number for a specific inode.
182  */
183 u_long
184 lfs_getversion(fs, ino)
185 	LFS *fs;
186 	ino_t ino;
187 {
188 	IFILE *ifp;
189 	BUF *bp;
190 	int version;
191 
192 printf("lfs_getversion: %d\n", ino);
193 	LFS_IENTRY(ifp, fs, ino, bp);
194 	version = ifp->if_version;
195 	brelse(bp);
196 	return(version);
197 }
198