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