initialize the size field, FFS does it in newfs, we don't
[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 *
1ef966ee 7 * @(#)lfs_alloc.c 7.40 (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 30lfs_valloc(pvp, notused, cred, vpp)
889a3fb1 31 struct vnode *pvp, **vpp;
ddd9f644 32 int notused;
889a3fb1 33 struct ucred *cred;
e3fe2d69 34{
4bed3ffc 35 struct lfs *fs;
889a3fb1
KB
36 struct buf *bp;
37 struct ifile *ifp;
38 struct inode *ip;
39 struct vnode *vp;
40 daddr_t blkno;
0b4d6502 41 ino_t new_ino;
889a3fb1 42 u_long i, max;
0b4d6502 43 int error;
e3fe2d69 44
a71716ec
KB
45#ifdef VERBOSE
46 printf("lfs_valloc\n");
47#endif
275ca4f0 48 /* Get the head of the freelist. */
a58cc97d 49 fs = VTOI(pvp)->i_lfs;
0b4d6502 50 new_ino = fs->lfs_free;
ddd9f644
KB
51#ifdef ALLOCPRINT
52 printf("lfs_ialloc: allocate inode %d\n", new_ino);
53#endif
0b4d6502 54
1344ae31 55 /*
889a3fb1
KB
56 * Remove the inode from the free list and write the new start
57 * of the free list into the superblock.
1344ae31 58 */
0b4d6502 59 LFS_IENTRY(ifp, fs, new_ino, bp);
0b4d6502 60 if (ifp->if_daddr != LFS_UNUSED_DADDR)
275ca4f0 61 panic("lfs_ialloc: inuse inode on the free list");
0b4d6502 62 fs->lfs_free = ifp->if_nextfree;
889a3fb1
KB
63 brelse(bp);
64
65 /* Extend IFILE so that the next lfs_valloc will succeed. */
66 if (fs->lfs_free == LFS_UNUSED_INUM) {
67 vp = fs->lfs_ivnode;
68 ip = VTOI(vp);
69 blkno = lblkno(fs, ip->i_size);
70printf("Extending ifile: blkno = %d\n", blkno);
71 bp = getblk(vp, blkno, fs->lfs_bsize);
72 if (!bp) {
73 uprintf("\n%s: no inodes left\n", fs->lfs_fsmnt);
74 log(LOG_ERR, "uid %d on %s: out of inodes\n",
75 cred->cr_uid, fs->lfs_fsmnt);
76 return (ENOSPC);
77 }
78 i = (blkno - fs->lfs_segtabsz - fs->lfs_cleansz) *
79 fs->lfs_ifpb;
80printf("Extending ifile: first inum = %d\n", i);
81 fs->lfs_free = i;
82 max = i + fs->lfs_ifpb;
83printf("Extending ifile: max inum = %d\n", max);
84 for (ifp = (struct ifile *)bp->b_un.b_words; i < max; ++ifp) {
85 ifp->if_version = 1;
86 ifp->if_daddr = LFS_UNUSED_DADDR;
87 ifp->if_nextfree = ++i;
88 }
89 ifp--;
90 ifp->if_nextfree = LFS_UNUSED_INUM;
91
92 ++ip->i_blocks; /* XXX This may not be right. */
93 ip->i_size += fs->lfs_bsize;
94printf("Extending ifile: blocks = %d size = %d\n", ip->i_blocks, ip->i_size);
95 vnode_pager_setsize(vp, ip->i_size);
96 vnode_pager_uncache(vp);
97 LFS_UBWRITE(bp);
98 }
07670f7d 99
275ca4f0 100 /* Create a vnode to associate with the inode. */
a58cc97d 101 if (error = lfs_vcreate(pvp->v_mount, new_ino, &vp))
7188ac27 102 return (error);
a58cc97d
KM
103 *vpp = vp;
104 ip = VTOI(vp);
105 VREF(ip->i_devvp);
0b4d6502 106
889a3fb1
KB
107 /* Zero out the direct and indirect block addresses. */
108 bzero(ip->i_db, (NDADDR + NIADDR) * sizeof(daddr_t));
109
275ca4f0 110 /* Set a new generation number for this inode. */
fb92d0ab
KM
111 if (++nextgennumber < (u_long)time.tv_sec)
112 nextgennumber = time.tv_sec;
113 ip->i_gen = nextgennumber;
e3fe2d69 114
275ca4f0 115 /* Insert into the inode hash table. */
ddd9f644 116 ufs_ihashins(ip);
743f1ef7 117
275ca4f0
KB
118 /* Set superblock modified bit and increment file count. */
119 fs->lfs_fmod = 1;
120 ++fs->lfs_nfiles;
0b4d6502 121 return (0);
e3fe2d69
KM
122}
123
275ca4f0 124/* Create a new vnode/inode pair and initialize what fields we can. */
0a0d4fba 125int
0b4d6502 126lfs_vcreate(mp, ino, vpp)
889a3fb1 127 struct mount *mp;
0b4d6502 128 ino_t ino;
889a3fb1 129 struct vnode **vpp;
e3fe2d69 130{
a58cc97d 131 extern struct vnodeops lfs_vnodeops;
889a3fb1
KB
132 struct inode *ip;
133 struct ufsmount *ump;
0b4d6502
KB
134 int error, i;
135
a71716ec 136#ifdef VERBOSE
ddd9f644
KB
137 printf("lfs_vcreate: ino %d\n", ino);
138#endif
275ca4f0 139 /* Create the vnode. */
4c5ed28a
KM
140 if (error = getnewvnode(VT_LFS, mp, &lfs_vnodeops, vpp)) {
141 *vpp = NULL;
5e1f6927 142 return (error);
4c5ed28a 143 }
0b4d6502 144
275ca4f0 145 /* Get a pointer to the private mount structure. */
0b4d6502
KB
146 ump = VFSTOUFS(mp);
147
148 /* Initialize the inode. */
4c5ed28a
KM
149 MALLOC(ip, struct inode *, sizeof(struct inode), M_LFSNODE, M_WAITOK);
150 (*vpp)->v_data = ip;
a58cc97d 151 ip->i_vnode = *vpp;
1ef966ee 152 ip->i_devvp = ump->um_devvp;
0b4d6502 153 ip->i_flag = 0;
a58cc97d 154 ip->i_dev = ump->um_dev;
d5075120 155 ip->i_number = ip->i_din.di_inum = ino;
a58cc97d 156 ip->i_lfs = ump->um_lfs;
0b4d6502
KB
157#ifdef QUOTA
158 for (i = 0; i < MAXQUOTAS; i++)
159 ip->i_dquot[i] = NODQUOT;
160#endif
1ef966ee
KB
161 ip->i_lockf = 0;
162 ip->i_diroff = 0;
163 ip->i_mode = 0;
164 ip->i_size = 0;
0b4d6502 165 return (0);
e3fe2d69 166}
d5075120 167
ddd9f644
KB
168/* Free an inode. */
169/* ARGUSED */
275ca4f0 170void
a58cc97d 171lfs_vfree(vp, notused1, notused2)
889a3fb1 172 struct vnode *vp;
ddd9f644
KB
173 ino_t notused1;
174 int notused2;
275ca4f0 175{
889a3fb1
KB
176 struct buf *bp;
177 struct ifile *ifp;
178 struct inode *ip;
4bed3ffc 179 struct lfs *fs;
275ca4f0
KB
180 ino_t ino;
181
a58cc97d 182 ip = VTOI(vp);
a71716ec
KB
183#ifdef VERBOSE
184 printf("lfs_vfree: free %d\n", ip->i_number);
ddd9f644
KB
185#endif
186 /* Get the inode number and file system. */
275ca4f0
KB
187 fs = ip->i_lfs;
188 ino = ip->i_number;
ddd9f644
KB
189
190 /*
1344ae31
KB
191 * Set the ifile's inode entry to unused, increment its version number
192 * and link it into the free chain.
ddd9f644 193 */
275ca4f0 194 LFS_IENTRY(ifp, fs, ino, bp);
ddd9f644
KB
195 ifp->if_daddr = LFS_UNUSED_DADDR;
196 ++ifp->if_version;
197 ifp->if_nextfree = fs->lfs_free;
198 fs->lfs_free = ino;
889a3fb1 199 LFS_UBWRITE(bp);
ddd9f644
KB
200
201 /* Set superblock modified bit and decrement file count. */
202 fs->lfs_fmod = 1;
203 --fs->lfs_nfiles;
275ca4f0 204}