|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
26: /*
27: * Copyright (c) 1982, 1986, 1989, 1993
28: * The Regents of the University of California. All rights reserved.
29: *
30: * Redistribution and use in source and binary forms, with or without
31: * modification, are permitted provided that the following conditions
32: * are met:
33: * 1. Redistributions of source code must retain the above copyright
34: * notice, this list of conditions and the following disclaimer.
35: * 2. Redistributions in binary form must reproduce the above copyright
36: * notice, this list of conditions and the following disclaimer in the
37: * documentation and/or other materials provided with the distribution.
38: * 3. All advertising materials mentioning features or use of this software
39: * must display the following acknowledgement:
40: * This product includes software developed by the University of
41: * California, Berkeley and its contributors.
42: * 4. Neither the name of the University nor the names of its contributors
43: * may be used to endorse or promote products derived from this software
44: * without specific prior written permission.
45: *
46: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56: * SUCH DAMAGE.
57: *
58: * @(#)ffs_vnops.c 8.15 (Berkeley) 5/14/95
59: */
60:
61: #include <rev_endian_fs.h>
62: #include <sys/param.h>
63: #include <sys/systm.h>
64: #include <sys/resourcevar.h>
65: #include <sys/kernel.h>
66: #include <sys/file.h>
67: #include <sys/stat.h>
68: #include <sys/buf.h>
69: #include <sys/proc.h>
70: #include <sys/conf.h>
71: #include <sys/mount.h>
72: #include <sys/vnode.h>
73: #include <sys/malloc.h>
74:
75: #include <sys/vm.h>
76:
77: #include <miscfs/specfs/specdev.h>
78: #include <miscfs/fifofs/fifo.h>
79:
80: #include <ufs/ufs/lockf.h>
81: #include <ufs/ufs/quota.h>
82: #include <ufs/ufs/inode.h>
83: #include <ufs/ufs/dir.h>
84: #include <ufs/ufs/ufsmount.h>
85: #include <ufs/ufs/ufs_extern.h>
86:
87: #include <ufs/ffs/fs.h>
88: #include <ufs/ffs/ffs_extern.h>
89: #if REV_ENDIAN_FS
90: #include <ufs/ufs/ufs_byte_order.h>
91: #include <architecture/byte_order.h>
92: #endif /* REV_ENDIAN_FS */
93:
94: /* Global vfs data structures for ufs. */
95: int (**ffs_vnodeop_p)();
96: struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
97: { &vop_default_desc, vn_default_error },
98: { &vop_lookup_desc, ufs_lookup }, /* lookup */
99: { &vop_create_desc, ufs_create }, /* create */
100: { &vop_whiteout_desc, ufs_whiteout }, /* whiteout */
101: { &vop_mknod_desc, ufs_mknod }, /* mknod */
102: { &vop_open_desc, ufs_open }, /* open */
103: { &vop_close_desc, ufs_close }, /* close */
104: { &vop_access_desc, ufs_access }, /* access */
105: { &vop_getattr_desc, ufs_getattr }, /* getattr */
106: { &vop_setattr_desc, ufs_setattr }, /* setattr */
107: { &vop_read_desc, ffs_read }, /* read */
108: { &vop_write_desc, ffs_write }, /* write */
109: { &vop_lease_desc, ufs_lease_check }, /* lease */
110: { &vop_ioctl_desc, ufs_ioctl }, /* ioctl */
111: { &vop_select_desc, ufs_select }, /* select */
112: { &vop_revoke_desc, ufs_revoke }, /* revoke */
113: { &vop_mmap_desc, ufs_mmap }, /* mmap */
114: { &vop_fsync_desc, ffs_fsync }, /* fsync */
115: { &vop_seek_desc, ufs_seek }, /* seek */
116: { &vop_remove_desc, ufs_remove }, /* remove */
117: { &vop_link_desc, ufs_link }, /* link */
118: { &vop_rename_desc, ufs_rename }, /* rename */
119: { &vop_mkdir_desc, ufs_mkdir }, /* mkdir */
120: { &vop_rmdir_desc, ufs_rmdir }, /* rmdir */
121: { &vop_symlink_desc, ufs_symlink }, /* symlink */
122: { &vop_readdir_desc, ufs_readdir }, /* readdir */
123: { &vop_readlink_desc, ufs_readlink }, /* readlink */
124: { &vop_abortop_desc, ufs_abortop }, /* abortop */
125: { &vop_inactive_desc, ufs_inactive }, /* inactive */
126: { &vop_reclaim_desc, ffs_reclaim }, /* reclaim */
127: { &vop_lock_desc, ufs_lock }, /* lock */
128: { &vop_unlock_desc, ufs_unlock }, /* unlock */
129: { &vop_bmap_desc, ufs_bmap }, /* bmap */
130: { &vop_strategy_desc, ufs_strategy }, /* strategy */
131: { &vop_print_desc, ufs_print }, /* print */
132: { &vop_islocked_desc, ufs_islocked }, /* islocked */
133: { &vop_pathconf_desc, ufs_pathconf }, /* pathconf */
134: { &vop_advlock_desc, ufs_advlock }, /* advlock */
135: { &vop_blkatoff_desc, ffs_blkatoff }, /* blkatoff */
136: { &vop_valloc_desc, ffs_valloc }, /* valloc */
137: { &vop_reallocblks_desc, ffs_reallocblks }, /* reallocblks */
138: { &vop_vfree_desc, ffs_vfree }, /* vfree */
139: { &vop_truncate_desc, ffs_truncate }, /* truncate */
140: { &vop_update_desc, ffs_update }, /* update */
141: { &vop_bwrite_desc, vn_bwrite },
142: { &vop_pagein_desc, ufs_pagein }, /* Pagein */
143: { &vop_pageout_desc, ufs_pageout }, /* Pageout */
144: { (struct vnodeop_desc*)NULL, (int(*)())NULL }
145: };
146: struct vnodeopv_desc ffs_vnodeop_opv_desc =
147: { &ffs_vnodeop_p, ffs_vnodeop_entries };
148:
149: int (**ffs_specop_p)();
150: struct vnodeopv_entry_desc ffs_specop_entries[] = {
151: { &vop_default_desc, vn_default_error },
152: { &vop_lookup_desc, spec_lookup }, /* lookup */
153: { &vop_create_desc, spec_create }, /* create */
154: { &vop_mknod_desc, spec_mknod }, /* mknod */
155: { &vop_open_desc, spec_open }, /* open */
156: { &vop_close_desc, ufsspec_close }, /* close */
157: { &vop_access_desc, ufs_access }, /* access */
158: { &vop_getattr_desc, ufs_getattr }, /* getattr */
159: { &vop_setattr_desc, ufs_setattr }, /* setattr */
160: { &vop_read_desc, ufsspec_read }, /* read */
161: { &vop_write_desc, ufsspec_write }, /* write */
162: { &vop_lease_desc, spec_lease_check }, /* lease */
163: { &vop_ioctl_desc, spec_ioctl }, /* ioctl */
164: { &vop_select_desc, spec_select }, /* select */
165: { &vop_revoke_desc, spec_revoke }, /* revoke */
166: { &vop_mmap_desc, spec_mmap }, /* mmap */
167: { &vop_fsync_desc, ffs_fsync }, /* fsync */
168: { &vop_seek_desc, spec_seek }, /* seek */
169: { &vop_remove_desc, spec_remove }, /* remove */
170: { &vop_link_desc, spec_link }, /* link */
171: { &vop_rename_desc, spec_rename }, /* rename */
172: { &vop_mkdir_desc, spec_mkdir }, /* mkdir */
173: { &vop_rmdir_desc, spec_rmdir }, /* rmdir */
174: { &vop_symlink_desc, spec_symlink }, /* symlink */
175: { &vop_readdir_desc, spec_readdir }, /* readdir */
176: { &vop_readlink_desc, spec_readlink }, /* readlink */
177: { &vop_abortop_desc, spec_abortop }, /* abortop */
178: { &vop_inactive_desc, ufs_inactive }, /* inactive */
179: { &vop_reclaim_desc, ffs_reclaim }, /* reclaim */
180: { &vop_lock_desc, ufs_lock }, /* lock */
181: { &vop_unlock_desc, ufs_unlock }, /* unlock */
182: { &vop_bmap_desc, spec_bmap }, /* bmap */
183: { &vop_strategy_desc, spec_strategy }, /* strategy */
184: { &vop_print_desc, ufs_print }, /* print */
185: { &vop_islocked_desc, ufs_islocked }, /* islocked */
186: { &vop_pathconf_desc, spec_pathconf }, /* pathconf */
187: { &vop_advlock_desc, spec_advlock }, /* advlock */
188: { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */
189: { &vop_valloc_desc, spec_valloc }, /* valloc */
190: { &vop_reallocblks_desc, spec_reallocblks }, /* reallocblks */
191: { &vop_vfree_desc, ffs_vfree }, /* vfree */
192: { &vop_truncate_desc, spec_truncate }, /* truncate */
193: { &vop_update_desc, ffs_update }, /* update */
194: { &vop_bwrite_desc, vn_bwrite },
195: #ifdef NeXT
196: { &vop_devblocksize_desc, spec_devblocksize }, /* devblocksize */
197: #endif /* NeXT */
198: { &vop_pagein_desc, ufs_pagein }, /* Pagein */
199: { &vop_pageout_desc, ufs_pageout }, /* Pageout */
200: { (struct vnodeop_desc*)NULL, (int(*)())NULL }
201: };
202: struct vnodeopv_desc ffs_specop_opv_desc =
203: { &ffs_specop_p, ffs_specop_entries };
204:
205: #if FIFO
206: int (**ffs_fifoop_p)();
207: struct vnodeopv_entry_desc ffs_fifoop_entries[] = {
208: { &vop_default_desc, vn_default_error },
209: { &vop_lookup_desc, fifo_lookup }, /* lookup */
210: { &vop_create_desc, fifo_create }, /* create */
211: { &vop_mknod_desc, fifo_mknod }, /* mknod */
212: { &vop_open_desc, fifo_open }, /* open */
213: { &vop_close_desc, ufsfifo_close }, /* close */
214: { &vop_access_desc, ufs_access }, /* access */
215: { &vop_getattr_desc, ufs_getattr }, /* getattr */
216: { &vop_setattr_desc, ufs_setattr }, /* setattr */
217: { &vop_read_desc, ufsfifo_read }, /* read */
218: { &vop_write_desc, ufsfifo_write }, /* write */
219: { &vop_lease_desc, fifo_lease_check }, /* lease */
220: { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */
221: { &vop_select_desc, fifo_select }, /* select */
222: { &vop_revoke_desc, fifo_revoke }, /* revoke */
223: { &vop_mmap_desc, fifo_mmap }, /* mmap */
224: { &vop_fsync_desc, ffs_fsync }, /* fsync */
225: { &vop_seek_desc, fifo_seek }, /* seek */
226: { &vop_remove_desc, fifo_remove }, /* remove */
227: { &vop_link_desc, fifo_link }, /* link */
228: { &vop_rename_desc, fifo_rename }, /* rename */
229: { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */
230: { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */
231: { &vop_symlink_desc, fifo_symlink }, /* symlink */
232: { &vop_readdir_desc, fifo_readdir }, /* readdir */
233: { &vop_readlink_desc, fifo_readlink }, /* readlink */
234: { &vop_abortop_desc, fifo_abortop }, /* abortop */
235: { &vop_inactive_desc, ufs_inactive }, /* inactive */
236: { &vop_reclaim_desc, ffs_reclaim }, /* reclaim */
237: { &vop_lock_desc, ufs_lock }, /* lock */
238: { &vop_unlock_desc, ufs_unlock }, /* unlock */
239: { &vop_bmap_desc, fifo_bmap }, /* bmap */
240: { &vop_strategy_desc, fifo_strategy }, /* strategy */
241: { &vop_print_desc, ufs_print }, /* print */
242: { &vop_islocked_desc, ufs_islocked }, /* islocked */
243: { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */
244: { &vop_advlock_desc, fifo_advlock }, /* advlock */
245: { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */
246: { &vop_valloc_desc, fifo_valloc }, /* valloc */
247: { &vop_reallocblks_desc, fifo_reallocblks }, /* reallocblks */
248: { &vop_vfree_desc, ffs_vfree }, /* vfree */
249: { &vop_truncate_desc, fifo_truncate }, /* truncate */
250: { &vop_update_desc, ffs_update }, /* update */
251: { &vop_bwrite_desc, vn_bwrite },
252: { &vop_pagein_desc, ufs_pagein }, /* Pagein */
253: { &vop_pageout_desc, ufs_pageout }, /* Pageout */
254: { (struct vnodeop_desc*)NULL, (int(*)())NULL }
255: };
256: struct vnodeopv_desc ffs_fifoop_opv_desc =
257: { &ffs_fifoop_p, ffs_fifoop_entries };
258: #endif /* FIFO */
259:
260: /*
261: * Enabling cluster read/write operations.
262: */
263: int doclusterread = 1;
264: int doclusterwrite = 1;
265:
266: #include <ufs/ufs/ufs_readwrite.c>
267:
268: /*
269: * Synch an open file.
270: */
271: /* ARGSUSED */
272: int
273: ffs_fsync(ap)
274: struct vop_fsync_args /* {
275: struct vnode *a_vp;
276: struct ucred *a_cred;
277: int a_waitfor;
278: struct proc *a_p;
279: } */ *ap;
280: {
281: register struct vnode *vp = ap->a_vp;
282: register struct buf *bp;
283: struct timeval tv;
284: struct buf *nbp;
285: int s;
286:
287: /*
288: * Flush all dirty buffers associated with a vnode.
289: */
290: loop:
291: s = splbio();
292: for (bp = vp->v_dirtyblkhd.lh_first; bp; bp = nbp) {
293: nbp = bp->b_vnbufs.le_next;
294: if ((bp->b_flags & B_BUSY))
295: continue;
296: if ((bp->b_flags & B_DELWRI) == 0)
297: panic("ffs_fsync: not dirty");
298: bremfree(bp);
299: bp->b_flags |= B_BUSY;
300: splx(s);
301: /*
302: * Wait for I/O associated with indirect blocks to complete,
303: * since there is no way to quickly wait for them below.
304: */
305: if (bp->b_vp == vp || ap->a_waitfor == MNT_NOWAIT)
306: (void) bawrite(bp);
307: else
308: (void) bwrite(bp);
309: goto loop;
310: }
311: if (ap->a_waitfor == MNT_WAIT) {
312: while (vp->v_numoutput) {
313: vp->v_flag |= VBWAIT;
314: tsleep((caddr_t)&vp->v_numoutput, PRIBIO + 1, "ffs_fsync", 0);
315: }
316:
317: /* I have seen this happen for swapfile. So it is safer to
318: * check for dirty buffers again. --Umesh
319: */
320: if (vp->v_dirtyblkhd.lh_first) {
321: vprint("ffs_fsync: dirty", vp);
322: splx(s);
323: goto loop;
324: }
325: }
326: splx(s);
327: tv = time;
328: return (VOP_UPDATE(ap->a_vp, &tv, &tv, ap->a_waitfor == MNT_WAIT));
329: }
330:
331: /*
332: * Reclaim an inode so that it can be used for other purposes.
333: */
334: int
335: ffs_reclaim(ap)
336: struct vop_reclaim_args /* {
337: struct vnode *a_vp;
338: struct proc *a_p;
339: } */ *ap;
340: {
341: register struct vnode *vp = ap->a_vp;
342: int error;
343:
344: if (error = ufs_reclaim(vp, ap->a_p))
345: return (error);
346: FREE_ZONE(vp->v_data, sizeof (struct inode),
347: VFSTOUFS(vp->v_mount)->um_devvp->v_tag == VT_MFS ?
348: M_MFSNODE : M_FFSNODE);
349: vp->v_data = NULL;
350: return (0);
351: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.