diff options
Diffstat (limited to 'sys/adosfs')
-rw-r--r-- | sys/adosfs/adlookup.c | 277 | ||||
-rw-r--r-- | sys/adosfs/adosfs.h | 152 | ||||
-rw-r--r-- | sys/adosfs/adutil.c | 249 | ||||
-rw-r--r-- | sys/adosfs/advfsops.c | 758 | ||||
-rw-r--r-- | sys/adosfs/advnops.c | 1077 |
5 files changed, 0 insertions, 2513 deletions
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 <sys/param.h> -#include <sys/systm.h> -#include <sys/vnode.h> -#include <sys/namei.h> -#include <sys/mount.h> -#include <sys/time.h> -#include <sys/queue.h> -#include <adosfs/adosfs.h> - -#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 <sys/param.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/proc.h> -#include <sys/systm.h> -#include <sys/malloc.h> -#include <sys/lock.h> -#include <sys/time.h> -#include <sys/queue.h> -#include <sys/buf.h> - -#include <machine/endian.h> - -#include <adosfs/adosfs.h> - -/* - * 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 <sys/param.h> -#include <sys/systm.h> -#include <sys/vnode.h> -#include <sys/mount.h> -#include <sys/proc.h> -#include <sys/time.h> -#include <sys/malloc.h> -#include <sys/disklabel.h> -#include <sys/fcntl.h> -#include <sys/namei.h> -#include <sys/ioctl.h> -#include <sys/queue.h> -#include <sys/buf.h> - -#include <machine/endian.h> - -#include <miscfs/specfs/specdev.h> /* XXX */ -#include <adosfs/adosfs.h> - -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 <sys/param.h> -#include <sys/systm.h> -#include <sys/vnode.h> -#include <sys/lockf.h> -#include <sys/mount.h> -#include <sys/time.h> -#include <sys/queue.h> -#include <sys/namei.h> -#include <sys/buf.h> -#include <sys/dirent.h> -#include <sys/malloc.h> -#include <sys/stat.h> -#include <sys/unistd.h> -#include <sys/poll.h> -#include <sys/proc.h> - -#include <machine/endian.h> - -#include <miscfs/specfs/specdev.h> -#include <adosfs/adosfs.h> - -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); -} |