clean up cruft after getting new IMP microcode
[unix-history] / usr / src / sys / ufs / ffs / ufs_vnops.c
CommitLineData
f3156a73 1/* ufs_vnops.c 4.17 82/01/19 */
d67a03eb
BJ
2
3#include "../h/param.h"
4#include "../h/systm.h"
5#include "../h/mount.h"
6#include "../h/ino.h"
7#include "../h/reg.h"
8#include "../h/buf.h"
9#include "../h/filsys.h"
10#include "../h/dir.h"
11#include "../h/user.h"
12#include "../h/inode.h"
13#include "../h/file.h"
14#include "../h/conf.h"
15#include "../h/stat.h"
0737b714 16#include "../h/inline.h"
ae921915
BJ
17#include "../h/socket.h"
18#include "../h/socketvar.h"
d67a03eb
BJ
19
20/*
21 * the fstat system call.
22 */
23fstat()
24{
25 register struct file *fp;
26 register struct a {
27 int fdes;
28 struct stat *sb;
29 } *uap;
30
31 uap = (struct a *)u.u_ap;
32 fp = getf(uap->fdes);
e92a04af 33 if (fp == NULL)
d67a03eb 34 return;
e92a04af 35 if (fp->f_flag & FSOCKET)
cc15ab5d 36 u.u_error = sostat(fp->f_socket, uap->sb);
e92a04af
BJ
37 else
38 stat1(fp->f_inode, uap->sb);
d67a03eb
BJ
39}
40
41/*
e92a04af 42 * Stat system call.
d67a03eb
BJ
43 */
44stat()
45{
46 register struct inode *ip;
47 register struct a {
48 char *fname;
49 struct stat *sb;
50 } *uap;
51
52 uap = (struct a *)u.u_ap;
53 ip = namei(uchar, 0);
e92a04af 54 if (ip == NULL)
d67a03eb 55 return;
a3aa7f92 56 stat1(ip, uap->sb);
d67a03eb
BJ
57 iput(ip);
58}
59
60/*
61 * The basic routine for fstat and stat:
62 * get the inode and pass appropriate parts back.
63 */
a3aa7f92 64stat1(ip, ub)
e92a04af
BJ
65 register struct inode *ip;
66 struct stat *ub;
d67a03eb
BJ
67{
68 register struct dinode *dp;
69 register struct buf *bp;
70 struct stat ds;
71
c0bb1685 72 IUPDAT(ip, &time, &time, 0);
d67a03eb 73 /*
e92a04af 74 * First copy from inode table
d67a03eb
BJ
75 */
76 ds.st_dev = ip->i_dev;
77 ds.st_ino = ip->i_number;
78 ds.st_mode = ip->i_mode;
79 ds.st_nlink = ip->i_nlink;
80 ds.st_uid = ip->i_uid;
81 ds.st_gid = ip->i_gid;
82 ds.st_rdev = (dev_t)ip->i_un.i_rdev;
a3aa7f92 83 ds.st_size = ip->i_size;
d67a03eb 84 /*
e92a04af 85 * Next the dates in the disk
d67a03eb
BJ
86 */
87 bp = bread(ip->i_dev, itod(ip->i_number));
88 dp = bp->b_un.b_dino;
89 dp += itoo(ip->i_number);
90 ds.st_atime = dp->di_atime;
91 ds.st_mtime = dp->di_mtime;
92 ds.st_ctime = dp->di_ctime;
93 brelse(bp);
94 if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
95 u.u_error = EFAULT;
96}
97
98/*
e92a04af 99 * Dup system call.
d67a03eb
BJ
100 */
101dup()
102{
103 register struct file *fp;
104 register struct a {
105 int fdes;
106 int fdes2;
107 } *uap;
108 register i, m;
109
110 uap = (struct a *)u.u_ap;
111 m = uap->fdes & ~077;
112 uap->fdes &= 077;
113 fp = getf(uap->fdes);
e92a04af 114 if (fp == NULL)
d67a03eb
BJ
115 return;
116 if ((m&0100) == 0) {
117 if ((i = ufalloc()) < 0)
118 return;
119 } else {
120 i = uap->fdes2;
121 if (i<0 || i>=NOFILE) {
122 u.u_error = EBADF;
123 return;
124 }
d67a03eb
BJ
125 u.u_r.r_val1 = i;
126 }
e92a04af 127 if (i != uap->fdes) {
d67a03eb 128 if (u.u_ofile[i]!=NULL)
f3156a73
BJ
129 closef(u.u_ofile[i], 0);
130 if (u.u_error)
131 return;
d67a03eb
BJ
132 u.u_ofile[i] = fp;
133 fp->f_count++;
134 }
135}
136
137/*
e92a04af 138 * Mount system call.
d67a03eb 139 */
e92a04af
BJ
140smount()
141{
d67a03eb
BJ
142 dev_t dev;
143 register struct inode *ip;
144 register struct mount *mp;
145 struct mount *smp;
146 register struct filsys *fp;
147 struct buf *bp;
148 register struct a {
149 char *fspec;
150 char *freg;
151 int ronly;
152 } *uap;
1e608f17 153 register char *cp;
d67a03eb
BJ
154
155 uap = (struct a *)u.u_ap;
156 dev = getmdev();
e92a04af 157 if (u.u_error)
d67a03eb
BJ
158 return;
159 u.u_dirp = (caddr_t)uap->freg;
160 ip = namei(uchar, 0);
e92a04af 161 if (ip == NULL)
d67a03eb 162 return;
e92a04af 163 if (ip->i_count!=1 || (ip->i_mode&IFMT) != IFDIR)
d67a03eb
BJ
164 goto out;
165 smp = NULL;
e92a04af
BJ
166 for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++) {
167 if (mp->m_bufp != NULL) {
168 if (dev == mp->m_dev)
d67a03eb
BJ
169 goto out;
170 } else
e92a04af 171 if (smp == NULL)
d67a03eb
BJ
172 smp = mp;
173 }
174 mp = smp;
e92a04af 175 if (mp == NULL)
d67a03eb
BJ
176 goto out;
177 (*bdevsw[major(dev)].d_open)(dev, !uap->ronly);
e92a04af 178 if (u.u_error)
d67a03eb
BJ
179 goto out;
180 bp = bread(dev, SUPERB);
e92a04af 181 if (u.u_error) {
d67a03eb
BJ
182 brelse(bp);
183 goto out1;
184 }
185 mp->m_inodp = ip;
186 mp->m_dev = dev;
2c3059b1
BJ
187 bp->b_flags |= B_LOCKED;
188 mp->m_bufp = bp;
189 fp = bp->b_un.b_filsys;
d67a03eb
BJ
190 fp->s_ilock = 0;
191 fp->s_flock = 0;
192 fp->s_ronly = uap->ronly & 1;
193 fp->s_nbehind = 0;
194 fp->s_lasti = 1;
1e608f17
BJ
195 u.u_dirp = uap->freg;
196 for (cp = fp->s_fsmnt; cp < &fp->s_fsmnt[sizeof (fp->s_fsmnt) - 1]; )
197 if ((*cp++ = uchar()) == 0)
198 u.u_dirp--; /* get 0 again */
199 *cp = 0;
d67a03eb
BJ
200 brelse(bp);
201 ip->i_flag |= IMOUNT;
e92a04af 202 irele(ip);
d67a03eb
BJ
203 return;
204
205out:
206 u.u_error = EBUSY;
207out1:
208 iput(ip);
209}
210
211/*
212 * the umount system call.
213 */
214sumount()
215{
216 dev_t dev;
217 register struct inode *ip;
218 register struct mount *mp;
219 struct buf *bp;
2c3059b1 220 int stillopen, flag;
d67a03eb
BJ
221 register struct a {
222 char *fspec;
223 };
224
225 dev = getmdev();
e92a04af 226 if (u.u_error)
d67a03eb
BJ
227 return;
228 xumount(dev); /* remove unused sticky files from text table */
68503f9a 229 update(0);
e92a04af
BJ
230 for (mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
231 if (mp->m_bufp != NULL && dev == mp->m_dev)
d67a03eb
BJ
232 goto found;
233 u.u_error = EINVAL;
234 return;
235
236found:
9491f93d 237 stillopen = 0;
e92a04af 238 for (ip = inode; ip < inodeNINODE; ip++)
2c3059b1 239 if (ip->i_number != 0 && dev == ip->i_dev) {
d67a03eb
BJ
240 u.u_error = EBUSY;
241 return;
2c3059b1
BJ
242 } else if (ip->i_number != 0 && (ip->i_mode&IFMT) == IFBLK &&
243 ip->i_un.i_rdev == dev)
244 stillopen++;
d67a03eb
BJ
245 ip = mp->m_inodp;
246 ip->i_flag &= ~IMOUNT;
e92a04af 247 ilock(ip);
d67a03eb 248 iput(ip);
2c3059b1
BJ
249 if ((bp = getblk(dev, SUPERB)) != mp->m_bufp)
250 panic("umount");
251 bp->b_flags &= ~B_LOCKED;
4a18fb8e 252 flag = !bp->b_un.b_filsys->s_ronly;
d67a03eb
BJ
253 mp->m_bufp = NULL;
254 brelse(bp);
aa250f32 255 mpurge(mp - &mount[0]);
4a18fb8e 256 if (!stillopen) {
4a18fb8e
RE
257 (*bdevsw[major(dev)].d_close)(dev, flag);
258 binval(dev);
259 }
d67a03eb
BJ
260}
261
262/*
263 * Common code for mount and umount.
264 * Check that the user's argument is a reasonable
265 * thing on which to mount, and return the device number if so.
266 */
267dev_t
268getmdev()
269{
270 dev_t dev;
271 register struct inode *ip;
272
d67a03eb
BJ
273 if (!suser())
274 return(NODEV);
d67a03eb 275 ip = namei(uchar, 0);
e92a04af 276 if (ip == NULL)
d67a03eb 277 return(NODEV);
e92a04af 278 if ((ip->i_mode&IFMT) != IFBLK)
d67a03eb
BJ
279 u.u_error = ENOTBLK;
280 dev = (dev_t)ip->i_un.i_rdev;
e92a04af 281 if (major(dev) >= nblkdev)
d67a03eb
BJ
282 u.u_error = ENXIO;
283 iput(ip);
284 return(dev);
285}