xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51155)
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.28 (Berkeley) 09/20/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 	struct inode *pip, **ipp;
32 	struct ucred *cred;
33 {
34 	IFILE *ifp;
35 	struct buf *bp;
36 	struct inode *ip;
37 	struct 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 	ifp->if_st_atime = time.tv_sec;
59 	fs->lfs_free = ifp->if_nextfree;
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 	struct inode *ip;
85 {
86 	IFILE *ifp;
87 	LFS *fs;
88 	struct buf *bp;
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 	struct 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 printf("itod: about to return %lx\n", ifp->if_daddr);
119 	return (ifp->if_daddr);
120 }
121 
122 struct dinode *
123 lfs_ifind(fs, ino, page)
124 	LFS *fs;
125 	ino_t ino;
126 	void *page;
127 {
128 	register struct dinode *dip;
129 	register int cnt;
130 
131 printf("lfs_ifind: inode %d\n", ino);
132 	dip = page;
133 	for (cnt = INOPB(fs); cnt--; ++dip)
134 		if (dip->di_inum == ino)
135 			return (dip);
136 
137 	(void)printf("lfs_ifind: dinode %u not found", ino);
138 	panic("lfs_ifind: inode not found");
139 	/* NOTREACHED */
140 }
141 
142 /*
143  * Create a new vnode/inode and initialize the fields we can.
144  */
145 lfs_vcreate(mp, ino, vpp)
146 	struct mount *mp;
147 	ino_t ino;
148 	struct vnode **vpp;
149 {
150 	struct inode *ip;
151 	struct ufsmount *ump;
152 	int error, i;
153 
154 printf("lfs_vcreate: ino %d\n", ino);
155 	error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp);
156 	if (error)
157 		return(error);
158 
159 	ump = VFSTOUFS(mp);
160 
161 	/* Initialize the inode. */
162 	ip = VTOI(*vpp);
163 	ip->i_diroff = 0;
164 	ip->i_devvp = ump->um_devvp;
165 	ip->i_dev = ump->um_dev;
166 	ip->i_flag = 0;
167 	ip->i_lfs = ump->um_lfs;
168 	ip->i_lockf = 0;
169 	ip->i_mode = 0;
170 	ip->i_number = ino;
171 	ip->i_vnode = *vpp;
172 #ifdef QUOTA
173 	for (i = 0; i < MAXQUOTAS; i++)
174 		ip->i_dquot[i] = NODQUOT;
175 #endif
176 	return (0);
177 }
178