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