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