xref: /csrg-svn/sys/ufs/lfs/lfs_alloc.c (revision 51492)
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.34 (Berkeley) 11/01/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_ialloc(pip, notused, cred, ipp)
30 	INODE *pip, **ipp;
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 	/* Get the head of the freelist. */
43 	fs = pip->i_lfs;
44 	new_ino = fs->lfs_free;
45 	if (new_ino == LFS_UNUSED_INUM) {
46 		/*
47 		 * XXX
48 		 * Currently, no more inodes are allocated if the ifile fills
49 		 * up.  The ifile should be extended instead.
50 		 */
51 		uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
52 		log(LOG_ERR, "uid %d on %s: out of inodes\n",
53 		    cred->cr_uid, fs->lfs_fsmnt);
54 		return (ENOSPC);
55 	}
56 #ifdef ALLOCPRINT
57 	printf("lfs_ialloc: allocate inode %d\n", new_ino);
58 #endif
59 
60 	/* Read the appropriate block from the ifile. */
61 	LFS_IENTRY(ifp, fs, new_ino, bp);
62 
63 	if (ifp->if_daddr != LFS_UNUSED_DADDR)
64 		panic("lfs_ialloc: inuse inode on the free list");
65 
66 	/* Remove from the free list, set the access time, write it back. */
67 	fs->lfs_free = ifp->if_nextfree;
68 	ifp->if_st_atime = time.tv_sec;
69 	lfs_bwrite(bp);
70 
71 	/* Create a vnode to associate with the inode. */
72 	error = lfs_vcreate(ITOV(pip)->v_mount, new_ino, &vp);
73 	if (error)
74 		return (error);
75 	*ipp = ip = VTOI(vp);
76 
77 	/* Set a new generation number for this inode. */
78 	if (++nextgennumber < (u_long)time.tv_sec)
79 		nextgennumber = time.tv_sec;
80 	ip->i_gen = nextgennumber;
81 
82 	/* Insert into the inode hash table. */
83 	ufs_ihashins(ip);
84 
85 	/* Set superblock modified bit and increment file count. */
86 	fs->lfs_fmod = 1;
87 	++fs->lfs_nfiles;
88 	return (0);
89 }
90 
91 /* Create a new vnode/inode pair and initialize what fields we can. */
92 int
93 lfs_vcreate(mp, ino, vpp)
94 	MOUNT *mp;
95 	ino_t ino;
96 	VNODE **vpp;
97 {
98 	INODE *ip;
99 	UFSMOUNT *ump;
100 	int error, i;
101 
102 #ifdef ALLOCPRINT
103 	printf("lfs_vcreate: ino %d\n", ino);
104 #endif
105 	/* Create the vnode. */
106 	if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp))
107 		return (error);
108 
109 	/* Get a pointer to the private mount structure. */
110 	ump = VFSTOUFS(mp);
111 
112 	/* Initialize the inode. */
113 	ip = VTOI(*vpp);
114 	ip->i_diroff = 0;
115 	ip->i_devvp = ump->um_devvp;
116 	ip->i_dev = ump->um_dev;
117 	ip->i_flag = 0;
118 	ip->i_lfs = ump->um_lfs;
119 	ip->i_lockf = 0;
120 	ip->i_mode = 0;
121 	ip->i_number = ip->i_din.di_inum = ino;
122 	ip->i_vnode = *vpp;
123 #ifdef QUOTA
124 	for (i = 0; i < MAXQUOTAS; i++)
125 		ip->i_dquot[i] = NODQUOT;
126 #endif
127 	VREF(ip->i_devvp);			/* XXX: Why? */
128 	return (0);
129 }
130 
131 /* Free an inode. */
132 /* ARGUSED */
133 void
134 lfs_ifree(ip, notused1, notused2)
135 	INODE *ip;
136 	ino_t notused1;
137 	int notused2;
138 {
139 	BUF *bp;
140 	IFILE *ifp;
141 	struct lfs *fs;
142 	ino_t ino;
143 
144 #ifdef ALLOCPRINT
145 	printf("lfs_ifree: free %d\n", ip->i_number);
146 #endif
147 	/* Get the inode number and file system. */
148 	fs = ip->i_lfs;
149 	ino = ip->i_number;
150 
151 	/*
152 	 * Read the appropriate block from the ifile.  Set the inode entry to
153 	 * unused, increment its version number and link it into the free chain.
154 	 */
155 	LFS_IENTRY(ifp, fs, ino, bp);
156 	ifp->if_daddr = LFS_UNUSED_DADDR;
157 	++ifp->if_version;
158 	ifp->if_nextfree = fs->lfs_free;
159 	fs->lfs_free = ino;
160 
161 	lfs_bwrite(bp);
162 
163 	/* Set superblock modified bit and decrement file count. */
164 	fs->lfs_fmod = 1;
165 	--fs->lfs_nfiles;
166 }
167