From ec42e67e3ece7b764cc447806ce367beb91df444 Mon Sep 17 00:00:00 2001 From: Theo de Raadt Date: Fri, 1 Jun 2007 05:37:15 +0000 Subject: remove crufty adosfs. everytime we try to change a vfs layer interface, adosfs has the issue and in an entirely different way. noone uses this code so this is hte best way to handle the problem diff from pedro who went to sleep but we need to move ahead; ok thib --- sys/adosfs/adlookup.c | 277 ------------- sys/adosfs/adosfs.h | 152 ------- sys/adosfs/adutil.c | 249 ------------ sys/adosfs/advfsops.c | 758 ---------------------------------- sys/adosfs/advnops.c | 1077 ------------------------------------------------- 5 files changed, 2513 deletions(-) (limited to 'sys/adosfs') diff --git a/sys/adosfs/adlookup.c b/sys/adosfs/adlookup.c index 7ffc7f392f6..e69de29bb2d 100644 --- a/sys/adosfs/adlookup.c +++ b/sys/adosfs/adlookup.c @@ -1,277 +0,0 @@ -/* $OpenBSD: adlookup.c,v 1.14 2003/04/01 12:18:43 art Exp $ */ -/* $NetBSD: adlookup.c,v 1.17 1996/10/25 23:13:58 cgd Exp $ */ - -/* - * Copyright (c) 1994 Christian E. Hopps - * Copyright (c) 1996 Matthias Scheler - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christian E. Hopps. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef ADOSFS_EXACTMATCH -#define strmatch(s1, l1, s2, l2, i) \ - ((l1) == (l2) && bcmp((s1), (s2), (l1)) == 0) -#else -#define strmatch(s1, l1, s2, l2, i) \ - ((l1) == (l2) && adoscaseequ((s1), (s2), (l1), (i))) -#endif - -/* - * adosfs lookup. enters with: - * pvp (parent vnode) referenced and locked. - * exit with: - * target vp referenced and locked. - * unlock pvp unless LOCKPARENT and at end of search. - * special cases: - * pvp == vp, just ref pvp, pvp already holds a ref and lock from - * caller, this will not occur with RENAME or CREATE. - * LOOKUP always unlocks parent if last element. (not now!?!?) - */ -int -adosfs_lookup(v) - void *v; -{ - struct vop_lookup_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - } */ *sp = v; - int nameiop, last, lockp, wantp, flags, error, nocache, i; - struct componentname *cnp; - struct vnode **vpp; /* place to store result */ - struct anode *ap; /* anode to find */ - struct vnode *vdp; /* vnode of search dir */ - struct anode *adp; /* anode of search dir */ - struct ucred *ucp; /* lookup credentials */ - struct proc *p; - u_int32_t plen, hval; - daddr_t bn; - char *pelt; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); -#endif - cnp = sp->a_cnp; - vdp = sp->a_dvp; - adp = VTOA(vdp); - vpp = sp->a_vpp; - *vpp = NULL; - ucp = cnp->cn_cred; - nameiop = cnp->cn_nameiop; - cnp->cn_flags &= ~PDIRUNLOCK; - flags = cnp->cn_flags; - last = flags & ISLASTCN; - lockp = flags & LOCKPARENT; - wantp = flags & (LOCKPARENT | WANTPARENT); - pelt = cnp->cn_nameptr; - plen = cnp->cn_namelen; - p = cnp->cn_proc; - nocache = 0; - - /* - * check that: - * pvp is a dir, and that the user has rights to access - */ - if (vdp->v_type != VDIR) - return (ENOTDIR); - if ((error = VOP_ACCESS(vdp, VEXEC, ucp, cnp->cn_proc)) != 0) - return (error); - if ((flags & ISLASTCN) && (vdp->v_mount->mnt_flag & MNT_RDONLY) && - (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)) - return (EROFS); - - /* - * Before tediously performing a linear scan of the directory, - * check the name cache to see if the directory/name pair - * we are looking for is known already. - */ - if ((error = cache_lookup(vdp, vpp, cnp)) >= 0) - return (error); - - /* - * fake a '.' - */ - if (plen == 1 && pelt[0] == '.') { - /* see special cases in prologue. */ - *vpp = vdp; - goto found; - } - /* - * fake a ".." - */ - if (flags & ISDOTDOT) { - if (vdp->v_type == VDIR && (vdp->v_flag & VROOT)) - panic("adosfs .. attempted lookup through root"); - /* - * cannot get `..' while `vdp' is locked - * e.g. procA holds lock on `..' and waits for `vdp' - * we wait for `..' and hold lock on `vdp'. deadlock. - * because `vdp' may have been achieved through symlink - * fancy detection code that decreases the race - * window size is not reasonably possible. - * - * basically unlock the parent, try and lock the child (..) - * if that fails relock the parent (ignoring error) and - * fail. Otherwise we have the child (..) if this is the - * last and the caller requested LOCKPARENT, attempt to - * relock the parent. If that fails unlock the child (..) - * and fail. Otherwise we have succeeded. - * - */ - VOP_UNLOCK(vdp, 0, p); /* race */ - cnp->cn_flags |= PDIRUNLOCK; - if ((error = VFS_VGET(vdp->v_mount, ABLKTOINO(adp->pblock), - vpp)) != 0) { - if (vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p) == 0) - cnp->cn_flags &= ~PDIRUNLOCK; - } else if (last && lockp) { - if ((error = vn_lock(vdp, LK_EXCLUSIVE | LK_RETRY, p))) - vput(*vpp); - else - cnp->cn_flags &= ~PDIRUNLOCK; - } - if (error) { - *vpp = NULL; - return (error); - } - goto found_lockdone; - } - - /* - * hash the name and grab the first block in chain - * then walk the chain. if chain has not been fully - * walked before, track the count in `tabi' - */ - hval = adoshash(pelt, plen, adp->ntabent, IS_INTER(adp->amp)); - bn = adp->tab[hval]; - i = min(adp->tabi[hval], 0); - while (bn != 0) { - if ((error = VFS_VGET(vdp->v_mount, ABLKTOINO(bn), vpp)) != - 0) { -#ifdef ADOSFS_DIAGNOSTIC - printf("[aget] %d)", error); -#endif - /* XXX check to unlock parent possibly? */ - return(error); - } - ap = VTOA(*vpp); - if (i <= 0) { - if (--i < adp->tabi[hval]) - adp->tabi[hval] = i; - /* - * last header in chain lock count down by - * negating it to positive - */ - if (ap->hashf == 0) { -#ifdef DEBUG - if (i != adp->tabi[hval]) - panic("adlookup: wrong chain count"); -#endif - adp->tabi[hval] = -adp->tabi[hval]; - } - } - if (strmatch(pelt, plen, ap->name, strlen(ap->name), - IS_INTER(adp->amp))) - goto found; - bn = ap->hashf; - vput(*vpp); - } - *vpp = NULL; - /* - * not found - */ - if ((nameiop == CREATE || nameiop == RENAME) && last) { - if ((error = VOP_ACCESS(vdp, VWRITE, ucp, cnp->cn_proc)) != 0) - { -#ifdef ADOSFS_DIAGNOSTIC - printf("[VOP_ACCESS] %d)", error); -#endif - return (error); - } - if (lockp == 0) { - VOP_UNLOCK(vdp, 0, p); - cnp->cn_flags |= PDIRUNLOCK; - } - cnp->cn_nameiop |= SAVENAME; -#ifdef ADOSFS_DIAGNOSTIC - printf("EJUSTRETURN)"); -#endif - return(EJUSTRETURN); - } - if ((cnp->cn_flags & MAKEENTRY) && nameiop != CREATE) - cache_enter(vdp, NULL, cnp); -#ifdef ADOSFS_DIAGNOSTIC - printf("ENOENT)"); -#endif - return(ENOENT); - -found: - if (nameiop == DELETE && last) { - if ((error = VOP_ACCESS(vdp, VWRITE, ucp, cnp->cn_proc)) != 0) - { - if (vdp != *vpp) - vput(*vpp); - *vpp = NULL; - return (error); - } - nocache = 1; - } - if (nameiop == RENAME && wantp && last) { - if (vdp == *vpp) - return(EISDIR); - if ((error = VOP_ACCESS(vdp, VWRITE, ucp, cnp->cn_proc)) != 0) - { - vput(*vpp); - *vpp = NULL; - return (error); - } - cnp->cn_flags |= SAVENAME; - nocache = 1; - } - if (vdp == *vpp) - VREF(vdp); - else if (lockp == 0 || last == 0) { - VOP_UNLOCK(vdp, 0, p); - cnp->cn_flags |= PDIRUNLOCK; - } -found_lockdone: - if ((cnp->cn_flags & MAKEENTRY) && nocache == 0) - cache_enter(vdp, *vpp, cnp); - -#ifdef ADOSFS_DIAGNOSTIC - printf("0)\n"); -#endif - return(0); -} diff --git a/sys/adosfs/adosfs.h b/sys/adosfs/adosfs.h index 843c39e6b02..e69de29bb2d 100644 --- a/sys/adosfs/adosfs.h +++ b/sys/adosfs/adosfs.h @@ -1,152 +0,0 @@ -/* $OpenBSD: adosfs.h,v 1.12 2003/11/13 17:23:57 drahn Exp $ */ -/* $NetBSD: adosfs.h,v 1.12 1996/10/08 22:18:02 thorpej Exp $ */ - -/* - * Copyright (c) 1994 Christian E. Hopps - * Copyright (c) 1996 Matthias Scheler - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christian E. Hopps. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * Amigados datestamp. (from 1/1/1978 00:00:00 local) - */ -struct datestamp { - u_int32_t days; - u_int32_t mins; - u_int32_t ticks; /* 20000 * (ticks % 50) = useconds */ - /* ticks / 50 = seconds */ -}; - -enum anode_type { AROOT, ADIR, AFILE, ALDIR, ALFILE, ASLINK }; - -/* - * similar to inode's, we use to represent: - * the root dir, reg dirs, reg files and extension blocks - * note the ``tab'' is a hash table for r/d, and a data block - * table for f/e. it is always ANODETABSZ(ap) bytes in size. - */ -struct anode { - LIST_ENTRY(anode) link; - enum anode_type type; - char name[31]; /* (r/d/f) name for object */ - struct datestamp mtimev; /* (r) volume modified */ - struct datestamp created; /* (r) volume created */ - struct datestamp mtime; /* (r/d/f) last modified */ - struct adosfsmount *amp; /* owner file system */ - struct vnode *vp; /* owner vnode */ - struct lockf *a_lockf; /* byte level lock list */ - struct lock a_lock; /* anode lock */ - u_int32_t fsize; /* (f) size of file in bytes */ - daddr_t block; /* block num */ - daddr_t pblock; /* (d/f/e) parent block */ - daddr_t hashf; /* (d/f) hash forward */ - daddr_t extb; /* (f/e) extension block number */ - daddr_t linkto; /* (hd/hf) hdr this link points at */ - daddr_t linknext; /* (d/f/hd/hf) next chain link/head */ - daddr_t lastlindblk; /* (f/hf) last logical indirect blk */ - daddr_t lastindblk; /* (f/hf) last indirect block read */ - daddr_t *tab; /* (r/d) hash table */ - int *tabi; /* (r/d) table info */ - int ntabent; /* (r/d) number of entries in table */ - int nwords; /* size of blocks in 32-bit words */ - int adprot; /* (d/f) amigados protection bits */ - uid_t uid; /* (d/f) uid of directory/file */ - gid_t gid; /* (d/f) gid of directory/file */ - char *slinkto; /* name of file or dir */ -}; -#define VTOA(vp) ((struct anode *)(vp)->v_data) -#define ATOV(ap) ((ap)->vp) -#define ANODETABENT(ap) ((ap)->nwords - 56) -#define ANODENDATBLKENT(ap) ((ap)->nwords - 56) -#define ABLKTOINO(bn) ((ino_t)(bn)) -#define AINOTOBLK(bn) ((daddr_t)(bn)) -/* - * mount data - */ -#define ANODEHASHSZ (512) - -struct adosfsmount { - LIST_HEAD(anodechain, anode) anodetab[ANODEHASHSZ]; - struct mount *mp; /* owner mount */ - u_int32_t dostype; /* type of volume */ - daddr_t rootb; /* root block number */ - int secsperblk; /* sectors per block */ - int bsize; /* size of blocks */ - int nwords; /* size of blocks in long words */ - int dbsize; /* data bytes per block */ - uid_t uid; /* uid of mounting user */ - gid_t gid; /* gid of mounting user */ - mode_t mask; /* mode mask */ - struct vnode *devvp; /* blk device mounted on */ - struct vnode *rootvp; /* out root vnode */ - struct netexport export; - u_int32_t *bitmap; /* allocation bitmap */ - u_int32_t numblks; /* number of usable blocks */ - u_int32_t freeblks; /* number of free blocks */ -}; -#define VFSTOADOSFS(mp) ((struct adosfsmount *)(mp)->mnt_data) - -#define IS_FFS(amp) ((amp)->dostype & 1) -#define IS_INTER(amp) (((amp)->dostype & 7) > 1) - -/* - * AmigaDOS block stuff. - */ -#define BBOFF (0) - -#define BPT_SHORT ((u_int32_t)2) -#define BPT_DATA ((u_int32_t)8) -#define BPT_LIST ((u_int32_t)16) - -#define BST_RDIR ((u_int32_t)1) -#define BST_UDIR ((u_int32_t)2) -#define BST_SLINK ((u_int32_t)3) -#define BST_LDIR ((u_int32_t)4) -#define BST_FILE ((u_int32_t)-3) -#define BST_LFILE ((u_int32_t)-4) - -#define OFS_DATA_OFFSET (24) - -/* - * utility protos - */ -#define adoswordn(bp,wn) betoh32(*((u_int32_t *)(bp)->b_data + (wn))) - -u_int32_t adoscksum(struct buf *, int); -int adoscaseequ(const char *, const char *, int, int); -int adoshash(const char *, int, int, int); -int adunixprot(int); -int adosfs_getblktype(struct adosfsmount *, struct buf *); - -struct vnode *adosfs_ahashget(struct mount *, ino_t); -int adosfs_ainshash(struct adosfsmount *, struct anode *); -void adosfs_aremhash(struct anode *); - -int adosfs_lookup(void *); - -extern int (**adosfs_vnodeop_p)(void *); diff --git a/sys/adosfs/adutil.c b/sys/adosfs/adutil.c index b9f0cb48a0a..e69de29bb2d 100644 --- a/sys/adosfs/adutil.c +++ b/sys/adosfs/adutil.c @@ -1,249 +0,0 @@ -/* $OpenBSD: adutil.c,v 1.17 2007/05/28 22:17:21 pyr Exp $ */ -/* $NetBSD: adutil.c,v 1.15 1996/10/13 02:52:07 christos Exp $ */ - -/* - * Copyright (c) 1994 Christian E. Hopps - * Copyright (c) 1996 Matthias Scheler - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christian E. Hopps. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -/* - * look for anode in the mount's hash table, return locked. - */ -#define AHASH(an) ((an) & (ANODEHASHSZ - 1)) - -static __inline char CapitalChar(char, int); - -struct vnode * -adosfs_ahashget(mp, an) - struct mount *mp; - ino_t an; -{ - struct anodechain *hp; - struct anode *ap; - struct proc *p = curproc; /* XXX */ - struct vnode *vp; - - hp = &VFSTOADOSFS(mp)->anodetab[AHASH(an)]; - - for (;;) { - LIST_FOREACH(ap, hp, link) { - if (ABLKTOINO(ap->block) == an) { - vp = ATOV(ap); - if (!vget(vp, LK_EXCLUSIVE, p)) - return (vp); - break; - } - } - if (ap == NULL) - return (NULL); - } - /* NOTREACHED */ -} - -/* - * insert in hash table and lock - */ -int -adosfs_ainshash(amp, ap) - struct adosfsmount *amp; - struct anode *ap; -{ - struct anodechain *hp; - struct anode *aq; - - /* lock the inode, then put it on the appropriate hash list */ - lockmgr(&ap->a_lock, LK_EXCLUSIVE, NULL); - - hp = &->anodetab[AHASH(ap->block)]; - - LIST_FOREACH(aq, hp, link) { - if (aq->block == ap->block) { - lockmgr(&ap->a_lock, LK_RELEASE, NULL); - return (EEXIST); - } - } - - LIST_INSERT_HEAD(hp, ap, link); - return (0); -} - -void -adosfs_aremhash(ap) - struct anode *ap; -{ - - if (ap->link.le_prev != NULL) - LIST_REMOVE(ap, link); -} - -int -adosfs_getblktype(amp, bp) - struct adosfsmount *amp; - struct buf *bp; -{ - if (adoscksum(bp, amp->nwords)) { -#ifdef DIAGNOSTIC - printf("adosfs: aget: cksum of blk %d failed\n", - bp->b_blkno / amp->secsperblk); -#endif - return (-1); - } - - /* - * check primary block type - */ - if (adoswordn(bp, 0) != BPT_SHORT) { -#ifdef DIAGNOSTIC - printf("adosfs: aget: bad primary type blk %d\n", - bp->b_blkno / amp->secsperblk); -#endif - return (-1); - } - - switch (adoswordn(bp, amp->nwords - 1)) { - case BST_RDIR: /* root block */ - return (AROOT); - case BST_LDIR: /* hard link to dir */ - return (ALDIR); - case BST_UDIR: /* user dir */ - return (ADIR); - case BST_LFILE: /* hard link to file */ - return (ALFILE); - case BST_FILE: /* file header */ - return (AFILE); - case BST_SLINK: /* soft link */ - return (ASLINK); - } - return (-1); -} - -int -adunixprot(adprot) - int adprot; -{ - if (adprot & 0xc000ee00) { - adprot = (adprot & 0xee0e) >> 1; - return (((adprot & 0x7) << 6) | - ((adprot & 0x700) >> 5) | - ((adprot & 0x7000) >> 12)); - } - else { - adprot = (adprot >> 1) & 0x7; - return((adprot << 6) | (adprot << 3) | adprot); - } -} - -static __inline char -CapitalChar(ch, inter) - char ch; - int inter; -{ - if ((ch >= 'a' && ch <= 'z') || - (inter && ch >= '\xe0' && ch <= '\xfe' && ch != '\xf7')) - return(ch - ('a' - 'A')); - return(ch); -} - -u_int32_t -adoscksum(bp, n) - struct buf *bp; - int n; -{ - u_int32_t sum, *lp; - - lp = (u_int32_t *)bp->b_data; - sum = 0; - - while (n--) - sum += betoh32(*lp++); - return(sum); -} - -int -adoscaseequ(name1, name2, len, inter) - const char *name1, *name2; - int len, inter; -{ - while (len-- > 0) - if (CapitalChar(*name1++, inter) != - CapitalChar(*name2++, inter)) - return 0; - - return 1; -} - -int -adoshash(nam, namlen, nelt, inter) - const char *nam; - int namlen, nelt, inter; -{ - int val; - - val = namlen; - while (namlen--) - val = ((val * 13) + (u_char)CapitalChar(*nam++, inter)) & - 0x7ff; - return(val % nelt); -} - -#ifdef notyet -/* - * datestamp is local time, tv is to be UTC - */ -int -dstotv(dsp, tvp) - struct datestamp *dsp; - struct timeval *tvp; -{ -} - -/* - * tv is UTC, datestamp is to be local time - */ -int -tvtods(tvp, dsp) - struct timeval *tvp; - struct datestamp *dsp; -{ -} -#endif diff --git a/sys/adosfs/advfsops.c b/sys/adosfs/advfsops.c index 3653ccafc8d..e69de29bb2d 100644 --- a/sys/adosfs/advfsops.c +++ b/sys/adosfs/advfsops.c @@ -1,758 +0,0 @@ -/* $OpenBSD: advfsops.c,v 1.26 2007/05/29 06:28:16 otto Exp $ */ -/* $NetBSD: advfsops.c,v 1.24 1996/12/22 10:10:12 cgd Exp $ */ - -/* - * Copyright (c) 1994 Christian E. Hopps - * Copyright (c) 1996 Matthias Scheler - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christian E. Hopps. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include /* XXX */ -#include - -int adosfs_init(struct vfsconf *); -int adosfs_mount(struct mount *, const char *, void *, struct nameidata *, - struct proc *); -int adosfs_start(struct mount *, int, struct proc *); -int adosfs_unmount(struct mount *, int, struct proc *); -int adosfs_root(struct mount *, struct vnode **); -int adosfs_quotactl(struct mount *, int, uid_t, caddr_t, struct proc *); -int adosfs_statfs(struct mount *, struct statfs *, struct proc *); -int adosfs_sync(struct mount *, int, struct ucred *, struct proc *); -int adosfs_vget(struct mount *, ino_t, struct vnode **); -int adosfs_fhtovp(struct mount *, struct fid *, struct vnode **); - -int adosfs_vptofh(struct vnode *, struct fid *); - -int adosfs_mountfs(struct vnode *, struct mount *, struct proc *); -int adosfs_loadbitmap(struct adosfsmount *); - -int -adosfs_mount(mp, path, data, ndp, p) - struct mount *mp; - const char *path; - void *data; - struct nameidata *ndp; - struct proc *p; -{ - struct vnode *devvp; - struct adosfs_args args; - struct adosfsmount *amp; - size_t size; - int error; - mode_t accessmode; - - error = copyin(data, &args, sizeof(struct adosfs_args)); - if (error) - return(error); - -#if 0 - if (mp->mnt_flag & MNT_UPDATE) - return (EOPNOTSUPP); -#endif - if ((mp->mnt_flag & MNT_RDONLY) == 0) - return (EROFS); - /* - * If updating, check whether changing from read-only to - * read/write; if there is no device name, that's all we do. - */ - if (mp->mnt_flag & MNT_UPDATE) { - amp = VFSTOADOSFS(mp); - if (args.fspec == 0) - return (vfs_export(mp, &->export, - &args.export_info)); - } - /* - * Not an update, or updating the name: look up the name - * and verify that it refers to a sensible block device. - */ - NDINIT(ndp, LOOKUP, FOLLOW, UIO_USERSPACE, args.fspec, p); - if ((error = namei(ndp)) != 0) - return (error); - devvp = ndp->ni_vp; - - if (devvp->v_type != VBLK) { - vrele(devvp); - return (ENOTBLK); - } - if (major(devvp->v_rdev) >= nblkdev) { - vrele(devvp); - return (ENXIO); - } - /* - * If mount by non-root, then verify that user has necessary - * permissions on the device. - */ - if (p->p_ucred->cr_uid != 0) { - accessmode = VREAD; - if ((mp->mnt_flag & MNT_RDONLY) == 0) - accessmode |= VWRITE; - vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, p); - error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p); - if (error) { - vput(devvp); - return (error); - } - VOP_UNLOCK(devvp, 0, p); - } -/* MNT_UPDATE? */ - if ((error = adosfs_mountfs(devvp, mp, p)) != 0) { - vrele(devvp); - return (error); - } - amp = VFSTOADOSFS(mp); - amp->uid = args.uid; - amp->gid = args.gid; - amp->mask = args.mask; - (void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size); - bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size); - (void)copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1, - &size); - bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size); - bcopy(&args, &mp->mnt_stat.mount_info.adosfs_args, sizeof(args)); - return (0); -} - -int -adosfs_mountfs(devvp, mp, p) - struct vnode *devvp; - struct mount *mp; - struct proc *p; -{ - struct disklabel dl; - struct partition *parp; - struct adosfsmount *amp; - struct buf *bp; - struct vnode *rvp; - int error, part, i; - - part = DISKPART(devvp->v_rdev); - amp = NULL; - - /* - * Disallow multiple mounts of the same device. - * Disallow mounting of a device that is currently in use - * (except for root, which might share swap device for miniroot). - * Flush out any old buffers remaining from a previous use. - */ - if ((error = vfs_mountedon(devvp)) != 0) - return (error); - if (vcount(devvp) > 1 && devvp != rootvp) - return (EBUSY); - if ((error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0)) != 0) - return (error); - - /* - * open blkdev and read root block - */ - if ((error = VOP_OPEN(devvp, FREAD, NOCRED, p)) != 0) - return (error); - error = VOP_IOCTL(devvp, DIOCGDINFO,(caddr_t)&dl, FREAD, NOCRED, p); - if (error) - goto fail; - - parp = &dl.d_partitions[part]; - amp = malloc(sizeof(struct adosfsmount), M_ADOSFSMNT, M_WAITOK); - bzero((char *)amp, sizeof(struct adosfsmount)); - amp->mp = mp; - if (dl.d_type == DTYPE_FLOPPY) { - amp->bsize = dl.d_secsize; - amp->secsperblk = 1; - } - else { - amp->bsize = DISKLABELV1_FFS_BSIZE(parp->fragblock); - amp->secsperblk = DISKLABELV1_FFS_FRAG(parp->p_fragblock); - } - amp->rootb = (parp->p_size / amp->secsperblk - 1 + parp->p_cpg) >> 1; - amp->numblks = parp->p_size / amp->secsperblk - parp->p_cpg; - - bp = NULL; - if ((error = bread(devvp, (daddr_t)BBOFF, - amp->bsize, NOCRED, &bp)) != 0) - goto fail; - - amp->dostype = adoswordn(bp, 0); - brelse(bp); - - if (amp->dostype < 0x444f5300 || amp->dostype > 0x444f5305) { - error = EINVAL; - goto fail; - } - - amp->nwords = amp->bsize >> 2; - amp->dbsize = amp->bsize - (IS_FFS(amp) ? 0 : OFS_DATA_OFFSET); - amp->devvp = devvp; - - mp->mnt_data = (qaddr_t)amp; - mp->mnt_stat.f_fsid.val[0] = (int32_t)devvp->v_rdev; - mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_ADOSFS); - mp->mnt_flag |= MNT_LOCAL; - devvp->v_specmountpoint = mp; - - /* - * init anode table. - */ - for (i = 0; i < ANODEHASHSZ; i++) - LIST_INIT(&->anodetab[i]); - - /* - * get the root anode, if not a valid fs this will fail. - */ - if ((error = VFS_ROOT(mp, &rvp)) != 0) - goto fail; - /* allocate and load bitmap, set free space */ - amp->bitmap = malloc(((amp->numblks + 31) / 32) * sizeof(*amp->bitmap), - M_ADOSFSBITMAP, M_WAITOK); - adosfs_loadbitmap(amp); - if (mp->mnt_flag & MNT_RDONLY && amp->bitmap) { - /* - * Don't need the bitmap any more if it's read-only. - */ - free(amp->bitmap, M_ADOSFSBITMAP); - amp->bitmap = NULL; - } - vput(rvp); - - return(0); - -fail: - (void) VOP_CLOSE(devvp, FREAD, NOCRED, p); - if (amp && amp->bitmap) - free(amp->bitmap, M_ADOSFSBITMAP); - if (amp) - free(amp, M_ADOSFSMNT); - return (error); -} - -int -adosfs_start(mp, flags, p) - struct mount *mp; - int flags; - struct proc *p; -{ - - return (0); -} - -int -adosfs_unmount(mp, mntflags, p) - struct mount *mp; - int mntflags; - struct proc *p; -{ - struct adosfsmount *amp; - int error, flags; - - flags = 0; - if (mntflags & MNT_FORCE) - flags |= FORCECLOSE; - if ((error = vflush(mp, NULLVP, flags)) != 0) - return (error); - amp = VFSTOADOSFS(mp); - amp->devvp->v_specmountpoint = NULL; - error = VOP_CLOSE(amp->devvp, FREAD, NOCRED, p); - vrele(amp->devvp); - if (amp->bitmap) - free(amp->bitmap, M_ADOSFSBITMAP); - free(amp, M_ADOSFSMNT); - mp->mnt_data = (qaddr_t)0; - mp->mnt_flag &= ~MNT_LOCAL; - return (error); -} - -int -adosfs_root(mp, vpp) - struct mount *mp; - struct vnode **vpp; -{ - struct vnode *nvp; - int error; - - if ((error = VFS_VGET(mp, ABLKTOINO(VFSTOADOSFS(mp)->rootb), &nvp)) != - 0) - return (error); - /* XXX verify it's a root block? */ - *vpp = nvp; - return (0); -} - -int -adosfs_statfs(mp, sbp, p) - struct mount *mp; - struct statfs *sbp; - struct proc *p; -{ - struct adosfsmount *amp; - - amp = VFSTOADOSFS(mp); - sbp->f_bsize = amp->bsize; - sbp->f_iosize = amp->dbsize; - sbp->f_blocks = amp->numblks; - sbp->f_bfree = amp->freeblks; - sbp->f_bavail = amp->freeblks; - sbp->f_files = 0; /* who knows */ - sbp->f_ffree = 0; /* " " */ - if (sbp != &mp->mnt_stat) { - bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN); - bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN); - bcopy(&mp->mnt_stat.mount_info.adosfs_args, - &sbp->mount_info.adosfs_args, sizeof(struct adosfs_args)); - } - strncpy(sbp->f_fstypename, mp->mnt_vfc->vfc_name, MFSNAMELEN); - return (0); -} - -/* - * lookup an anode, check mount's hash table if not found, create - * return locked and referenced al la vget(vp, 1); - */ -int -adosfs_vget(mp, an, vpp) - struct mount *mp; - ino_t an; - struct vnode **vpp; -{ - struct adosfsmount *amp; - struct vnode *vp; - struct anode *ap; - struct buf *bp; - char *nam, *tmp; - int namlen, error; - - error = 0; - amp = VFSTOADOSFS(mp); - bp = NULL; - - /* - * check hash table. we are done if found - */ - retry: - if ((*vpp = adosfs_ahashget(mp, an)) != NULL) - return (0); - - error = getnewvnode(VT_ADOSFS, mp, adosfs_vnodeop_p, &vp); - if (error) - return (error); - - /* - * setup, insert in hash, and lock before io. - */ - vp->v_data = ap = malloc(sizeof(struct anode), M_ANODE, M_WAITOK); - bzero(ap, sizeof(struct anode)); - lockinit(&ap->a_lock, PINOD, "anode", 0, 0); - ap->vp = vp; - ap->amp = amp; - ap->block = AINOTOBLK(an); - ap->nwords = amp->nwords; - error = adosfs_ainshash(amp, ap); - - if (error) { - vrele (vp); - - if (error == EEXIST) - goto retry; - - return (error); - } - - if ((error = bread(amp->devvp, an * amp->secsperblk, amp->bsize, - NOCRED, &bp)) != 0) { - vput(vp); - return (error); - } - - /* - * get type and fill rest in based on that. - */ - switch (ap->type = adosfs_getblktype(amp, bp)) { - case AROOT: - vp->v_type = VDIR; - vp->v_flag |= VROOT; - ap->mtimev.days = adoswordn(bp, ap->nwords - 10); - ap->mtimev.mins = adoswordn(bp, ap->nwords - 9); - ap->mtimev.ticks = adoswordn(bp, ap->nwords - 8); - ap->created.days = adoswordn(bp, ap->nwords - 7); - ap->created.mins = adoswordn(bp, ap->nwords - 6); - ap->created.ticks = adoswordn(bp, ap->nwords - 5); - break; - case ALDIR: - case ADIR: - vp->v_type = VDIR; - break; - case ALFILE: - case AFILE: - vp->v_type = VREG; - ap->fsize = adoswordn(bp, ap->nwords - 47); - break; - case ASLINK: /* XXX soft link */ - vp->v_type = VLNK; - /* - * convert from BCPL string and - * from: "part:dir/file" to: "/part/dir/file" - */ - nam = bp->b_data + (6 * sizeof(u_int32_t)); - namlen = strlen(nam); - tmp = nam; - while (*tmp && *tmp != ':') - tmp++; - if (*tmp == 0) { - ap->slinkto = malloc(namlen + 1, M_ANODE, M_WAITOK); - bcopy(nam, ap->slinkto, namlen); - } else if (*nam == ':') { - ap->slinkto = malloc(namlen + 1, M_ANODE, M_WAITOK); - bcopy(nam, ap->slinkto, namlen); - ap->slinkto[0] = '/'; - } else { - ap->slinkto = malloc(namlen + 2, M_ANODE, M_WAITOK); - ap->slinkto[0] = '/'; - bcopy(nam, &ap->slinkto[1], namlen); - ap->slinkto[tmp - nam + 1] = '/'; - namlen++; - } - ap->slinkto[namlen] = 0; - ap->fsize = namlen; - break; - default: - brelse(bp); - vput(vp); - return (EINVAL); - } - - /* - * Get appropriate data from this block; hard link needs - * to get other data from the "real" block. - */ - - /* - * copy in name (from original block) - */ - nam = bp->b_data + (ap->nwords - 20) * sizeof(u_int32_t); - namlen = *(u_char *)nam++; - if (namlen > 30) { -#ifdef DIAGNOSTIC - printf("adosfs: aget: name length too long blk %d\n", an); -#endif - brelse(bp); - vput(vp); - return (EINVAL); - } - bcopy(nam, ap->name, namlen); - ap->name[namlen] = 0; - - /* - * if dir alloc hash table and copy it in - */ - if (vp->v_type == VDIR) { - int i; - - ap->ntabent = ANODETABENT(ap); - ap->tab = malloc(ap->ntabent * (sizeof(daddr_t) + sizeof(int)), - M_ANODE, M_WAITOK); - ap->tabi = (int *)&ap->tab[ap->ntabent]; - bzero(ap->tabi, ANODETABENT(ap) * sizeof(int)); - for (i = 0; i < ap->ntabent; i++) - ap->tab[i] = (daddr_t)adoswordn(bp, i + 6); - } - - /* - * misc. - */ - ap->pblock = (daddr_t)adoswordn(bp, ap->nwords - 3); - ap->hashf = (daddr_t)adoswordn(bp, ap->nwords - 4); - ap->linknext = (daddr_t)adoswordn(bp, ap->nwords - 10); - ap->linkto = (daddr_t)adoswordn(bp, ap->nwords - 11); - - /* - * setup last indirect block cache. - */ - ap->lastlindblk = 0; - if (ap->type == AFILE) { - ap->lastindblk = ap->block; - if (adoswordn(bp, ap->nwords - 10)) - ap->linkto = ap->block; - } else if (ap->type == ALFILE) { - ap->lastindblk = ap->linkto; - brelse(bp); - bp = NULL; - error = bread(amp->devvp, ap->linkto * amp->secsperblk, - amp->bsize, NOCRED, &bp); - ap->fsize = adoswordn(bp, ap->nwords - 47); - /* - * Should ap->block be set to the real file header block? - */ - ap->block = ap->linkto; - } - - if (ap->type == AROOT) { - ap->adprot = 15; - ap->uid = amp->uid; - ap->gid = amp->gid; - } else { - ap->adprot = adoswordn(bp, ap->nwords - 48) ^ 15; - /* - * Get uid/gid from extensions in file header - * (really need to know if this is a muFS partition) - */ - ap->uid = (adoswordn(bp, ap->nwords - 49) >> 16) & 0xffff; - ap->gid = adoswordn(bp, ap->nwords - 49) & 0xffff; - if (ap->uid || ap->gid) { - if (ap->uid == 0xffff) - ap->uid = 0; - if (ap->gid == 0xffff) - ap->gid = 0; - ap->adprot |= 0x40000000; /* Kludge */ - } - else { - /* - * uid & gid extension don't exist, - * so use the mount-point uid/gid - */ - ap->uid = amp->uid; - ap->gid = amp->gid; - } - } - ap->mtime.days = adoswordn(bp, ap->nwords - 23); - ap->mtime.mins = adoswordn(bp, ap->nwords - 22); - ap->mtime.ticks = adoswordn(bp, ap->nwords - 21); - - *vpp = vp; /* return vp */ - brelse(bp); /* release buffer */ - return (0); -} - -/* - * Load the bitmap into memory, and count the number of available - * blocks. - * The bitmap will be released if the filesystem is read-only; it's - * only needed to find the free space. - */ -int -adosfs_loadbitmap(amp) - struct adosfsmount *amp; -{ - struct buf *bp, *mapbp; - u_int32_t bits; - daddr_t bn; - int blkix, endix, mapix, bmsize, n; - int error; - - bp = mapbp = NULL; - bn = amp->rootb; - if ((error = bread(amp->devvp, bn * amp->secsperblk, amp->bsize, - NOCRED, &bp)) != 0) - return (error); - blkix = amp->nwords - 49; - endix = amp->nwords - 24; - mapix = 0; - bmsize = (amp->numblks + 31) / 32; - while (mapix < bmsize) { - if (adoswordn(bp, blkix) == 0) - break; - if (mapbp != NULL) - brelse(mapbp); - if ((error = bread(amp->devvp, - adoswordn(bp, blkix) * amp->secsperblk, amp->bsize, - NOCRED, &mapbp)) != 0) - break; - if (adoscksum(mapbp, amp->nwords)) { -#ifdef DIAGNOSTIC - printf("adosfs: loadbitmap - cksum of blk %d failed\n", - adoswordn(bp, blkix)); -#endif - /* XXX Force read-only? Set free space 0? */ - break; - } - n = 1; - while (n < amp->nwords && mapix < bmsize) { - amp->bitmap[mapix++] = bits = adoswordn(mapbp, n); - ++n; - if (mapix == bmsize && amp->numblks & 31) - bits &= ~(0xffffffff << (amp->numblks & 31)); - while (bits) { - if (bits & 1) - ++amp->freeblks; - bits >>= 1; - } - } - ++blkix; - if (mapix < bmsize && blkix == endix) { - bn = (daddr_t)adoswordn(bp, blkix); - brelse(bp); - if ((error = bread(amp->devvp, bn * amp->secsperblk, - amp->bsize, NOCRED, &bp)) != 0) - break; - /* - * Why is there no checksum on these blocks? - */ - blkix = 0; - endix = amp->nwords - 1; - } - } - if (bp) - brelse(bp); - if (mapbp) - brelse(mapbp); - return (error); -} - - -/* - * File handle to vnode - * - * Have to be really careful about stale file handles: - * - check that the inode number is in range - * - call iget() to get the locked inode - * - check for an unallocated inode (i_mode == 0) - * - check that the generation number matches - */ - -/* - * This is using the same layout as struct fid from mount.h for the first two - * fields. - */ -struct ifid { - u_short ifid_len; - u_short ifid_pad; - ino_t ifid_ino; - daddr_t ifid_start; -}; - -int -adosfs_fhtovp(mp, fhp, vpp) - struct mount *mp; - struct fid *fhp; - struct vnode **vpp; -{ - struct ifid *ifhp = (struct ifid *)fhp; -#if 0 - struct anode *ap; -#endif - struct vnode *nvp; - int error; - -#ifdef ADOSFS_DIAGNOSTIC - printf("adfhtovp(%x, %x, %x)\n", mp, fhp, vpp); -#endif - - if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) { - *vpp = NULLVP; - return (error); - } -#if 0 - ap = VTOA(nvp); - if (ap->inode.iso_mode == 0) { - vput(nvp); - *vpp = NULLVP; - return (ESTALE); - } -#endif - *vpp = nvp; - return(0); -} - -int -adosfs_vptofh(vp, fhp) - struct vnode *vp; - struct fid *fhp; -{ - struct anode *ap = VTOA(vp); - struct ifid *ifhp; - - ifhp = (struct ifid *)fhp; - ifhp->ifid_len = sizeof(struct ifid); - - ifhp->ifid_ino = ABLKTOINO(ap->block); - ifhp->ifid_start = ap->block; - -#ifdef ADOSFS_DIAGNOSTIC - printf("advptofh(%x, %x)\n", vp, fhp); -#endif - return(0); -} - -int -adosfs_quotactl(mp, cmds, uid, arg, p) - struct mount *mp; - int cmds; - uid_t uid; - caddr_t arg; - struct proc *p; -{ - return(EOPNOTSUPP); -} - -int -adosfs_sync(mp, waitfor, uc, p) - struct mount *mp; - int waitfor; - struct ucred *uc; - struct proc *p; -{ -#ifdef ADOSFS_DIAGNOSTIC - printf("ad_sync(%x, %x)\n", mp, waitfor); -#endif - return(0); -} - -int -adosfs_init(struct vfsconf *vfsp) -{ - return (0); -} - -/* - * vfs generic function call table - */ -const struct vfsops adosfs_vfsops = { - adosfs_mount, - adosfs_start, - adosfs_unmount, - adosfs_root, - adosfs_quotactl, - adosfs_statfs, - adosfs_sync, - adosfs_vget, - adosfs_fhtovp, - adosfs_vptofh, - adosfs_init, -}; diff --git a/sys/adosfs/advnops.c b/sys/adosfs/advnops.c index 3156c16b9df..e69de29bb2d 100644 --- a/sys/adosfs/advnops.c +++ b/sys/adosfs/advnops.c @@ -1,1077 +0,0 @@ -/* $OpenBSD: advnops.c,v 1.35 2007/04/11 16:08:50 thib Exp $ */ -/* $NetBSD: advnops.c,v 1.32 1996/10/13 02:52:09 christos Exp $ */ - -/* - * Copyright (c) 1994 Christian E. Hopps - * Copyright (c) 1996 Matthias Scheler - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Christian E. Hopps. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include - -int adosfs_advlock(void *); -int adosfs_open(void *); -int adosfs_getattr(void *); -int adosfs_read(void *); -int adosfs_write(void *); -int adosfs_ioctl(void *); -int adosfs_poll(void *); -int adosfs_strategy(void *); -int adosfs_link(void *); -int adosfs_symlink(void *); -int adosfs_lock(void *); -int adosfs_unlock(void *); -int adosfs_bmap(void *); -int adosfs_print(void *); -int adosfs_readdir(void *); -int adosfs_access(void *); -int adosfs_readlink(void *); -int adosfs_inactive(void *); -int adosfs_islocked(void *); -int adosfs_reclaim(void *); -int adosfs_pathconf(void *); -int adnullop(void *); -int adenotsup(void *); - -#define adosfs_close adnullop -#define adosfs_fsync adnullop -#define adosfs_bwrite adenotsup -#define adosfs_create adenotsup -#define adosfs_mkdir adenotsup -#define adosfs_mknod adenotsup -#define adosfs_remove adenotsup -#define adosfs_rename adenotsup -#define adosfs_rmdir adenotsup -#define adosfs_setattr adenotsup - -struct vnodeopv_entry_desc adosfs_vnodeop_entries[] = { - { &vop_default_desc, vn_default_error }, - { &vop_lookup_desc, adosfs_lookup }, /* lookup */ - { &vop_create_desc, adosfs_create }, /* create */ - { &vop_mknod_desc, adosfs_mknod }, /* mknod */ - { &vop_open_desc, adosfs_open }, /* open */ - { &vop_close_desc, adosfs_close }, /* close */ - { &vop_access_desc, adosfs_access }, /* access */ - { &vop_getattr_desc, adosfs_getattr }, /* getattr */ - { &vop_setattr_desc, adosfs_setattr }, /* setattr */ - { &vop_read_desc, adosfs_read }, /* read */ - { &vop_write_desc, adosfs_write }, /* write */ - { &vop_ioctl_desc, adosfs_ioctl }, /* ioctl */ - { &vop_poll_desc, adosfs_poll }, /* poll */ - { &vop_fsync_desc, adosfs_fsync }, /* fsync */ - { &vop_remove_desc, adosfs_remove }, /* remove */ - { &vop_link_desc, adosfs_link }, /* link */ - { &vop_rename_desc, adosfs_rename }, /* rename */ - { &vop_mkdir_desc, adosfs_mkdir }, /* mkdir */ - { &vop_rmdir_desc, adosfs_rmdir }, /* rmdir */ - { &vop_symlink_desc, adosfs_symlink }, /* symlink */ - { &vop_readdir_desc, adosfs_readdir }, /* readdir */ - { &vop_readlink_desc, adosfs_readlink }, /* readlink */ - { &vop_abortop_desc, vop_generic_abortop }, /* abortop */ - { &vop_inactive_desc, adosfs_inactive }, /* inactive */ - { &vop_reclaim_desc, adosfs_reclaim }, /* reclaim */ - { &vop_lock_desc, adosfs_lock }, /* lock */ - { &vop_unlock_desc, adosfs_unlock }, /* unlock */ - { &vop_bmap_desc, adosfs_bmap }, /* bmap */ - { &vop_strategy_desc, adosfs_strategy }, /* strategy */ - { &vop_print_desc, adosfs_print }, /* print */ - { &vop_islocked_desc, adosfs_islocked }, /* islocked */ - { &vop_pathconf_desc, adosfs_pathconf }, /* pathconf */ - { &vop_advlock_desc, adosfs_advlock }, /* advlock */ - { &vop_bwrite_desc, adosfs_bwrite }, /* bwrite */ - { (struct vnodeop_desc*)NULL, (int(*)(void *))NULL } -}; - -int (**adosfs_vnodeop_p)(void *); - -struct vnodeopv_desc adosfs_vnodeop_opv_desc = - { &adosfs_vnodeop_p, adosfs_vnodeop_entries }; - -int -adosfs_open(v) - void *v; -{ -#ifdef ADOSFS_DIAGNOSTIC - struct vop_open_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct proc *a_p; - } */ *sp = v; - advopprint(sp); - printf(" 0)"); -#endif - return(0); -} - -int -adosfs_getattr(v) - void *v; -{ - struct vop_getattr_args /* { - struct vnode *a_vp; - struct vattr *a_vap; - struct ucred *a_cred; - struct proc *a_p; - } */ *sp = v; - struct vattr *vap; - struct adosfsmount *amp; - struct anode *ap; - u_int32_t fblks; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); -#endif - vap = sp->a_vap; - ap = VTOA(sp->a_vp); - amp = ap->amp; - vattr_null(vap); - vap->va_uid = ap->uid; - vap->va_gid = ap->gid; - vap->va_fsid = sp->a_vp->v_mount->mnt_stat.f_fsid.val[0]; - vap->va_atime.tv_sec = vap->va_mtime.tv_sec = vap->va_ctime.tv_sec = - ap->mtime.days * 24 * 60 * 60 + ap->mtime.mins * 60 + - ap->mtime.ticks / 50 + (8 * 365 + 2) * 24 * 60 * 60; - vap->va_atime.tv_nsec = vap->va_mtime.tv_nsec = vap->va_ctime.tv_nsec = 0; - vap->va_gen = 0; - vap->va_flags = 0; - vap->va_rdev = NODEV; - vap->va_fileid = (long)ap->block; - vap->va_type = sp->a_vp->v_type; - vap->va_mode = amp->mask & adunixprot(ap->adprot); - if (sp->a_vp->v_type == VDIR) { - vap->va_nlink = 1; /* XXX bogus, oh well */ - vap->va_bytes = amp->bsize; - vap->va_size = amp->bsize; - } else { - /* - * XXX actually we can track this if we were to walk the list - * of links if it exists. - * XXX for now, just set nlink to 2 if this is a hard link - * to a file, or a file with a hard link. - */ - vap->va_nlink = 1 + (ap->linkto != 0); - /* - * round up to nearest blocks add number of file list - * blocks needed and multiply by number of bytes per block. - */ - fblks = howmany(ap->fsize, amp->dbsize); - fblks += howmany(fblks, ANODENDATBLKENT(ap)); - vap->va_bytes = fblks * amp->dbsize; - vap->va_size = (off_t)ap->fsize; - - vap->va_blocksize = amp->dbsize; - } -#ifdef ADOSFS_DIAGNOSTIC - printf(" 0)"); -#endif - return(0); -} -/* - * are things locked??? they need to be to avoid this being - * deleted or changed (data block pointer blocks moving about.) - */ -int -adosfs_read(v) - void *v; -{ - struct vop_read_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *sp = v; - struct adosfsmount *amp; - struct anode *ap; - struct uio *uio; - struct buf *bp; - daddr_t lbn; - int size, error, n, on; - u_int32_t off; - int64_t diff; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); -#endif - error = 0; - uio = sp->a_uio; - ap = VTOA(sp->a_vp); - amp = ap->amp; - /* - * Return EOF for character devices, EIO for others - */ - if (sp->a_vp->v_type != VREG) { - error = EIO; - goto reterr; - } - if (uio->uio_resid == 0) - goto reterr; - if (uio->uio_offset < 0 || uio->uio_offset > UINT_MAX) { /* XXX */ - error = EINVAL; - goto reterr; - } - off = (u_int32_t)uio->uio_offset; - - /* - * to expensive to let general algorithm figure out that - * we are beyond the file. Do it now. - */ - if (off >= ap->fsize) - goto reterr; - - /* - * taken from ufs_read() - */ - do { - /* - * we are only supporting ADosFFS currently - * (which have data blocks without headers) - */ - size = amp->dbsize; - lbn = off / size; - on = off % size; - n = min((u_int32_t)(size - on), uio->uio_resid); - diff = ap->fsize - off; - /* - * check for EOF - */ - if (diff <= 0) - return(0); - if (diff < n) - n = (int)diff; - /* - * read ahead could possibly be worth something - * but not much as ados makes little attempt to - * make things contiguous - */ - error = bread(sp->a_vp, lbn * amp->secsperblk, amp->bsize, - NOCRED, &bp); - - if (!IS_FFS(amp)) { - if (bp->b_resid > 0) - error = EIO; /* OFS needs the complete block */ - else if (adoswordn(bp, 0) != BPT_DATA) { -#ifdef DIAGNOSTIC - printf("adosfs: bad primary type blk %d\n", - bp->b_blkno / amp->secsperblk); -#endif - error=EINVAL; - } - else if (adoscksum(bp, ap->nwords)) { -#ifdef DIAGNOSTIC - printf("adosfs: blk %u failed cksum.\n", - bp->b_blkno / amp->secsperblk); -#endif - error=EINVAL; - } - } - - if (error) { - brelse(bp); - goto reterr; - } -#ifdef ADOSFS_DIAGNOSTIC - printf(" %u+%u-%u+%u", lbn, on, lbn, n); -#endif - n = min(n, size - bp->b_resid); /* XXX check types */ - error = uiomove(bp->b_data + on + amp->bsize - - amp->dbsize, n, uio); - brelse(bp); - off = (u_int32_t)uio->uio_offset; - } while (error == 0 && uio->uio_resid > 0 && n != 0); -reterr: -#ifdef ADOSFS_DIAGNOSTIC - printf(" %d)", error); -#endif - return(error); -} - -int -adosfs_write(v) - void *v; -{ -#ifdef ADOSFS_DIAGNOSTIC - struct vop_write_args /* { - struct vnode *a_vp; - struct uio *a_uio; - int a_ioflag; - struct ucred *a_cred; - } */ *sp = v; - advopprint(sp); - printf(" EOPNOTSUPP)"); -#endif - return(EOPNOTSUPP); -} - -/* - * Device ioctl operation. - */ -/* ARGSUSED */ -int -adosfs_ioctl(v) - void *v; -{ -#ifdef ADOSFS_DIAGNOSTIC - struct vop_ioctl_args /* { - struct vnode *a_vp; - u_long a_command; - caddr_t a_data; - int a_fflag; - struct ucred *a_cred; - struct proc *a_p; - } */ *sp = v; - advopprint(sp); - printf(" ENOTTY)"); -#endif - return(ENOTTY); -} - -/* ARGSUSED */ -int -adosfs_poll(v) - void *v; -{ - struct vop_poll_args /* { - struct vnode *a_vp; - int a_events; - struct proc *a_p; - } */ *ap = v; -#ifdef ADOSFS_DIAGNOSTIC - /* - * sure there's something to read... - */ - advopprint(sp); - printf(" %d", - ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); -#endif - return(ap->a_events & (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM)); -} - -/* - * Just call the device strategy routine - */ -int -adosfs_strategy(v) - void *v; -{ - struct vop_strategy_args /* { - struct buf *a_bp; - } */ *sp = v; - struct buf *bp; - struct anode *ap; - struct vnode *vp; - int error; - int s; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); -#endif - error = 0; - bp = sp->a_bp; - if (bp->b_vp == NULL) { - bp->b_flags |= B_ERROR; - s = splbio(); - biodone(bp); - splx(s); - error = EIO; - goto reterr; - } - vp = bp->b_vp; - ap = VTOA(vp); - if (bp->b_blkno == bp->b_lblkno) { - error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL); - if (error) { - bp->b_flags |= B_ERROR; - s = splbio(); - biodone(bp); - splx(s); - goto reterr; - } - } -#if 0 - if (bp->b_blkno == UINT_MAX) { /* XXX huh? (was (long)... == -1 */ - biodone(bp); - error = 0; - goto reterr; - } -#endif - vp = ap->amp->devvp; - bp->b_dev = vp->v_rdev; - VOCALL(vp->v_op, VOFFSET(vop_strategy), sp); -reterr: -#ifdef ADOSFS_DIAGNOSTIC - printf(" %d)", error); -#endif - return(error); -} - -int -adosfs_link(v) - void *v; -{ - struct vop_link_args /* { - struct vnode *a_dvp; - struct vnode *a_vp; - struct componentname *a_cnp; - } */ *ap = v; - - VOP_ABORTOP(ap->a_dvp, ap->a_cnp); - vput(ap->a_dvp); - return (EROFS); -} - -int -adosfs_symlink(v) - void *v; -{ - struct vop_symlink_args /* { - struct vnode *a_dvp; - struct vnode **a_vpp; - struct componentname *a_cnp; - struct vattr *a_vap; - char *a_target; - } */ *ap = v; - - VOP_ABORTOP(ap->a_dvp, ap->a_cnp); - vput(ap->a_dvp); - return (EROFS); -} - -/* - * lock the anode - */ -int -adosfs_lock(v) - void *v; -{ - struct vop_lock_args /* { - struct vnode *a_vp; - int a_flags; - struct proc *a_p; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - int rv; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(ap); -#endif - - rv = lockmgr(&VTOA(vp)->a_lock, ap->a_flags, NULL); - -#ifdef ADOSFS_DIAGNOSTIC - printf(" %d)", rv); -#endif - return (rv); -} - -/* - * unlock an anode - */ -int -adosfs_unlock(v) - void *v; -{ - struct vop_unlock_args /* { - struct vnode *a_vp; - } */ *ap = v; - struct vnode *vp = ap->a_vp; - int rv; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(ap); -#endif - - rv = lockmgr(&VTOA(vp)->a_lock, ap->a_flags | LK_RELEASE, NULL); - -#ifdef ADOSFS_DIAGNOSTIC - printf(" %d)", rv); -#endif - return (rv); -} - -/* - * Wait until the vnode has finished changing state. - */ -int -adosfs_bmap(v) - void *v; -{ - struct vop_bmap_args /* { - struct vnode *a_vp; - daddr_t a_bn; - struct vnode **a_vpp; - daddr_t *a_bnp; - int *a_runp; - } */ *sp = v; - struct anode *ap; - struct buf *flbp; - daddr_t *bnp, bn, nb, flblk, fcnt; - int error, flblkoff; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); -#endif - ap = VTOA(sp->a_vp); - bn = sp->a_bn / ap->amp->secsperblk; - bnp = sp->a_bnp; - error = 0; - - if (sp->a_vpp != NULL) - *sp->a_vpp = ap->amp->devvp; - if (bnp == NULL) - goto reterr; - if (bn < 0) { - error = EFBIG; - goto reterr; - } - if (sp->a_vp->v_type != VREG) { - error = EINVAL; - goto reterr; - } - - /* - * walk the chain of file list blocks until we find - * the one that will yield the block pointer we need. - */ - if (ap->type == AFILE) - nb = ap->block; /* pointer to ourself */ - else if (ap->type == ALFILE) - nb = ap->linkto; /* pointer to real file */ - else { - error = EINVAL; - goto reterr; - } - - flblk = bn / ANODENDATBLKENT(ap); - flbp = NULL; - - /* - * check last indirect block cache - */ - if (flblk < ap->lastlindblk) - fcnt = 0; - else { - flblk -= ap->lastlindblk; - fcnt = ap->lastlindblk; - nb = ap->lastindblk; - } - while (1) { - if (flbp) - brelse(flbp); - if (nb == 0) { -#ifdef DIAGNOSTIC - printf("adosfs: bad file list chain.\n"); -#endif - error = EINVAL; - goto reterr; - } - error = bread(ap->amp->devvp, nb * ap->amp->secsperblk, - ap->amp->bsize, NOCRED, &flbp); - if (error) - goto reterr; - if (adoscksum(flbp, ap->nwords)) { -#ifdef DIAGNOSTIC - printf("adosfs: blk %u failed cksum.\n", nb); -#endif - brelse(flbp); - error = EINVAL; - goto reterr; - } - /* - * update last indirect block cache - */ - ap->lastlindblk = fcnt++; - ap->lastindblk = nb; - - nb = (daddr_t)adoswordn(flbp, ap->nwords - 2); - if (flblk == 0) - break; - flblk--; - } - /* - * calculate offset of block number in table. The table starts - * at nwords - 51 and goes to offset 6 or less if indicated by the - * valid table entries stored at offset ADBI_NBLKTABENT. - */ - flblkoff = bn % ANODENDATBLKENT(ap); - if (flblkoff < adoswordn(flbp, 2 /* ADBI_NBLKTABENT */)) { - flblkoff = (ap->nwords - 51) - flblkoff; - *bnp = adoswordn(flbp, flblkoff) * ap->amp->secsperblk; - } else { -#ifdef DIAGNOSTIC - printf("flblk offset %d too large in lblk %u blk %u\n", - flblkoff, bn / ap->amp->secsperblk, flbp->b_blkno); -#endif - error = EINVAL; - } - brelse(flbp); -reterr: -#ifdef ADOSFS_DIAGNOSTIC - if (error == 0 && bnp) - printf(" %u => %u", bn, *bnp); - printf(" %d)", error); -#endif - return(error); -} - -/* - * Print out the contents of an adosfs vnode. - */ -/* ARGSUSED */ -int -adosfs_print(v) - void *v; -{ -#ifdef DIAGNOSTIC - struct vop_print_args /* { - struct vnode *a_vp; - } */ *ap = v; - struct anode *anp = VTOA(ap->a_vp); -#endif - - /* XXX Fill in more info here. */ - printf("tag VT_ADOSFS\n"); -#ifdef DIAGNOSTIC - lockmgr_printinfo(&anp->a_lock); -#endif - return(0); -} - -int -adosfs_advlock(v) - void *v; -{ - struct vop_advlock_args /* { - struct vnode *a_vp; - caddr_t a_id; - int a_op; - struct flock *a_fl; - int a_flags; - } */ *ap = v; - register struct anode *anp = VTOA(ap->a_vp); - - return (lf_advlock(&anp->a_lockf, anp->fsize, ap->a_id, ap->a_op, - ap->a_fl, ap->a_flags)); -} - -/* This is laid out like a standard dirent, except that it is shorter. */ -struct adirent { - u_int32_t fileno; - u_int16_t reclen; - u_int8_t type; - u_int8_t namlen; - char name[32]; /* maxlen of 30 plus 2 NUL's */ -}; - -/* XXX look over the off_t usage below wrt type safety */ -int -adosfs_readdir(v) - void *v; -{ - struct vop_readdir_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - int *a_eofflag; - u_long **a_cookies; - int *a_ncookies; - } */ *sp = v; - int error, useri, chainc, hashi, scanned, uavail; - struct adirent ad, *adp; - struct anode *pap, *ap; - struct adosfsmount *amp; - struct vnode *vp; - struct uio *uio; - daddr_t nextbn; - off_t uoff; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); -#endif - if (sp->a_vp->v_type != VDIR) { - error = ENOTDIR; - goto reterr; - } - uio = sp->a_uio; - uoff = uio->uio_offset; - if (uoff < 0) { - error = EINVAL; - goto reterr; - } - - pap = VTOA(sp->a_vp); - amp = pap->amp; - adp = &ad; - error = nextbn = hashi = chainc = scanned = 0; - uavail = uio->uio_resid / sizeof(ad); - useri = uoff / sizeof(ad); - - /* - * if no slots available or offset requested is not on a slot boundary - */ - if (uavail < 1 || uoff % sizeof(ad)) { - error = EINVAL; - goto reterr; - } - - while (uavail && (sp->a_cookies == NULL || sp->a_ncookies > 0)) { - if (hashi == pap->ntabent) { - *sp->a_eofflag = 1; - break; - } - if (pap->tab[hashi] == 0) { - hashi++; - continue; - } - if (nextbn == 0) - nextbn = pap->tab[hashi]; - - /* - * first determine if we can skip this chain - */ - if (chainc == 0) { - int skip; - - skip = useri - scanned; - if (pap->tabi[hashi] > 0 && pap->tabi[hashi] <= skip) { - scanned += pap->tabi[hashi]; - hashi++; - nextbn = 0; - continue; - } - } - - /* - * now [continue to] walk the chain - */ - ap = NULL; - do { - error = VFS_VGET(amp->mp, ABLKTOINO(nextbn), &vp); - if (error) - goto reterr; - ap = VTOA(vp); - scanned++; - chainc++; - nextbn = ap->hashf; - - /* - * check for end of chain. - */ - if (nextbn == 0) { - pap->tabi[hashi] = chainc; - hashi++; - chainc = 0; - } else if (pap->tabi[hashi] <= 0 && - -chainc < pap->tabi[hashi]) - pap->tabi[hashi] = -chainc; - - if (useri >= scanned) { - vput(vp); - ap = NULL; - } - } while (ap == NULL && nextbn != 0); - - /* - * we left the loop but without a result so do main over. - */ - if (ap == NULL) - continue; - /* - * Fill in dirent record - */ - bzero(adp, sizeof(struct adirent)); - adp->fileno = (u_int32_t)ap->block; - /* - * this deserves an function in kern/vfs_subr.c - */ - switch (ATOV(ap)->v_type) { - case VREG: - adp->type = DT_REG; - break; - case VDIR: - adp->type = DT_DIR; - break; - case VLNK: - adp->type = DT_LNK; - break; - default: - adp->type = DT_UNKNOWN; - break; - } - adp->reclen = sizeof(struct adirent); - adp->namlen = strlen(ap->name); - bcopy(ap->name, adp->name, adp->namlen); - vput(vp); - - error = uiomove((caddr_t)adp, sizeof(struct adirent), uio); - if (error) - break; -#ifdef FIXME_TO_HAVE_COOKIES - if (sp->a_cookies) { - *sp->a_cookies++ = (u_long)uoff; - sp->a_ncookies--; - } -#endif - uoff += sizeof(struct adirent); - useri++; - uavail--; - } -#if doesnt_uiomove_handle_this - uio->uio_offset = uoff; -#endif -reterr: -#ifdef ADOSFS_DIAGNOSTIC - printf(" %d)", error); -#endif - return(error); -} - - -int -adosfs_access(v) - void *v; -{ - struct vop_access_args /* { - struct vnode *a_vp; - int a_mode; - struct ucred *a_cred; - struct proc *a_p; - } */ *sp = v; - struct anode *ap; - int error; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); -#endif - - ap = VTOA(sp->a_vp); -#ifdef DIAGNOSTIC - if (!VOP_ISLOCKED(sp->a_vp)) { - vprint("adosfs_access: not locked", sp->a_vp); - panic("adosfs_access: not locked"); - } -#endif -#ifdef QUOTA -#endif - error = vaccess(adunixprot(ap->adprot) & ap->amp->mask, ap->uid, - ap->gid, sp->a_mode, sp->a_cred); -#ifdef ADOSFS_DIAGNOSTIC - printf(" %d)", error); -#endif - return(error); -} - -/*ARGSUSED*/ -int -adosfs_readlink(v) - void *v; -{ - struct vop_readlink_args /* { - struct vnode *a_vp; - struct uio *a_uio; - struct ucred *a_cred; - } */ *sp = v; - struct anode *ap; - int error; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); -#endif - ap = VTOA(sp->a_vp); - error = uiomove(ap->slinkto, strlen(ap->slinkto), sp->a_uio); -#ifdef ADOSFS_DIAGNOSTIC - printf(" %d)", error); -#endif - return (error); -} - -/*ARGSUSED*/ -int -adosfs_inactive(v) - void *v; -{ - struct vop_inactive_args /* { - struct vnode *a_vp; - } */ *sp = v; -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); -#endif - - VOP_UNLOCK(sp->a_vp, 0, sp->a_p); - - if (sp->a_vp->v_usecount == 0 /* && check for file gone? */) - vrecycle(sp->a_vp, sp->a_p); - -#ifdef ADOSFS_DIAGNOSTIC - printf(" 0)"); -#endif - return(0); -} - -int -adosfs_islocked(v) - void *v; -{ - struct vop_islocked_args /* { - struct vnode *a_vp; - } */ *ap = v; - int locked; - -#ifdef ADOSFS_DIAGNOSTIC - advopprint(ap); -#endif - - locked = lockstatus(&VTOA(ap->a_vp)->a_lock); - -#ifdef ADOSFS_DIAGNOSTIC - printf(" %d)", locked); -#endif - return(locked); -} - -/* - * the kernel wants its vnode back. - * no lock needed we are being called from vclean() - */ -int -adosfs_reclaim(v) - void *v; -{ - struct vop_reclaim_args /* { - struct vnode *a_vp; - } */ *sp = v; - struct vnode *vp; - struct anode *ap; - -#ifdef ADOSFS_DIAGNOSTIC - printf("(reclaim 0)"); -#endif - vp = sp->a_vp; - ap = VTOA(vp); - - adosfs_aremhash(ap); - - cache_purge(vp); - if (vp->v_type == VDIR && ap->tab) - free(ap->tab, M_ANODE); - else if (vp->v_type == VLNK && ap->slinkto) - free(ap->slinkto, M_ANODE); - free(ap, M_ANODE); - vp->v_data = NULL; - return(0); -} - - -/* - * POSIX pathconf info, grabbed from kern/u fs, probably need to - * investigate exactly what each return type means as they are probably - * not valid currently - */ -int -adosfs_pathconf(v) - void *v; -{ - struct vop_pathconf_args /* { - struct vnode *a_vp; - int a_name; - register_t *a_retval; - } */ *ap = v; - - switch (ap->a_name) { - case _PC_CHOWN_RESTRICTED: - *ap->a_retval = 1; - return (0); - case _PC_LINK_MAX: - *ap->a_retval = LINK_MAX; - return (0); - case _PC_MAX_CANON: - *ap->a_retval = MAX_CANON; - return (0); - case _PC_MAX_INPUT: - *ap->a_retval = MAX_INPUT; - return (0); - case _PC_NAME_MAX: - *ap->a_retval = 30; - return (0); - case _PC_NO_TRUNC: - *ap->a_retval = 0; - return (0); - case _PC_PATH_MAX: - *ap->a_retval = PATH_MAX; - return (0); - case _PC_PIPE_BUF: - *ap->a_retval = PIPE_BUF; - return (0); - case _PC_VDISABLE: - *ap->a_retval = _POSIX_VDISABLE; - return (0); - default: - return (EINVAL); - } - /* NOTREACHED */ -} - -int -adenotsup(sp) - void *sp; -{ -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); - printf(" EOPNOTSUPP)"); -#endif - return(EOPNOTSUPP); -} - -int -adnullop(sp) - void *sp; -{ -#ifdef ADOSFS_DIAGNOSTIC - advopprint(sp); - printf(" NULL)"); -#endif - return(0); -} -- cgit v1.2.3