1 /* $NetBSD: ffs_vnops.c,v 1.9 1996/09/07 12:41:39 mycroft Exp $ */ 2 3 /* 4 * Copyright (c) 1982, 1986, 1989, 1993 5 * The Regents of the University of California. All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed by the University of 18 * California, Berkeley and its contributors. 19 * 4. Neither the name of the University nor the names of its contributors 20 * may be used to endorse or promote products derived from this software 21 * without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 33 * SUCH DAMAGE. 34 * 35 * @(#)ffs_vnops.c 8.10 (Berkeley) 8/10/94 36 */ 37 38 #include <sys/param.h> 39 #include <sys/systm.h> 40 #include <sys/resourcevar.h> 41 #include <sys/kernel.h> 42 #include <sys/file.h> 43 #include <sys/stat.h> 44 #include <sys/buf.h> 45 #include <sys/proc.h> 46 #include <sys/conf.h> 47 #include <sys/mount.h> 48 #include <sys/vnode.h> 49 #include <sys/malloc.h> 50 #include <sys/signalvar.h> 51 52 #include <vm/vm.h> 53 54 #include <miscfs/fifofs/fifo.h> 55 #include <miscfs/genfs/genfs.h> 56 #include <miscfs/specfs/specdev.h> 57 58 #include <ufs/ufs/quota.h> 59 #include <ufs/ufs/inode.h> 60 #include <ufs/ufs/dir.h> 61 #include <ufs/ufs/ufs_extern.h> 62 #include <ufs/ufs/ufsmount.h> 63 64 #include <ufs/ffs/fs.h> 65 #include <ufs/ffs/ffs_extern.h> 66 67 /* Global vfs data structures for ufs. */ 68 int (**ffs_vnodeop_p) __P((void *)); 69 struct vnodeopv_entry_desc ffs_vnodeop_entries[] = { 70 { &vop_default_desc, vn_default_error }, 71 { &vop_lookup_desc, ufs_lookup }, /* lookup */ 72 { &vop_create_desc, ufs_create }, /* create */ 73 { &vop_whiteout_desc, ufs_whiteout }, /* whiteout */ 74 { &vop_mknod_desc, ufs_mknod }, /* mknod */ 75 { &vop_open_desc, ufs_open }, /* open */ 76 { &vop_close_desc, ufs_close }, /* close */ 77 { &vop_access_desc, ufs_access }, /* access */ 78 { &vop_getattr_desc, ufs_getattr }, /* getattr */ 79 { &vop_setattr_desc, ufs_setattr }, /* setattr */ 80 { &vop_read_desc, ffs_read }, /* read */ 81 { &vop_write_desc, ffs_write }, /* write */ 82 { &vop_lease_desc, ufs_lease_check }, /* lease */ 83 { &vop_ioctl_desc, ufs_ioctl }, /* ioctl */ 84 { &vop_poll_desc, ufs_poll }, /* poll */ 85 { &vop_mmap_desc, ufs_mmap }, /* mmap */ 86 { &vop_fsync_desc, ffs_fsync }, /* fsync */ 87 { &vop_seek_desc, ufs_seek }, /* seek */ 88 { &vop_remove_desc, ufs_remove }, /* remove */ 89 { &vop_link_desc, ufs_link }, /* link */ 90 { &vop_rename_desc, ufs_rename }, /* rename */ 91 { &vop_mkdir_desc, ufs_mkdir }, /* mkdir */ 92 { &vop_rmdir_desc, ufs_rmdir }, /* rmdir */ 93 { &vop_symlink_desc, ufs_symlink }, /* symlink */ 94 { &vop_readdir_desc, ufs_readdir }, /* readdir */ 95 { &vop_readlink_desc, ufs_readlink }, /* readlink */ 96 { &vop_abortop_desc, ufs_abortop }, /* abortop */ 97 { &vop_inactive_desc, ufs_inactive }, /* inactive */ 98 { &vop_reclaim_desc, ffs_reclaim }, /* reclaim */ 99 { &vop_lock_desc, ufs_lock }, /* lock */ 100 { &vop_unlock_desc, ufs_unlock }, /* unlock */ 101 { &vop_bmap_desc, ufs_bmap }, /* bmap */ 102 { &vop_strategy_desc, ufs_strategy }, /* strategy */ 103 { &vop_print_desc, ufs_print }, /* print */ 104 { &vop_islocked_desc, ufs_islocked }, /* islocked */ 105 { &vop_pathconf_desc, ufs_pathconf }, /* pathconf */ 106 { &vop_advlock_desc, ufs_advlock }, /* advlock */ 107 { &vop_blkatoff_desc, ffs_blkatoff }, /* blkatoff */ 108 { &vop_valloc_desc, ffs_valloc }, /* valloc */ 109 { &vop_reallocblks_desc, ffs_reallocblks }, /* reallocblks */ 110 { &vop_vfree_desc, ffs_vfree }, /* vfree */ 111 { &vop_truncate_desc, ffs_truncate }, /* truncate */ 112 { &vop_update_desc, ffs_update }, /* update */ 113 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 114 { (struct vnodeop_desc*)NULL, (int(*) __P((void*)))NULL } 115 }; 116 struct vnodeopv_desc ffs_vnodeop_opv_desc = 117 { &ffs_vnodeop_p, ffs_vnodeop_entries }; 118 119 int (**ffs_specop_p) __P((void *)); 120 struct vnodeopv_entry_desc ffs_specop_entries[] = { 121 { &vop_default_desc, vn_default_error }, 122 { &vop_lookup_desc, spec_lookup }, /* lookup */ 123 { &vop_create_desc, spec_create }, /* create */ 124 { &vop_mknod_desc, spec_mknod }, /* mknod */ 125 { &vop_open_desc, spec_open }, /* open */ 126 { &vop_close_desc, ufsspec_close }, /* close */ 127 { &vop_access_desc, ufs_access }, /* access */ 128 { &vop_getattr_desc, ufs_getattr }, /* getattr */ 129 { &vop_setattr_desc, ufs_setattr }, /* setattr */ 130 { &vop_read_desc, ufsspec_read }, /* read */ 131 { &vop_write_desc, ufsspec_write }, /* write */ 132 { &vop_lease_desc, spec_lease_check }, /* lease */ 133 { &vop_ioctl_desc, spec_ioctl }, /* ioctl */ 134 { &vop_poll_desc, spec_poll }, /* poll */ 135 { &vop_mmap_desc, spec_mmap }, /* mmap */ 136 { &vop_fsync_desc, ffs_fsync }, /* fsync */ 137 { &vop_seek_desc, spec_seek }, /* seek */ 138 { &vop_remove_desc, spec_remove }, /* remove */ 139 { &vop_link_desc, spec_link }, /* link */ 140 { &vop_rename_desc, spec_rename }, /* rename */ 141 { &vop_mkdir_desc, spec_mkdir }, /* mkdir */ 142 { &vop_rmdir_desc, spec_rmdir }, /* rmdir */ 143 { &vop_symlink_desc, spec_symlink }, /* symlink */ 144 { &vop_readdir_desc, spec_readdir }, /* readdir */ 145 { &vop_readlink_desc, spec_readlink }, /* readlink */ 146 { &vop_abortop_desc, spec_abortop }, /* abortop */ 147 { &vop_inactive_desc, ufs_inactive }, /* inactive */ 148 { &vop_reclaim_desc, ffs_reclaim }, /* reclaim */ 149 { &vop_lock_desc, ufs_lock }, /* lock */ 150 { &vop_unlock_desc, ufs_unlock }, /* unlock */ 151 { &vop_bmap_desc, spec_bmap }, /* bmap */ 152 { &vop_strategy_desc, spec_strategy }, /* strategy */ 153 { &vop_print_desc, ufs_print }, /* print */ 154 { &vop_islocked_desc, ufs_islocked }, /* islocked */ 155 { &vop_pathconf_desc, spec_pathconf }, /* pathconf */ 156 { &vop_advlock_desc, spec_advlock }, /* advlock */ 157 { &vop_blkatoff_desc, spec_blkatoff }, /* blkatoff */ 158 { &vop_valloc_desc, spec_valloc }, /* valloc */ 159 { &vop_reallocblks_desc, spec_reallocblks }, /* reallocblks */ 160 { &vop_vfree_desc, ffs_vfree }, /* vfree */ 161 { &vop_truncate_desc, spec_truncate }, /* truncate */ 162 { &vop_update_desc, ffs_update }, /* update */ 163 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 164 { (struct vnodeop_desc*)NULL, (int(*) __P((void *)))NULL } 165 }; 166 struct vnodeopv_desc ffs_specop_opv_desc = 167 { &ffs_specop_p, ffs_specop_entries }; 168 169 #ifdef FIFO 170 int (**ffs_fifoop_p) __P((void *)); 171 struct vnodeopv_entry_desc ffs_fifoop_entries[] = { 172 { &vop_default_desc, vn_default_error }, 173 { &vop_lookup_desc, fifo_lookup }, /* lookup */ 174 { &vop_create_desc, fifo_create }, /* create */ 175 { &vop_mknod_desc, fifo_mknod }, /* mknod */ 176 { &vop_open_desc, fifo_open }, /* open */ 177 { &vop_close_desc, ufsfifo_close }, /* close */ 178 { &vop_access_desc, ufs_access }, /* access */ 179 { &vop_getattr_desc, ufs_getattr }, /* getattr */ 180 { &vop_setattr_desc, ufs_setattr }, /* setattr */ 181 { &vop_read_desc, ufsfifo_read }, /* read */ 182 { &vop_write_desc, ufsfifo_write }, /* write */ 183 { &vop_lease_desc, fifo_lease_check }, /* lease */ 184 { &vop_ioctl_desc, fifo_ioctl }, /* ioctl */ 185 { &vop_poll_desc, fifo_poll }, /* poll */ 186 { &vop_mmap_desc, fifo_mmap }, /* mmap */ 187 { &vop_fsync_desc, ffs_fsync }, /* fsync */ 188 { &vop_seek_desc, fifo_seek }, /* seek */ 189 { &vop_remove_desc, fifo_remove }, /* remove */ 190 { &vop_link_desc, fifo_link }, /* link */ 191 { &vop_rename_desc, fifo_rename }, /* rename */ 192 { &vop_mkdir_desc, fifo_mkdir }, /* mkdir */ 193 { &vop_rmdir_desc, fifo_rmdir }, /* rmdir */ 194 { &vop_symlink_desc, fifo_symlink }, /* symlink */ 195 { &vop_readdir_desc, fifo_readdir }, /* readdir */ 196 { &vop_readlink_desc, fifo_readlink }, /* readlink */ 197 { &vop_abortop_desc, fifo_abortop }, /* abortop */ 198 { &vop_inactive_desc, ufs_inactive }, /* inactive */ 199 { &vop_reclaim_desc, ffs_reclaim }, /* reclaim */ 200 { &vop_lock_desc, ufs_lock }, /* lock */ 201 { &vop_unlock_desc, ufs_unlock }, /* unlock */ 202 { &vop_bmap_desc, fifo_bmap }, /* bmap */ 203 { &vop_strategy_desc, fifo_strategy }, /* strategy */ 204 { &vop_print_desc, ufs_print }, /* print */ 205 { &vop_islocked_desc, ufs_islocked }, /* islocked */ 206 { &vop_pathconf_desc, fifo_pathconf }, /* pathconf */ 207 { &vop_advlock_desc, fifo_advlock }, /* advlock */ 208 { &vop_blkatoff_desc, fifo_blkatoff }, /* blkatoff */ 209 { &vop_valloc_desc, fifo_valloc }, /* valloc */ 210 { &vop_reallocblks_desc, fifo_reallocblks }, /* reallocblks */ 211 { &vop_vfree_desc, ffs_vfree }, /* vfree */ 212 { &vop_truncate_desc, fifo_truncate }, /* truncate */ 213 { &vop_update_desc, ffs_update }, /* update */ 214 { &vop_bwrite_desc, vn_bwrite }, /* bwrite */ 215 { (struct vnodeop_desc*)NULL, (int(*) __P((void *)))NULL } 216 }; 217 struct vnodeopv_desc ffs_fifoop_opv_desc = 218 { &ffs_fifoop_p, ffs_fifoop_entries }; 219 #endif /* FIFO */ 220 221 #ifdef DEBUG 222 /* 223 * Enabling cluster read/write operations. 224 */ 225 #include <sys/sysctl.h> 226 int doclusterread = 1; 227 struct ctldebug debug11 = { "doclusterread", &doclusterread }; 228 int doclusterwrite = 1; 229 struct ctldebug debug12 = { "doclusterwrite", &doclusterwrite }; 230 #else 231 /* XXX for ufs_readwrite */ 232 #define doclusterread 1 233 #define doclusterwrite 1 234 #endif 235 236 #include <ufs/ufs/ufs_readwrite.c> 237 238 /* 239 * Reclaim an inode so that it can be used for other purposes. 240 */ 241 int 242 ffs_reclaim(v) 243 void *v; 244 { 245 struct vop_reclaim_args /* { 246 struct vnode *a_vp; 247 } */ *ap = v; 248 register struct vnode *vp = ap->a_vp; 249 int error; 250 251 if ((error = ufs_reclaim(vp)) != 0) 252 return (error); 253 FREE(vp->v_data, VFSTOUFS(vp->v_mount)->um_devvp->v_tag == VT_MFS ? 254 M_MFSNODE : M_FFSNODE); 255 vp->v_data = NULL; 256 return (0); 257 } 258