Annotation of sys/ufs/ext2fs/ext2fs_subr.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ext2fs_subr.c,v 1.17 2007/06/17 20:15:25 jasper Exp $ */
! 2: /* $NetBSD: ext2fs_subr.c,v 1.1 1997/06/11 09:34:03 bouyer Exp $ */
! 3:
! 4: /*
! 5: * Copyright (c) 1997 Manuel Bouyer.
! 6: * Copyright (c) 1982, 1986, 1989, 1993
! 7: * The Regents of the University of California. All rights reserved.
! 8: *
! 9: * Redistribution and use in source and binary forms, with or without
! 10: * modification, are permitted provided that the following conditions
! 11: * are met:
! 12: * 1. Redistributions of source code must retain the above copyright
! 13: * notice, this list of conditions and the following disclaimer.
! 14: * 2. Redistributions in binary form must reproduce the above copyright
! 15: * notice, this list of conditions and the following disclaimer in the
! 16: * documentation and/or other materials provided with the distribution.
! 17: * 3. Neither the name of the University nor the names of its contributors
! 18: * may be used to endorse or promote products derived from this software
! 19: * without specific prior written permission.
! 20: *
! 21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
! 22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! 23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
! 24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
! 25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
! 26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
! 27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
! 28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
! 29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
! 30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
! 31: * SUCH DAMAGE.
! 32: *
! 33: * @(#)ffs_subr.c 8.2 (Berkeley) 9/21/93
! 34: * Modified for ext2fs by Manuel Bouyer.
! 35: */
! 36:
! 37: #include <sys/param.h>
! 38: #include <sys/systm.h>
! 39: #include <sys/vnode.h>
! 40: #include <sys/mount.h>
! 41: #include <sys/buf.h>
! 42:
! 43: #include <ufs/ufs/quota.h>
! 44: #include <ufs/ufs/inode.h>
! 45: #include <ufs/ufs/ufsmount.h>
! 46:
! 47: #include <ufs/ext2fs/ext2fs.h>
! 48: #include <ufs/ext2fs/ext2fs_extern.h>
! 49:
! 50: #include <miscfs/specfs/specdev.h>
! 51: #include <miscfs/fifofs/fifo.h>
! 52:
! 53: union _qcvt {
! 54: int64_t qcvt;
! 55: int32_t val[2];
! 56: };
! 57:
! 58: #define SETHIGH(q, h) { \
! 59: union _qcvt tmp; \
! 60: tmp.qcvt = (q); \
! 61: tmp.val[_QUAD_HIGHWORD] = (h); \
! 62: (q) = tmp.qcvt; \
! 63: }
! 64:
! 65: #define SETLOW(q, l) { \
! 66: union _qcvt tmp; \
! 67: tmp.qcvt = (q); \
! 68: tmp.val[_QUAD_LOWWORD] = (l); \
! 69: (q) = tmp.qcvt; \
! 70: }
! 71:
! 72: #ifdef _KERNEL
! 73:
! 74: /*
! 75: * Return buffer with the contents of block "offset" from the beginning of
! 76: * directory "ip". If "res" is non-zero, fill it in with a pointer to the
! 77: * remaining space in the directory.
! 78: */
! 79: int
! 80: ext2fs_bufatoff(struct inode *ip, off_t offset, char **res, struct buf **bpp)
! 81: {
! 82: struct vnode *vp;
! 83: struct m_ext2fs *fs;
! 84: struct buf *bp;
! 85: int32_t lbn;
! 86: int error;
! 87:
! 88: vp = ITOV(ip);
! 89: fs = ip->i_e2fs;
! 90: lbn = lblkno(fs, offset);
! 91:
! 92: *bpp = NULL;
! 93: if ((error = bread(vp, lbn, fs->e2fs_bsize, NOCRED, &bp)) != 0) {
! 94: brelse(bp);
! 95: return (error);
! 96: }
! 97: if (res)
! 98: *res = (char *)bp->b_data + blkoff(fs, offset);
! 99: *bpp = bp;
! 100: return (0);
! 101: }
! 102: #endif
! 103:
! 104: #if defined(_KERNEL) && defined(DIAGNOSTIC)
! 105: void
! 106: ext2fs_checkoverlap(struct buf *bp, struct inode *ip)
! 107: {
! 108: struct buf *ep;
! 109: int32_t start, last;
! 110: struct vnode *vp;
! 111:
! 112: start = bp->b_blkno;
! 113: last = start + btodb(bp->b_bcount) - 1;
! 114: LIST_FOREACH(ep, &bufhead, b_list) {
! 115: if (ep == bp || (ep->b_flags & B_INVAL) ||
! 116: ep->b_vp == NULLVP)
! 117: continue;
! 118: if (VOP_BMAP(ep->b_vp, (daddr_t)0, &vp, (daddr_t)0, NULL))
! 119: continue;
! 120: if (vp != ip->i_devvp)
! 121: continue;
! 122: /* look for overlap */
! 123: if (ep->b_bcount == 0 || ep->b_blkno > last ||
! 124: ep->b_blkno + btodb(ep->b_bcount) <= start)
! 125: continue;
! 126: vprint("Disk overlap", vp);
! 127: printf("\tstart %d, end %d overlap start %d, end %ld\n",
! 128: start, last, ep->b_blkno,
! 129: ep->b_blkno + btodb(ep->b_bcount) - 1);
! 130: panic("Disk buffer overlap");
! 131: }
! 132: }
! 133: #endif /* DIAGNOSTIC */
! 134:
! 135: /*
! 136: * Initialize the vnode associated with a new inode, handle aliased vnodes.
! 137: */
! 138: int
! 139: ext2fs_vinit(struct mount *mp, int (**specops)(void *),
! 140: int (**fifoops)(void *), struct vnode **vpp)
! 141: {
! 142: struct inode *ip;
! 143: struct vnode *vp, *nvp;
! 144: struct timeval tv;
! 145:
! 146: vp = *vpp;
! 147: ip = VTOI(vp);
! 148: vp->v_type = IFTOVT(ip->i_e2fs_mode);
! 149:
! 150: switch(vp->v_type) {
! 151: case VCHR:
! 152: case VBLK:
! 153: vp->v_op = specops;
! 154:
! 155: nvp = checkalias(vp, fs2h32(ip->i_e2din->e2di_rdev), mp);
! 156: if (nvp != NULL) {
! 157: /*
! 158: * Discard unneeded vnode, but save its inode. Note
! 159: * that the lock is carried over in the inode to the
! 160: * replacement vnode.
! 161: */
! 162: nvp->v_data = vp->v_data;
! 163: vp->v_data = NULL;
! 164: vp->v_op = spec_vnodeop_p;
! 165: #ifdef VFSDEBUG
! 166: vp->v_flag &= ~VLOCKSWORK;
! 167: #endif
! 168: vrele(vp);
! 169: vgone(vp);
! 170: /* Reinitialize aliased vnode. */
! 171: vp = nvp;
! 172: ip->i_vnode = vp;
! 173: }
! 174:
! 175: break;
! 176:
! 177: case VFIFO:
! 178: #ifdef FIFO
! 179: vp->v_op = fifoops;
! 180: break;
! 181: #else
! 182: return (EOPNOTSUPP);
! 183: #endif /* FIFO */
! 184:
! 185: default:
! 186:
! 187: break;
! 188: }
! 189:
! 190: if (ip->i_number == EXT2_ROOTINO)
! 191: vp->v_flag |= VROOT;
! 192:
! 193: /* Initialize modrev times */
! 194: getmicrouptime(&tv);
! 195: SETHIGH(ip->i_modrev, tv.tv_sec);
! 196: SETLOW(ip->i_modrev, tv.tv_usec * 4294);
! 197:
! 198: *vpp = vp;
! 199:
! 200: return (0);
! 201: }
CVSweb