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