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