1: /*
2: * @(#) ufs_syscalls2.c 1.5 (2.11BSD) 1997/1/31
3: *
4: * ufs_syscalls was getting too large. Various UFS related system calls were
5: * relocated to this file.
6: */
7:
8: #include "param.h"
9: #include "../machine/seg.h"
10: #include "sys/file.h"
11: #include "user.h"
12: #include "inode.h"
13: #include "buf.h"
14: #include "fs.h"
15: #include "namei.h"
16: #include "mount.h"
17: #include "kernel.h"
18:
19: statfs()
20: {
21: register struct a
22: {
23: char *path;
24: struct statfs *buf;
25: } *uap = (struct a *)u.u_ap;
26: register struct inode *ip;
27: struct nameidata nd;
28: register struct nameidata *ndp = &nd;
29: struct mount *mp;
30:
31: NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, uap->path);
32: ip = namei(ndp);
33: if (!ip)
34: return(u.u_error);
35: mp = (struct mount *)((int)ip->i_fs - offsetof(struct mount, m_filsys));
36: iput(ip);
37: u.u_error = statfs1(mp, uap->buf);
38: return(u.u_error);
39: }
40:
41: fstatfs()
42: {
43: register struct a
44: {
45: int fd;
46: struct statfs *buf;
47: } *uap = (struct a *)u.u_ap;
48: register struct inode *ip;
49: struct mount *mp;
50:
51: ip = getinode(uap->fd);
52: if (!ip)
53: return(u.u_error);
54: mp = (struct mount *)((int)ip->i_fs - offsetof(struct mount, m_filsys));
55: u.u_error = statfs1(mp, uap->buf);
56: return(u.u_error);
57: }
58:
59: statfs1(mp, sbp)
60: struct mount *mp;
61: struct statfs *sbp;
62: {
63: struct statfs sfs;
64: register struct statfs *sfsp;
65: struct xmount *xmp = (struct xmount *)SEG5;
66: struct fs *fs = &mp->m_filsys;
67:
68: sfsp = &sfs;
69: sfsp->f_type = MOUNT_UFS;
70: sfsp->f_bsize = MAXBSIZE;
71: sfsp->f_iosize = MAXBSIZE;
72: sfsp->f_blocks = fs->fs_fsize - fs->fs_isize;
73: sfsp->f_bfree = fs->fs_tfree;
74: sfsp->f_bavail = fs->fs_tfree;
75: sfsp->f_files = (fs->fs_isize - 2) * INOPB;
76: sfsp->f_ffree = fs->fs_tinode;
77:
78: mapseg5(mp->m_extern, XMOUNTDESC);
79: bcopy(xmp->xm_mnton, sfsp->f_mntonname, MNAMELEN);
80: bcopy(xmp->xm_mntfrom, sfsp->f_mntfromname, MNAMELEN);
81: normalseg5();
82: sfsp->f_flags = mp->m_flags & MNT_VISFLAGMASK;
83: return(copyout(sfsp, sbp, sizeof (struct statfs)));
84: }
85:
86: getfsstat()
87: {
88: register struct a
89: {
90: struct statfs *buf;
91: int bufsize;
92: u_int flags;
93: } *uap = (struct a *)u.u_ap;
94: register struct mount *mp;
95: caddr_t sfsp;
96: int count, maxcount, error;
97:
98: maxcount = uap->bufsize / sizeof (struct statfs);
99: sfsp = (caddr_t)uap->buf;
100: count = 0;
101: for (mp = mount; mp < &mount[NMOUNT]; mp++)
102: {
103: if (mp->m_inodp == NULL)
104: continue;
105: if (count < maxcount)
106: {
107: if (error = statfs1(mp, sfsp))
108: return(u.u_error = error);
109: sfsp += sizeof (struct statfs);
110: }
111: count++;
112: }
113: if (sfsp && count > maxcount)
114: u.u_r.r_val1 = maxcount;
115: else
116: u.u_r.r_val1 = count;
117: return(0);
118: }
119:
120: /*
121: * 'ufs_sync' is the routine which syncs a single filesystem. This was
122: * created to replace 'update' which 'unmount' called. It seemed silly to
123: * sync _every_ filesystem when unmounting just one filesystem.
124: */
125:
126: ufs_sync(mp)
127: register struct mount *mp;
128: {
129: register struct fs *fs;
130: struct buf *bp;
131: int error = 0;
132:
133: fs = &mp->m_filsys;
134: if (fs->fs_fmod && (mp->m_flags & MNT_RDONLY))
135: {
136: printf("fs = %s\n", fs->fs_fsmnt);
137: panic("sync: rofs");
138: }
139: syncinodes(fs); /* sync the inodes for this filesystem */
140: bflush(mp->m_dev); /* flush dirty data blocks */
141: #ifdef QUOTA
142: qsync(mp->m_dev); /* sync the quotas */
143: #endif
144:
145: /*
146: * And lastly the superblock, if the filesystem was modified.
147: * Write back modified superblocks. Consistency check that the superblock
148: * of each file system is still in the buffer cache.
149: */
150: if (fs->fs_fmod)
151: {
152: bp = getblk(mp->m_dev, SUPERB);
153: fs->fs_fmod = 0;
154: fs->fs_time = time.tv_sec;
155: bcopy(fs, mapin(bp), sizeof (struct fs));
156: mapout(bp);
157: bwrite(bp);
158: error = geterror(bp);
159: }
160: return(error);
161: }
162:
163: /*
164: * This is somewhat inefficient in that the inode table is scanned for each
165: * filesystem but it didn't seem worth a page or two of code on something
166: * which only happens every 30 seconds.
167: */
168:
169: syncinodes(fs)
170: struct fs *fs;
171: {
172: register struct inode *ip;
173:
174: /*
175: * Write back each (modified) inode.
176: */
177: for (ip = inode; ip < inodeNINODE; ip++)
178: {
179: /*
180: * Attempt to reduce the overhead by short circuiting the scan if the
181: * inode is not for the filesystem being processed.
182: */
183: if (ip->i_fs != fs)
184: continue;
185: if ((ip->i_flag & ILOCKED) != 0 || ip->i_count == 0 ||
186: (ip->i_flag & (IMOD|IACC|IUPD|ICHG)) == 0)
187: continue;
188: ip->i_flag |= ILOCKED;
189: ip->i_count++;
190: iupdat(ip, &time, &time, 0);
191: iput(ip);
192: }
193: }
194:
195: /*
196: * mode mask for creation of files
197: */
198: umask()
199: {
200: register struct a {
201: int mask;
202: } *uap = (struct a *)u.u_ap;
203:
204: u.u_r.r_val1 = u.u_cmask;
205: u.u_cmask = uap->mask & 07777;
206: }
207:
208: /*
209: * Seek system call
210: */
211: lseek()
212: {
213: register struct file *fp;
214: register struct a {
215: int fd;
216: off_t off;
217: int sbase;
218: } *uap = (struct a *)u.u_ap;
219:
220: if ((fp = getf(uap->fd)) == NULL)
221: return;
222: if (fp->f_type != DTYPE_INODE) {
223: u.u_error = ESPIPE;
224: return;
225: }
226: switch (uap->sbase) {
227:
228: case L_INCR:
229: fp->f_offset += uap->off;
230: break;
231: case L_XTND:
232: fp->f_offset = uap->off + ((struct inode *)fp->f_data)->i_size;
233: break;
234: case L_SET:
235: fp->f_offset = uap->off;
236: break;
237: default:
238: u.u_error = EINVAL;
239: return;
240: }
241: u.u_r.r_off = fp->f_offset;
242: }
243:
244: /*
245: * Synch an open file.
246: */
247: fsync()
248: {
249: register struct a {
250: int fd;
251: } *uap = (struct a *)u.u_ap;
252: register struct inode *ip;
253:
254: if ((ip = getinode(uap->fd)) == NULL)
255: return;
256: ilock(ip);
257: syncip(ip);
258: iunlock(ip);
259: }
260:
261: utimes()
262: {
263: register struct a {
264: char *fname;
265: struct timeval *tptr;
266: } *uap = (struct a *)u.u_ap;
267: register struct inode *ip;
268: struct nameidata nd;
269: register struct nameidata *ndp = &nd;
270: struct timeval tv[2];
271: struct vattr vattr;
272:
273: VATTR_NULL(&vattr);
274: if (uap->tptr == NULL) {
275: tv[0].tv_sec = tv[1].tv_sec = time.tv_sec;
276: vattr.va_vaflags |= VA_UTIMES_NULL;
277: } else if (u.u_error = copyin((caddr_t)uap->tptr,(caddr_t)tv,sizeof(tv)))
278: return;
279: NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, uap->fname);
280: if ((ip = namei(ndp)) == NULL)
281: return;
282: vattr.va_atime = tv[0].tv_sec;
283: vattr.va_mtime = tv[1].tv_sec;
284: u.u_error = ufs_setattr(ip, &vattr);
285: iput(ip);
286: }
Defined functions
Defined struct's
a
defined in line
263; used 14 times