Research V6 development
[unix-history] / usr / sys / ken / sys3.c
CommitLineData
f1b39b19
KT
1#
2/*
3 */
4
5#include "../param.h"
6#include "../systm.h"
7#include "../reg.h"
8#include "../buf.h"
9#include "../filsys.h"
10#include "../user.h"
11#include "../inode.h"
12#include "../file.h"
13#include "../conf.h"
14
15/*
16 * the fstat system call.
17 */
18fstat()
19{
20 register *fp;
21
22 fp = getf(u.u_ar0[R0]);
23 if(fp == NULL)
24 return;
25 stat1(fp->f_inode, u.u_arg[0]);
26}
27
28/*
29 * the stat system call.
30 */
31stat()
32{
33 register ip;
34 extern uchar;
35
36 ip = namei(&uchar, 0);
37 if(ip == NULL)
38 return;
39 stat1(ip, u.u_arg[1]);
40 iput(ip);
41}
42
43/*
44 * The basic routine for fstat and stat:
45 * get the inode and pass appropriate parts back.
46 */
47stat1(ip, ub)
48int *ip;
49{
50 register i, *bp, *cp;
51
52 iupdat(ip, time);
53 bp = bread(ip->i_dev, ldiv(ip->i_number+31, 16));
54 cp = bp->b_addr + 32*lrem(ip->i_number+31, 16) + 24;
55 ip = &(ip->i_dev);
56 for(i=0; i<14; i++) {
57 suword(ub, *ip++);
58 ub =+ 2;
59 }
60 for(i=0; i<4; i++) {
61 suword(ub, *cp++);
62 ub =+ 2;
63 }
64 brelse(bp);
65}
66
67/*
68 * the dup system call.
69 */
70dup()
71{
72 register i, *fp;
73
74 fp = getf(u.u_ar0[R0]);
75 if(fp == NULL)
76 return;
77 if ((i = ufalloc()) < 0)
78 return;
79 u.u_ofile[i] = fp;
80 fp->f_count++;
81}
82
83/*
84 * the mount system call.
85 */
86smount()
87{
88 int d;
89 register *ip;
90 register struct mount *mp, *smp;
91 extern uchar;
92
93 d = getmdev();
94 if(u.u_error)
95 return;
96 u.u_dirp = u.u_arg[1];
97 ip = namei(&uchar, 0);
98 if(ip == NULL)
99 return;
100 if(ip->i_count!=1 || (ip->i_mode&(IFBLK&IFCHR))!=0)
101 goto out;
102 smp = NULL;
103 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++) {
104 if(mp->m_bufp != NULL) {
105 if(d == mp->m_dev)
106 goto out;
107 } else
108 if(smp == NULL)
109 smp = mp;
110 }
111 if(smp == NULL)
112 goto out;
113 (*bdevsw[d.d_major].d_open)(d, !u.u_arg[2]);
114 if(u.u_error)
115 goto out;
116 mp = bread(d, 1);
117 if(u.u_error) {
118 brelse(mp);
119 goto out1;
120 }
121 smp->m_inodp = ip;
122 smp->m_dev = d;
123 smp->m_bufp = getblk(NODEV);
124 bcopy(mp->b_addr, smp->m_bufp->b_addr, 256);
125 smp = smp->m_bufp->b_addr;
126 smp->s_ilock = 0;
127 smp->s_flock = 0;
128 smp->s_ronly = u.u_arg[2] & 1;
129 brelse(mp);
130 ip->i_flag =| IMOUNT;
131 prele(ip);
132 return;
133
134out:
135 u.u_error = EBUSY;
136out1:
137 iput(ip);
138}
139
140/*
141 * the umount system call.
142 */
143sumount()
144{
145 int d;
146 register struct inode *ip;
147 register struct mount *mp;
148
149 update();
150 d = getmdev();
151 if(u.u_error)
152 return;
153 for(mp = &mount[0]; mp < &mount[NMOUNT]; mp++)
154 if(mp->m_bufp!=NULL && d==mp->m_dev)
155 goto found;
156 u.u_error = EINVAL;
157 return;
158
159found:
160 for(ip = &inode[0]; ip < &inode[NINODE]; ip++)
161 if(ip->i_number!=0 && d==ip->i_dev) {
162 u.u_error = EBUSY;
163 return;
164 }
165 (*bdevsw[d.d_major].d_close)(d, 0);
166 ip = mp->m_inodp;
167 ip->i_flag =& ~IMOUNT;
168 iput(ip);
169 ip = mp->m_bufp;
170 mp->m_bufp = NULL;
171 brelse(ip);
172}
173
174/*
175 * Common code for mount and umount.
176 * Check that the user's argument is a reasonable
177 * thing on which to mount, and return the device number if so.
178 */
179getmdev()
180{
181 register d, *ip;
182 extern uchar;
183
184 ip = namei(&uchar, 0);
185 if(ip == NULL)
186 return;
187 if((ip->i_mode&IFMT) != IFBLK)
188 u.u_error = ENOTBLK;
189 d = ip->i_addr[0];
190 if(ip->i_addr[0].d_major >= nblkdev)
191 u.u_error = ENXIO;
192 iput(ip);
193 return(d);
194}