1/* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * (c) UNIX System Laboratories, Inc. 5 * All or some portions of this file are derived from material licensed 6 * to the University of California by American Telephone and Telegraph 7 * Co. or Unix System Laboratories, Inc. and are reproduced herein with 8 * the permission of UNIX System Laboratories, Inc. --- 22 unchanged lines hidden (view full) --- 31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 36 * SUCH DAMAGE. 37 * 38 * @(#)vfs_subr.c 8.31 (Berkeley) 5/26/95 |
39 * $Id: vfs_subr.c,v 1.193 1999/05/08 07:02:38 phk Exp $ |
40 */ 41 42/* 43 * External virtual filesystem routines 44 */ 45#include "opt_ddb.h" 46 47#include <sys/param.h> --- 1135 unchanged lines hidden (view full) --- 1183 } 1184 error = getnewvnode(VT_NON, (struct mount *)0, spec_vnodeop_p, &nvp); 1185 if (error) { 1186 *vpp = NULLVP; 1187 return (error); 1188 } 1189 vp = nvp; 1190 vp->v_type = VBLK; |
1191 if ((nvp = checkalias(vp, dev2udev(dev), (struct mount *)0)) != NULL) { |
1192 vput(vp); 1193 vp = nvp; 1194 } 1195 *vpp = vp; 1196 return (0); 1197} 1198 1199/* 1200 * Check to see if the new vnode represents a special device 1201 * for which we already have a vnode (either because of 1202 * bdevvp() or because of a different vnode representing 1203 * the same block device). If such an alias exists, deallocate 1204 * the existing contents and return the aliased vnode. The 1205 * caller is responsible for filling it with its new contents. 1206 */ 1207struct vnode * 1208checkalias(nvp, nvp_rdev, mp) 1209 register struct vnode *nvp; |
1210 udev_t nvp_rdev; |
1211 struct mount *mp; 1212{ 1213 struct proc *p = curproc; /* XXX */ 1214 struct vnode *vp; 1215 struct vnode **vpp; |
1216 int rmaj = umajor(nvp_rdev); 1217 dev_t dev; |
1218 1219 if (nvp->v_type != VBLK && nvp->v_type != VCHR) 1220 return (NULLVP); 1221 |
1222 dev = udev2dev(nvp_rdev, 2); 1223 |
1224 vpp = &speclisth[SPECHASH(nvp_rdev)]; 1225loop: 1226 simple_lock(&spechash_slock); 1227 for (vp = *vpp; vp; vp = vp->v_specnext) { |
1228 if (dev != vp->v_rdev || nvp->v_type != vp->v_type) |
1229 continue; 1230 /* 1231 * Alias, but not in use, so flush it out. 1232 * Only alias active device nodes. 1233 * Not sure why we don't re-use this like we do below. 1234 */ 1235 simple_lock(&vp->v_interlock); 1236 if (vp->v_usecount == 0) { --- 23 unchanged lines hidden (view full) --- 1260 /* 1261 * Put the new vnode into the hash chain. 1262 * and if there was an alias, connect them. 1263 */ 1264 MALLOC(sinfo, struct specinfo *, 1265 sizeof(struct specinfo), M_VNODE, M_WAITOK); 1266 bzero(sinfo, sizeof(struct specinfo)); 1267 nvp->v_specinfo = sinfo; |
1268 sinfo->si_rdev = dev; |
1269 sinfo->si_hashchain = vpp; 1270 sinfo->si_specnext = *vpp; 1271 sinfo->si_bsize_phys = DEV_BSIZE; 1272 sinfo->si_bsize_best = BLKDEV_IOSIZE; 1273 sinfo->si_bsize_max = MAXBSIZE; 1274 1275 /* 1276 * Ask the device to fix up specinfo. Typically the 1277 * si_bsize_* parameters may need fixing up. 1278 */ 1279 1280 if (nvp->v_type == VBLK && rmaj < nblkdev) { |
1281 if (bdevsw(dev) && bdevsw(dev)->d_parms) |
1282 |
1283 (*bdevsw(dev)->d_parms)(dev, sinfo, DPARM_GET); |
1284 } else if (nvp->v_type == VCHR && rmaj < nchrdev) { |
1285 if (devsw(dev) && devsw(dev)->d_parms) 1286 (*devsw(dev)->d_parms)(dev, sinfo, DPARM_GET); |
1287 } 1288 1289 simple_unlock(&spechash_slock); 1290 *vpp = nvp; 1291 if (vp != NULLVP) { 1292 nvp->v_flag |= VALIASED; 1293 vp->v_flag |= VALIASED; 1294 vput(vp); --- 1629 unchanged lines hidden --- |