fstat for ports now in pipe.c
[unix-history] / usr / src / sys / kern / vfs_syscalls.c
CommitLineData
a3aa7f92 1/* vfs_syscalls.c 4.10 81/04/28 */
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 }
37 stat1(fp->f_inode, uap->sb);
d67a03eb
BJ
38}
39
40/*
41 * the stat system call.
42 */
43stat()
44{
45 register struct inode *ip;
46 register struct a {
47 char *fname;
48 struct stat *sb;
49 } *uap;
50
51 uap = (struct a *)u.u_ap;
52 ip = namei(uchar, 0);
53 if(ip == NULL)
54 return;
a3aa7f92 55 stat1(ip, uap->sb);
d67a03eb
BJ
56 iput(ip);
57}
58
59/*
60 * The basic routine for fstat and stat:
61 * get the inode and pass appropriate parts back.
62 */
a3aa7f92 63stat1(ip, ub)
d67a03eb
BJ
64register struct inode *ip;
65struct stat *ub;
d67a03eb
BJ
66{
67 register struct dinode *dp;
68 register struct buf *bp;
69 struct stat ds;
70
c0bb1685 71 IUPDAT(ip, &time, &time, 0);
d67a03eb
BJ
72 /*
73 * first copy from inode table
74 */
75 ds.st_dev = ip->i_dev;
76 ds.st_ino = ip->i_number;
77 ds.st_mode = ip->i_mode;
78 ds.st_nlink = ip->i_nlink;
79 ds.st_uid = ip->i_uid;
80 ds.st_gid = ip->i_gid;
81 ds.st_rdev = (dev_t)ip->i_un.i_rdev;
a3aa7f92 82 ds.st_size = ip->i_size;
d67a03eb
BJ
83 /*
84 * next the dates in the disk
85 */
86 bp = bread(ip->i_dev, itod(ip->i_number));
87 dp = bp->b_un.b_dino;
88 dp += itoo(ip->i_number);
89 ds.st_atime = dp->di_atime;
90 ds.st_mtime = dp->di_mtime;
91 ds.st_ctime = dp->di_ctime;
92 brelse(bp);
93 if (copyout((caddr_t)&ds, (caddr_t)ub, sizeof(ds)) < 0)
94 u.u_error = EFAULT;
95}
96
97/*
98 * the dup system call.
99 */
100dup()
101{
102 register struct file *fp;
103 register struct a {
104 int fdes;
105 int fdes2;
106 } *uap;
107 register i, m;
108
109 uap = (struct a *)u.u_ap;
110 m = uap->fdes & ~077;
111 uap->fdes &= 077;
112 fp = getf(uap->fdes);
113 if(fp == NULL)
114 return;
115 if ((m&0100) == 0) {
116 if ((i = ufalloc()) < 0)
117 return;
118 } else {
119 i = uap->fdes2;
120 if (i<0 || i>=NOFILE) {
121 u.u_error = EBADF;
122 return;
123 }
124 if (u.u_vrpages[i]) {
125 u.u_error = ETXTBSY;
126 return;
127 }
128 u.u_r.r_val1 = i;
129 }
130 if (i!=uap->fdes) {
131 if (u.u_ofile[i]!=NULL)
132 closef(u.u_ofile[i]);
133 u.u_ofile[i] = fp;
134 fp->f_count++;
135 }
136}
137
138/*
139 * the mount system call.
140 */
1e608f17 141smount() {
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();
157 if(u.u_error)
158 return;
159 u.u_dirp = (caddr_t)uap->freg;
160 ip = namei(uchar, 0);
161 if(ip == NULL)
162 return;
163 if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0)
164 goto out;
165 smp = NULL;
166 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) {
167 if(mp->m_bufp != NULL) {
168 if(dev == mp->m_dev)
169 goto out;
170 } else
171 if(smp == NULL)
172 smp = mp;
173 }
174 mp = smp;
175 if(mp == NULL)
176 goto out;
177 (*bdevsw[major(dev)].d_open)(dev, !uap->ronly);
178 if(u.u_error)
179 goto out;
180 bp = bread(dev, SUPERB);
181 if(u.u_error) {
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;
202 prele(ip);
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();
226 if(u.u_error)
227 return;
228 xumount(dev); /* remove unused sticky files from text table */
229 update();
230 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
231 if(mp->m_bufp != NULL && dev == mp->m_dev)
232 goto found;
233 u.u_error = EINVAL;
234 return;
235
236found:
9491f93d 237 stillopen = 0;
75105cf0 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;
247 plock(ip);
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
BJ
275 ip = namei(uchar, 0);
276 if(ip == NULL)
277 return(NODEV);
278 if((ip->i_mode&IFMT) != IFBLK)
279 u.u_error = ENOTBLK;
280 dev = (dev_t)ip->i_un.i_rdev;
281 if(major(dev) >= nblkdev)
282 u.u_error = ENXIO;
283 iput(ip);
284 return(dev);
285}