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