Initial commit of Andrew McMurry's Acorn Filecore filesystem.
This is a read only implementation of the filecore filesystem found on Acorn RiscPC machines (arm32).
This commit is contained in:
parent
4283228f33
commit
faf4eed3e3
8
sys/filecorefs/Makefile
Normal file
8
sys/filecorefs/Makefile
Normal file
@ -0,0 +1,8 @@
|
||||
# $NetBSD: Makefile,v 1.1 1998/08/14 03:26:12 mark Exp $
|
||||
|
||||
KDIR= /sys/filecorefs
|
||||
INCSDIR=/usr/include/filecorefs
|
||||
|
||||
INCS= filecore_mount.h
|
||||
|
||||
.include <bsd.kinc.mk>
|
119
sys/filecorefs/filecore.h
Normal file
119
sys/filecorefs/filecore.h
Normal file
@ -0,0 +1,119 @@
|
||||
/* $NetBSD: filecore.h,v 1.1 1998/08/14 03:26:12 mark Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1994 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore.h 1.0 1998/6/1
|
||||
*/
|
||||
|
||||
/*
|
||||
* Definitions describing Acorn Filecore file system structure, as well as
|
||||
* the functions necessary to access fields of filecore file system
|
||||
* structures.
|
||||
*/
|
||||
|
||||
#define FILECORE_BOOTBLOCK_BLKN 6
|
||||
#define FILECORE_BOOTBLOCK_SIZE 0x200
|
||||
#define FILECORE_BB_DISCREC 0x1C0
|
||||
#define FILECORE_DISCREC_SIZE 60
|
||||
#define FILECORE_DIR_SIZE 2048
|
||||
#define FILECORE_DIRENT_SIZE 26
|
||||
#define FILECORE_MAXDIRENTS 77
|
||||
|
||||
#define FILECORE_ROOTINO 0xFFFFFFFF
|
||||
#define FILECORE_INO_MASK 0x00FFFFFF
|
||||
#define FILECORE_INO_INDEX 24
|
||||
|
||||
#define FILECORE_ATTR_READ 1
|
||||
#define FILECORE_ATTR_WRITE 2
|
||||
#define FILECORE_ATTR_DIR 8
|
||||
#define FILECORE_ATTR_OREAD 32
|
||||
#define FILECORE_ATTR_OWRITE 64
|
||||
|
||||
#if 0
|
||||
#define FILECORE_DEBUG
|
||||
#define FILECORE_DEBUG_BR
|
||||
#endif
|
||||
|
||||
struct filecore_disc_record {
|
||||
unsigned log2secsize:8; /* base 2 log of the sector size */
|
||||
unsigned secspertrack:8; /* number of sectors per track */
|
||||
unsigned heads:8; /* number of heads */
|
||||
unsigned density:8; /* 0: harddisc, else floppy density */
|
||||
unsigned idlen:8; /* length of fragment id in bits */
|
||||
unsigned log2bpmb:8; /* base 2 log of the bytes per FAU */
|
||||
unsigned skew:8; /* track to sector skew */
|
||||
unsigned bootoption:8; /* *OPT option */
|
||||
unsigned lowsector:8; /* lowest sector id on a track */
|
||||
unsigned nzones:8; /* number of zones in the map */
|
||||
unsigned zone_spare:16; /* number of non-map bits per zone */
|
||||
unsigned root; /* address of root directory */
|
||||
unsigned disc_size; /* disc size in bytes (low word) */
|
||||
unsigned disc_id:16; /* disc cycle id */
|
||||
char disc_name[10]; /* disc name */
|
||||
unsigned disc_type; /* disc type */
|
||||
unsigned disc_size_2; /* disc size in bytes (high word) */
|
||||
unsigned share_size:8; /* base 2 log sharing granularity */
|
||||
unsigned big_flag:8; /* 1 if disc > 512Mb */
|
||||
char reserved[18];
|
||||
};
|
||||
|
||||
struct filecore_direntry {
|
||||
char name[10];
|
||||
unsigned load:32;
|
||||
unsigned exec:32;
|
||||
unsigned len:32;
|
||||
unsigned addr:24;
|
||||
unsigned attr:8;
|
||||
};
|
||||
|
||||
struct filecore_dirhead {
|
||||
unsigned mas_seq:8;
|
||||
unsigned chkname:32;
|
||||
};
|
||||
|
||||
struct filecore_dirtail {
|
||||
unsigned lastmark:8;
|
||||
unsigned reserved:16;
|
||||
unsigned parent1:16;
|
||||
unsigned parent2:8;
|
||||
char title[19];
|
||||
char name[10];
|
||||
unsigned mas_seq:8;
|
||||
unsigned chkname:32;
|
||||
unsigned checkbyte:8;
|
||||
};
|
||||
|
||||
#define fcdirhead(dp) ((struct filecore_dirhead *)(dp))
|
||||
#define fcdirentry(dp,n) (((struct filecore_direntry *)(((char *)(dp))+5))+(n))
|
||||
#define fcdirtail(dp) ((struct filecore_dirtail *)(((char *)(dp))+2007))
|
233
sys/filecorefs/filecore_bmap.c
Normal file
233
sys/filecorefs/filecore_bmap.c
Normal file
@ -0,0 +1,233 @@
|
||||
/* $NetBSD: filecore_bmap.c,v 1.1 1998/08/14 03:26:12 mark Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1994 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore_bmap.c 1.1 1998/6/26
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
#include <filecorefs/filecore.h>
|
||||
#include <filecorefs/filecore_extern.h>
|
||||
#include <filecorefs/filecore_node.h>
|
||||
|
||||
/*
|
||||
* Bmap converts a the logical block number of a file to its physical block
|
||||
* number on the disk. The conversion is done by using the logical block
|
||||
* number to index into the data block (extent) for the file.
|
||||
*/
|
||||
int
|
||||
filecore_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;
|
||||
} */ *ap = v;
|
||||
struct filecore_node *ip = VTOI(ap->a_vp);
|
||||
struct filecore_mnt *fcmp = ip->i_mnt;
|
||||
daddr_t lbn = ap->a_bn;
|
||||
|
||||
/*
|
||||
* Check for underlying vnode requests and ensure that logical
|
||||
* to physical mapping is requested.
|
||||
*/
|
||||
if (ap->a_vpp != NULL)
|
||||
*ap->a_vpp = ip->i_devvp;
|
||||
if (ap->a_bnp == NULL)
|
||||
return (0);
|
||||
|
||||
/*
|
||||
* Determine maximum number of readahead blocks following the
|
||||
* requested block.
|
||||
*/
|
||||
if (ap->a_runp) {
|
||||
int nblk;
|
||||
int bshift=fcmp->log2bsize;
|
||||
|
||||
nblk = (ip->i_size >> bshift) - (lbn + 1);
|
||||
if (nblk <= 0)
|
||||
*ap->a_runp = 0;
|
||||
else if (nblk >= (MAXBSIZE >> bshift))
|
||||
*ap->a_runp = (MAXBSIZE >> bshift) - 1;
|
||||
else
|
||||
*ap->a_runp = nblk;
|
||||
}
|
||||
/*
|
||||
* Compute the requested block number
|
||||
*/
|
||||
return filecore_map(fcmp, ip->i_dirent.addr, lbn, ap->a_bnp);
|
||||
}
|
||||
|
||||
int
|
||||
filecore_map(fcmp, addr, lbn, bnp)
|
||||
struct filecore_mnt *fcmp;
|
||||
u_int32_t addr;
|
||||
daddr_t lbn;
|
||||
daddr_t *bnp;
|
||||
{
|
||||
struct buf *bp;
|
||||
u_long frag,sect,zone,izone,a,b,m,n;
|
||||
u_int64_t zaddr;
|
||||
unsigned *ptr;
|
||||
long c;
|
||||
int error=0;
|
||||
|
||||
#ifdef FILECORE_DEBUG
|
||||
printf("filecore_map(addr=%x, lbn=%x)\n",addr,lbn);
|
||||
#endif
|
||||
frag=addr>>8;
|
||||
sect=(addr & 0xff) +
|
||||
((lbn<<fcmp->log2bsize)>>fcmp->drec.log2secsize);
|
||||
if (frag!=2)
|
||||
zone=frag/fcmp->idspz; else zone=fcmp->drec.nzones/2;
|
||||
izone=zone;
|
||||
if (zone!=0)
|
||||
zaddr=((8<<fcmp->drec.log2secsize)-fcmp->drec.zone_spare)*zone
|
||||
- 8*FILECORE_DISCREC_SIZE;
|
||||
else
|
||||
zaddr=0;
|
||||
if (sect>0) sect--;
|
||||
do {
|
||||
error=bread(fcmp->fc_devvp, fcmp->map + zone,
|
||||
1<<fcmp->drec.log2secsize, NOCRED, &bp);
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("bread(%p, %lx, %d, CRED, %p)=%d\n",fcmp->fc_devvp,
|
||||
fcmp->map+zone, 1<<fcmp->drec.log2secsize, bp, error);
|
||||
printf("block is at %p\n",bp->b_data);
|
||||
#endif
|
||||
if (error!=0) {
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) bm1\n",bp);
|
||||
#endif
|
||||
|
||||
brelse(bp);
|
||||
return error;
|
||||
}
|
||||
ptr=(unsigned *)(bp->b_data)+1; /* skip map zone header */
|
||||
if (zone==0) ptr+=FILECORE_DISCREC_SIZE>>2;
|
||||
b=0;
|
||||
while (b < (8<<(fcmp->drec.log2secsize))-fcmp->drec.zone_spare) {
|
||||
a=ptr[b>>5]>>(b&31);
|
||||
c=32-(b&31)-fcmp->drec.idlen;
|
||||
if (c<=0) {
|
||||
m = ptr[(b>>5)+1];
|
||||
a |= m << (fcmp->drec.idlen+c);
|
||||
m >>= -c;
|
||||
c+=32;
|
||||
} else m = a >> fcmp->drec.idlen;
|
||||
n=fcmp->drec.idlen+1;
|
||||
while ((m&1)==0) {
|
||||
m>>=1; n++;
|
||||
if (--c==0) { c=32; m=ptr[(b+n-1)>>5]; }
|
||||
}
|
||||
a &= fcmp->mask;
|
||||
if (a==frag) {
|
||||
if (sect<<fcmp->drec.log2secsize<n<<fcmp->drec.log2bpmb) {
|
||||
*bnp=(((zaddr+b)<<fcmp->drec.log2bpmb)>>fcmp->drec.log2secsize)+sect;
|
||||
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) bm2\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
return 0;
|
||||
} else sect -= (n<<fcmp->drec.log2bpmb) >> fcmp->drec.log2secsize;
|
||||
}
|
||||
b+=n;
|
||||
}
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) bm3\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
if (++zone==fcmp->drec.nzones) {
|
||||
zone=0; zaddr=0;
|
||||
} else zaddr+=((8<<fcmp->drec.log2secsize)-fcmp->drec.zone_spare);
|
||||
} while (zone!=izone);
|
||||
return (E2BIG);
|
||||
}
|
||||
|
||||
int
|
||||
filecore_bread(fcmp, addr, size, cred, bp)
|
||||
struct filecore_mnt *fcmp;
|
||||
u_int32_t addr;
|
||||
int size;
|
||||
struct ucred *cred;
|
||||
struct buf **bp;
|
||||
{
|
||||
int error=0;
|
||||
daddr_t bn;
|
||||
|
||||
error = filecore_map(fcmp, addr, 0, &bn);
|
||||
if (error) {
|
||||
|
||||
#ifdef FILECORE_DEBUG
|
||||
printf("filecore_bread(error=%d)\n",error);
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
error = bread(fcmp->fc_devvp, bn, size, cred, bp);
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("bread(%p, %x, %d, CRED, %p)=%d\n",fcmp->fc_devvp, bn, size,
|
||||
*bp, error);
|
||||
#endif
|
||||
return error;
|
||||
}
|
||||
|
||||
int
|
||||
filecore_dbread(ip, bp)
|
||||
struct filecore_node *ip;
|
||||
struct buf **bp;
|
||||
{
|
||||
int error=0;
|
||||
|
||||
if (ip->i_block==-1) error = filecore_map(ip->i_mnt, ip->i_dirent.addr,
|
||||
0, &(ip->i_block));
|
||||
if (error) return error;
|
||||
error = bread(ip->i_mnt->fc_devvp, ip->i_block, FILECORE_DIR_SIZE,
|
||||
NOCRED, bp);
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("bread(%p, %x, %d, CRED, %p)=%d\n",ip->i_mnt->fc_devvp,
|
||||
ip->i_block, FILECORE_DIR_SIZE, *bp, error);
|
||||
#endif
|
||||
return error;
|
||||
}
|
94
sys/filecorefs/filecore_extern.h
Normal file
94
sys/filecorefs/filecore_extern.h
Normal file
@ -0,0 +1,94 @@
|
||||
/* $NetBSD: filecore_extern.h,v 1.1 1998/08/14 03:26:12 mark Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1994 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore_extern.h 1.1 1998/6/26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Definitions used in the kernel for Acorn Filecore file system support.
|
||||
*/
|
||||
|
||||
#ifndef FILECOREMNT_ROOT
|
||||
#define FILECOREMNT_ROOT 0
|
||||
#endif
|
||||
|
||||
struct filecore_mnt {
|
||||
struct mount *fc_mountp;
|
||||
dev_t fc_dev;
|
||||
struct vnode *fc_devvp;
|
||||
|
||||
u_int32_t blksize;
|
||||
u_int32_t log2bsize;
|
||||
u_int32_t map;
|
||||
u_int32_t idspz;
|
||||
u_int32_t mask;
|
||||
u_int64_t nblks;
|
||||
|
||||
uid_t fc_uid; /* uid to set as owner of the files */
|
||||
gid_t fc_gid; /* gid to set as owner of the files */
|
||||
int fc_mntflags;
|
||||
struct netexport fc_export;
|
||||
struct filecore_disc_record drec;
|
||||
};
|
||||
|
||||
#define VFSTOFILECORE(mp) ((struct filecore_mnt *)((mp)->mnt_data))
|
||||
|
||||
#define blkoff(fcp, loc) ((loc) & ((fcp)->blksize-1))
|
||||
#define lblktosize(fcp, blk) ((blk) << (fcp)->log2bsize)
|
||||
#define lblkno(fcp, loc) ((loc) >> (fcp)->log2bsize)
|
||||
#define blksize(fcp, ip, lbn) ((fcp)->blksize)
|
||||
|
||||
int filecore_mount __P((struct mount *,
|
||||
const char *, void *, struct nameidata *, struct proc *));
|
||||
int filecore_start __P((struct mount *, int, struct proc *));
|
||||
int filecore_unmount __P((struct mount *, int, struct proc *));
|
||||
int filecore_root __P((struct mount *, struct vnode **));
|
||||
int filecore_quotactl __P((struct mount *, int, uid_t, caddr_t, struct proc *));
|
||||
int filecore_statfs __P((struct mount *, struct statfs *, struct proc *));
|
||||
int filecore_sync __P((struct mount *, int, struct ucred *, struct proc *));
|
||||
int filecore_vget __P((struct mount *, ino_t, struct vnode **));
|
||||
int filecore_fhtovp __P((struct mount *, struct fid *, struct mbuf *,
|
||||
struct vnode **, int *, struct ucred **));
|
||||
int filecore_vptofh __P((struct vnode *, struct fid *));
|
||||
void filecore_init __P((void));
|
||||
int filecore_sysctl __P((int *, u_int, void *, size_t *, void *, size_t,
|
||||
struct proc *));
|
||||
|
||||
extern int (**filecore_vnodeop_p) __P((void *));
|
||||
|
||||
int filecore_bbchecksum __P((void *));
|
||||
int filecore_bread __P((struct filecore_mnt *, u_int32_t, int, struct ucred *,
|
||||
struct buf **));
|
||||
int filecore_map __P((struct filecore_mnt *, u_int32_t, daddr_t, daddr_t *));
|
340
sys/filecorefs/filecore_lookup.c
Normal file
340
sys/filecorefs/filecore_lookup.c
Normal file
@ -0,0 +1,340 @@
|
||||
/* $NetBSD: filecore_lookup.c,v 1.1 1998/08/14 03:26:12 mark Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1989, 1993, 1994 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore_lookup.c 1.1 1998/6/26
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
#include <filecorefs/filecore.h>
|
||||
#include <filecorefs/filecore_extern.h>
|
||||
#include <filecorefs/filecore_node.h>
|
||||
|
||||
struct nchstats filecore_nchstats;
|
||||
|
||||
/*
|
||||
* Convert a component of a pathname into a pointer to a locked inode.
|
||||
* This is a very central and rather complicated routine.
|
||||
* If the file system is not maintained in a strict tree hierarchy,
|
||||
* this can result in a deadlock situation (see comments in code below).
|
||||
*
|
||||
* The flag argument is LOOKUP, CREATE, RENAME, or DELETE depending on
|
||||
* whether the name is to be looked up, created, renamed, or deleted.
|
||||
* When CREATE, RENAME, or DELETE is specified, information usable in
|
||||
* creating, renaming, or deleting a directory entry may be calculated.
|
||||
* If flag has LOCKPARENT or'ed into it and the target of the pathname
|
||||
* exists, lookup returns both the target and its parent directory locked.
|
||||
* When creating or renaming and LOCKPARENT is specified, the target may
|
||||
* not be ".". When deleting and LOCKPARENT is specified, the target may
|
||||
* be "."., but the caller must check to ensure it does an vrele and iput
|
||||
* instead of two iputs.
|
||||
*
|
||||
* Overall outline of ufs_lookup:
|
||||
*
|
||||
* check accessibility of directory
|
||||
* look for name in cache, if found, then if at end of path
|
||||
* and deleting or creating, drop it, else return name
|
||||
* search for name in directory, to found or notfound
|
||||
* notfound:
|
||||
* if creating, return locked directory, leaving info on available slots
|
||||
* else return error
|
||||
* found:
|
||||
* if at end of path and deleting, return information to allow delete
|
||||
* if at end of path and rewriting (RENAME and LOCKPARENT), lock target
|
||||
* inode and return info to allow rewrite
|
||||
* if not at end, add name to cache; if at end and neither creating
|
||||
* nor deleting, add name to cache
|
||||
*
|
||||
* NOTE: (LOOKUP | LOCKPARENT) currently returns the parent inode unlocked.
|
||||
*/
|
||||
int
|
||||
filecore_lookup(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_lookup_args /* {
|
||||
struct vnode *a_dvp;
|
||||
struct vnode **a_vpp;
|
||||
struct componentname *a_cnp;
|
||||
} */ *ap = v;
|
||||
register struct vnode *vdp; /* vnode for directory being searched */
|
||||
register struct filecore_node *dp; /* inode for directory being searched */
|
||||
register struct filecore_mnt *fcmp; /* file system that directory is in */
|
||||
struct buf *bp; /* a buffer of directory entries */
|
||||
register struct filecore_direntry *de;
|
||||
int numdirpasses; /* strategy for directory search */
|
||||
struct vnode *pdp; /* saved dp during symlink work */
|
||||
struct vnode *tdp; /* returned by filecore_vget_internal */
|
||||
int lockparent; /* 1 => lockparent flag is set */
|
||||
int wantparent; /* 1 => wantparent or lockparent flag */
|
||||
int error;
|
||||
u_short namelen;
|
||||
int res;
|
||||
const char *name;
|
||||
struct vnode **vpp = ap->a_vpp;
|
||||
struct componentname *cnp = ap->a_cnp;
|
||||
struct ucred *cred = cnp->cn_cred;
|
||||
int flags = cnp->cn_flags;
|
||||
int nameiop = cnp->cn_nameiop;
|
||||
int i, endsearch;
|
||||
|
||||
bp = NULL;
|
||||
*vpp = NULL;
|
||||
vdp = ap->a_dvp;
|
||||
dp = VTOI(vdp);
|
||||
fcmp = dp->i_mnt;
|
||||
lockparent = flags & LOCKPARENT;
|
||||
wantparent = flags & (LOCKPARENT|WANTPARENT);
|
||||
|
||||
/*
|
||||
* Check accessiblity of directory.
|
||||
*/
|
||||
if ((error = VOP_ACCESS(vdp, VEXEC, cred, 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);
|
||||
|
||||
/*
|
||||
* We now have a segment name to search for, and a directory to search.
|
||||
*
|
||||
* 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) {
|
||||
int vpid; /* capability number of vnode */
|
||||
|
||||
if (error == ENOENT)
|
||||
return (error);
|
||||
#ifdef PARANOID
|
||||
if ((vdp->v_flag & VROOT) && (flags & ISDOTDOT))
|
||||
panic("filecore_lookup: .. through root");
|
||||
#endif
|
||||
/*
|
||||
* Get the next vnode in the path.
|
||||
* See comment below starting `Step through' for
|
||||
* an explaination of the locking protocol.
|
||||
*/
|
||||
pdp = vdp;
|
||||
dp = VTOI(*vpp);
|
||||
vdp = *vpp;
|
||||
vpid = vdp->v_id;
|
||||
if (pdp == vdp) {
|
||||
VREF(vdp);
|
||||
error = 0;
|
||||
} else if (flags & ISDOTDOT) {
|
||||
VOP_UNLOCK(pdp, 0);
|
||||
error = vget(vdp, LK_EXCLUSIVE);
|
||||
if (!error && lockparent && (flags & ISLASTCN))
|
||||
error = vn_lock(pdp, LK_EXCLUSIVE);
|
||||
} else {
|
||||
error = vget(vdp, LK_EXCLUSIVE);
|
||||
if (!lockparent || error || !(flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0);
|
||||
}
|
||||
/*
|
||||
* Check that the capability number did not change
|
||||
* while we were waiting for the lock.
|
||||
*/
|
||||
if (!error) {
|
||||
if (vpid == vdp->v_id)
|
||||
return (0);
|
||||
vput(vdp);
|
||||
if (lockparent && pdp != vdp && (flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0);
|
||||
}
|
||||
if ((error = vn_lock(pdp, LK_EXCLUSIVE)) != 0)
|
||||
return (error);
|
||||
vdp = pdp;
|
||||
dp = VTOI(pdp);
|
||||
*vpp = NULL;
|
||||
}
|
||||
|
||||
name = cnp->cn_nameptr;
|
||||
namelen = cnp->cn_namelen;
|
||||
|
||||
/*
|
||||
* If there is cached information on a previous search of
|
||||
* this directory, pick up where we last left off.
|
||||
* We cache only lookups as these are the most common
|
||||
* and have the greatest payoff. Caching CREATE has little
|
||||
* benefit as it usually must search the entire directory
|
||||
* to determine that the entry does not exist. Caching the
|
||||
* location of the last DELETE or RENAME has not reduced
|
||||
* profiling time and hence has been removed in the interest
|
||||
* of simplicity.
|
||||
*/
|
||||
if (nameiop != LOOKUP || dp->i_diroff == 0 ||
|
||||
dp->i_diroff >= FILECORE_MAXDIRENTS) {
|
||||
i = 0;
|
||||
numdirpasses = 1;
|
||||
} else {
|
||||
i = dp->i_diroff;
|
||||
numdirpasses = 2;
|
||||
filecore_nchstats.ncs_2passes++;
|
||||
}
|
||||
endsearch = FILECORE_MAXDIRENTS;
|
||||
|
||||
if ((flags & ISDOTDOT) || (name[0]=='.' && namelen==1))
|
||||
goto found;
|
||||
|
||||
error = filecore_dbread(dp, &bp);
|
||||
if (error) return error;
|
||||
|
||||
de = fcdirentry(bp->b_data,i);
|
||||
|
||||
searchloop:
|
||||
while (de->name[0]!=0 && i<endsearch) {
|
||||
/*
|
||||
* Check for a name match.
|
||||
*/
|
||||
res = filecore_fncmp(de->name,name,namelen);
|
||||
|
||||
if (res==0) goto found;
|
||||
if (res<0) goto notfound;
|
||||
|
||||
i++;
|
||||
de++;
|
||||
}
|
||||
|
||||
notfound:
|
||||
/*
|
||||
* If we started in the middle of the directory and failed
|
||||
* to find our target, we must check the beginning as well.
|
||||
*/
|
||||
if (numdirpasses == 2) {
|
||||
numdirpasses--;
|
||||
i = 0;
|
||||
de = fcdirentry(bp->b_data,i);
|
||||
endsearch = dp->i_diroff;
|
||||
goto searchloop;
|
||||
}
|
||||
if (bp != NULL) {
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) lo1\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert name into cache (as non-existent) if appropriate.
|
||||
*/
|
||||
if (cnp->cn_flags & MAKEENTRY)
|
||||
cache_enter(vdp, *vpp, cnp);
|
||||
if (nameiop == CREATE || nameiop == RENAME)
|
||||
return (EJUSTRETURN);
|
||||
return (ENOENT);
|
||||
|
||||
found:
|
||||
if (numdirpasses == 2)
|
||||
filecore_nchstats.ncs_pass2++;
|
||||
|
||||
/*
|
||||
* Found component in pathname.
|
||||
* If the final component of path name, save information
|
||||
* in the cache as to where the entry was found.
|
||||
*/
|
||||
if ((flags & ISLASTCN) && nameiop == LOOKUP)
|
||||
dp->i_diroff = i;
|
||||
|
||||
/*
|
||||
* Step through the translation in the name. We do not `iput' the
|
||||
* directory because we may need it again if a symbolic link
|
||||
* is relative to the current directory. Instead we save it
|
||||
* unlocked as "pdp". We must get the target inode before unlocking
|
||||
* the directory to insure that the inode will not be removed
|
||||
* before we get it. We prevent deadlock by always fetching
|
||||
* inodes from the root, moving down the directory tree. Thus
|
||||
* when following backward pointers ".." we must unlock the
|
||||
* parent directory before getting the requested directory.
|
||||
* There is a potential race condition here if both the current
|
||||
* and parent directories are removed before the `iget' for the
|
||||
* inode associated with ".." returns. We hope that this occurs
|
||||
* infrequently since we cannot avoid this race condition without
|
||||
* implementing a sophisticated deadlock detection algorithm.
|
||||
* Note also that this simple deadlock detection scheme will not
|
||||
* work if the file system has any hard links other than ".."
|
||||
* that point backwards in the directory structure.
|
||||
*/
|
||||
pdp = vdp;
|
||||
/*
|
||||
* If ino is different from dp->i_ino,
|
||||
* it's a relocated directory.
|
||||
*/
|
||||
if (flags & ISDOTDOT) {
|
||||
ino_t pin = filecore_getparent(dp);
|
||||
VOP_UNLOCK(pdp, 0); /* race to get the inode */
|
||||
error = VFS_VGET(vdp->v_mount, pin, &tdp);
|
||||
if (error) {
|
||||
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY);
|
||||
return (error);
|
||||
}
|
||||
if (lockparent && (flags & ISLASTCN) &&
|
||||
(error = vn_lock(pdp, LK_EXCLUSIVE))) {
|
||||
vput(tdp);
|
||||
return (error);
|
||||
}
|
||||
*vpp = tdp;
|
||||
} else if (name[0]=='.' && namelen==1) {
|
||||
VREF(vdp); /* we want ourself, ie "." */
|
||||
*vpp = vdp;
|
||||
} else {
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) lo4\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
error = VFS_VGET(vdp->v_mount, dp->i_dirent.addr |
|
||||
(i<<FILECORE_INO_INDEX), &tdp);
|
||||
if (error)
|
||||
return (error);
|
||||
if (!lockparent || !(flags & ISLASTCN))
|
||||
VOP_UNLOCK(pdp, 0);
|
||||
*vpp = tdp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert name into cache if appropriate.
|
||||
*/
|
||||
if (cnp->cn_flags & MAKEENTRY)
|
||||
cache_enter(vdp, *vpp, cnp);
|
||||
return (0);
|
||||
}
|
55
sys/filecorefs/filecore_mount.h
Normal file
55
sys/filecorefs/filecore_mount.h
Normal file
@ -0,0 +1,55 @@
|
||||
/* $NetBSD: filecore_mount.h,v 1.1 1998/08/14 03:26:13 mark Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1995 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore_mount.h 1.1 1998/6/26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Arguments to mount Acorn Filecore filesystems.
|
||||
*/
|
||||
struct filecore_args {
|
||||
char *fspec; /* block special device to mount */
|
||||
struct export_args export; /* network export info */
|
||||
uid_t uid; /* uid that owns filecore files */
|
||||
gid_t gid; /* gid that owns filecore files */
|
||||
int flags; /* mounting flags, see below */
|
||||
};
|
||||
|
||||
#define FILECOREMNT_ROOT 0
|
||||
#define FILECOREMNT_OWNACCESS 1 /* Only user has Owner access */
|
||||
#define FILECOREMNT_ALLACCESS 2 /* World has Owner access */
|
||||
#define FILECOREMNT_OWNREAD 4 /* All files have Owner read access */
|
||||
#define FILECOREMNT_USEUID 8 /* Use uid of mount process */
|
||||
#define FILECOREMNT_FILETYPE 16 /* Include filetype in filename */
|
209
sys/filecorefs/filecore_node.c
Normal file
209
sys/filecorefs/filecore_node.c
Normal file
@ -0,0 +1,209 @@
|
||||
/* $NetBSD: filecore_node.c,v 1.1 1998/08/14 03:26:13 mark Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1982, 1986, 1989, 1994
|
||||
* The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore_node.c 1.0 1998/6/4
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <filecorefs/filecore.h>
|
||||
#include <filecorefs/filecore_extern.h>
|
||||
#include <filecorefs/filecore_node.h>
|
||||
#include <filecorefs/filecore_mount.h>
|
||||
|
||||
/*
|
||||
* Structures associated with filecore_node caching.
|
||||
*/
|
||||
struct filecore_node **filecorehashtbl;
|
||||
u_long filecorehash;
|
||||
#define INOHASH(device, inum) (((device) + ((inum)>>12)) & filecorehash)
|
||||
struct simplelock filecore_ihash_slock;
|
||||
|
||||
int prtactive; /* 1 => print out reclaim of active vnodes */
|
||||
|
||||
/*
|
||||
* Initialize hash links for inodes and dnodes.
|
||||
*/
|
||||
void
|
||||
filecore_init()
|
||||
{
|
||||
|
||||
filecorehashtbl = hashinit(desiredvnodes, M_FILECOREMNT, M_WAITOK, &filecorehash);
|
||||
simple_lock_init(&filecore_ihash_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Use the device/inum pair to find the incore inode, and return a pointer
|
||||
* to it. If it is in core, but locked, wait for it.
|
||||
*/
|
||||
struct vnode *
|
||||
filecore_ihashget(dev, inum)
|
||||
dev_t dev;
|
||||
ino_t inum;
|
||||
{
|
||||
struct filecore_node *ip;
|
||||
struct vnode *vp;
|
||||
|
||||
loop:
|
||||
simple_lock(&filecore_ihash_slock);
|
||||
for (ip = filecorehashtbl[INOHASH(dev, inum)]; ip; ip = ip->i_next) {
|
||||
if (inum == ip->i_number && dev == ip->i_dev) {
|
||||
vp = ITOV(ip);
|
||||
simple_lock(&vp->v_interlock);
|
||||
simple_unlock(&filecore_ihash_slock);
|
||||
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
|
||||
goto loop;
|
||||
return (vp);
|
||||
}
|
||||
}
|
||||
simple_unlock(&filecore_ihash_slock);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Insert the inode into the hash table, and return it locked.
|
||||
*/
|
||||
void
|
||||
filecore_ihashins(ip)
|
||||
struct filecore_node *ip;
|
||||
{
|
||||
struct filecore_node **ipp, *iq;
|
||||
|
||||
simple_lock(&filecore_ihash_slock);
|
||||
ipp = &filecorehashtbl[INOHASH(ip->i_dev, ip->i_number)];
|
||||
if ((iq = *ipp) != NULL)
|
||||
iq->i_prev = &ip->i_next;
|
||||
ip->i_next = iq;
|
||||
ip->i_prev = ipp;
|
||||
*ipp = ip;
|
||||
simple_unlock(&filecore_ihash_slock);
|
||||
|
||||
lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove the inode from the hash table.
|
||||
*/
|
||||
void
|
||||
filecore_ihashrem(ip)
|
||||
register struct filecore_node *ip;
|
||||
{
|
||||
register struct filecore_node *iq;
|
||||
|
||||
simple_lock(&filecore_ihash_slock);
|
||||
if ((iq = ip->i_next) != NULL)
|
||||
iq->i_prev = ip->i_prev;
|
||||
*ip->i_prev = iq;
|
||||
#ifdef DIAGNOSTIC
|
||||
ip->i_next = NULL;
|
||||
ip->i_prev = NULL;
|
||||
#endif
|
||||
simple_unlock(&filecore_ihash_slock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Last reference to an inode, write the inode out and if necessary,
|
||||
* truncate and deallocate the file.
|
||||
*/
|
||||
int
|
||||
filecore_inactive(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_inactive_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct proc *p = ap->a_p;
|
||||
register struct filecore_node *ip = VTOI(vp);
|
||||
int error = 0;
|
||||
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("filecore_inactive: pushing active", vp);
|
||||
|
||||
ip->i_flag = 0;
|
||||
VOP_UNLOCK(vp, 0);
|
||||
/*
|
||||
* If we are done with the inode, reclaim it
|
||||
* so that it can be reused immediately.
|
||||
*/
|
||||
if (filecore_staleinode(ip))
|
||||
vrecycle(vp, (struct simplelock *)0, p);
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reclaim an inode so that it can be used for other purposes.
|
||||
*/
|
||||
int
|
||||
filecore_reclaim(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_reclaim_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
register struct filecore_node *ip = VTOI(vp);
|
||||
|
||||
if (prtactive && vp->v_usecount != 0)
|
||||
vprint("filecore_reclaim: pushing active", vp);
|
||||
/*
|
||||
* Remove the inode from its hash chain.
|
||||
*/
|
||||
filecore_ihashrem(ip);
|
||||
/*
|
||||
* Purge old data structures associated with the inode.
|
||||
*/
|
||||
cache_purge(vp);
|
||||
if (ip->i_devvp) {
|
||||
vrele(ip->i_devvp);
|
||||
ip->i_devvp = 0;
|
||||
}
|
||||
FREE(vp->v_data, M_FILECORENODE);
|
||||
vp->v_data = NULL;
|
||||
return (0);
|
||||
}
|
115
sys/filecorefs/filecore_node.h
Normal file
115
sys/filecorefs/filecore_node.h
Normal file
@ -0,0 +1,115 @@
|
||||
/* $NetBSD: filecore_node.h,v 1.1 1998/08/14 03:26:13 mark Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1994 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore_node.h 1.1 1998/6/26
|
||||
*/
|
||||
|
||||
/*
|
||||
* In a future format, directories may be more than 2Gb in length,
|
||||
* however, in practice this seems unlikely. So, we define
|
||||
* the type doff_t as a long to keep down the cost of doing
|
||||
* lookup on a 32-bit machine. If you are porting to a 64-bit
|
||||
* architecture, you should make doff_t the same as off_t.
|
||||
*/
|
||||
#define doff_t long
|
||||
|
||||
struct filecore_node {
|
||||
struct filecore_node *i_next, **i_prev; /* hash chain */
|
||||
struct vnode *i_vnode; /* vnode associated with this inode */
|
||||
struct vnode *i_devvp; /* vnode for block I/O */
|
||||
u_long i_flag; /* see below */
|
||||
dev_t i_dev; /* device where inode resides */
|
||||
ino_t i_number; /* the identity of the inode */
|
||||
daddr_t i_block; /* the disc address of the file */
|
||||
ino_t i_parent; /* the ino of the file's parent */
|
||||
|
||||
struct filecore_mnt *i_mnt; /* filesystem associated with this inode */
|
||||
struct lockf *i_lockf; /* head of byte-level lock list */
|
||||
struct lock i_lock; /* node lock */
|
||||
int i_diroff; /* offset in dir, where we found last entry */
|
||||
|
||||
struct filecore_direntry i_dirent; /* directory entry */
|
||||
};
|
||||
|
||||
#define i_forw i_chain[0]
|
||||
#define i_back i_chain[1]
|
||||
#define i_size i_dirent.len
|
||||
|
||||
/* flags */
|
||||
#define IN_ACCESS 0x0020 /* inode access time to be updated */
|
||||
|
||||
#define VTOI(vp) ((struct filecore_node *)(vp)->v_data)
|
||||
#define ITOV(ip) ((ip)->i_vnode)
|
||||
|
||||
#define filecore_staleinode(ip) ((ip)->i_dirent.name[0]==0)
|
||||
|
||||
/*
|
||||
* Prototypes for Filecore vnode operations
|
||||
*/
|
||||
int filecore_lookup __P((void *));
|
||||
#define filecore_open genfs_nullop
|
||||
#define filecore_close genfs_nullop
|
||||
int filecore_access __P((void *));
|
||||
int filecore_getattr __P((void *));
|
||||
int filecore_read __P((void *));
|
||||
#define filecore_poll genfs_poll
|
||||
int filecore_mmap __P((void *));
|
||||
#define filecore_seek genfs_seek
|
||||
int filecore_readdir __P((void *));
|
||||
int filecore_readlink __P((void *));
|
||||
#define filecore_abortop genfs_abortop
|
||||
int filecore_inactive __P((void *));
|
||||
int filecore_reclaim __P((void *));
|
||||
int filecore_link __P((void *));
|
||||
int filecore_symlink __P((void *));
|
||||
int filecore_bmap __P((void *));
|
||||
int filecore_lock __P((void *));
|
||||
int filecore_unlock __P((void *));
|
||||
int filecore_strategy __P((void *));
|
||||
int filecore_print __P((void *));
|
||||
int filecore_islocked __P((void *));
|
||||
int filecore_pathconf __P((void *));
|
||||
int filecore_blkatoff __P((void *));
|
||||
|
||||
struct vnode *filecore_ihashget __P((dev_t, ino_t));
|
||||
void filecore_ihashins __P((struct filecore_node *));
|
||||
void filecore_ihashrem __P((struct filecore_node *));
|
||||
|
||||
mode_t filecore_mode __P((struct filecore_node *));
|
||||
struct timespec filecore_time __P((struct filecore_node *));
|
||||
ino_t filecore_getparent __P((struct filecore_node *));
|
||||
int filecore_fn2unix __P((char *, char *, u_int8_t *));
|
||||
int filecore_fncmp __P((const char *, const char *, u_short));
|
||||
int filecore_dbread __P((struct filecore_node *, struct buf **));
|
316
sys/filecorefs/filecore_utils.c
Normal file
316
sys/filecorefs/filecore_utils.c
Normal file
@ -0,0 +1,316 @@
|
||||
/* $NetBSD: filecore_utils.c,v 1.1 1998/08/14 03:26:13 mark Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1994 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code includes code derived from software contributed to the
|
||||
* NetBSD project by Mark Brinicombe.
|
||||
*
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore_utils.c 1.1 1998/6/26
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1998 Christopher G. Demetriou. 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 Christopher G. Demetriou
|
||||
* for the NetBSD Project.
|
||||
* 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/stat.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/dirent.h>
|
||||
|
||||
#include <filecorefs/filecore.h>
|
||||
#include <filecorefs/filecore_extern.h>
|
||||
#include <filecorefs/filecore_node.h>
|
||||
#include <filecorefs/filecore_mount.h>
|
||||
|
||||
/*
|
||||
* int filecore_bbchecksum(u_char *bootblock)
|
||||
*
|
||||
* Calculates the filecore boot block checksum. This is used to validate
|
||||
* a filecore boot block on the disk. If a boot block is validated then
|
||||
* it is used to locate the partition table. If the boot block is not
|
||||
* validated, it is assumed that the whole disk is NetBSD.
|
||||
*
|
||||
* The basic algorithm is:
|
||||
*
|
||||
* for (each byte in block, excluding checksum) {
|
||||
* sum += byte;
|
||||
* if (sum > 255)
|
||||
* sum -= 255;
|
||||
* }
|
||||
*
|
||||
* That's equivalent to summing all of the bytes in the block
|
||||
* (excluding the checksum byte, of course), then calculating the
|
||||
* checksum as "cksum = sum - ((sum - 1) / 255) * 255)". That
|
||||
* expression may or may not yield a faster checksum function,
|
||||
* but it's easier to reason about.
|
||||
*
|
||||
* Note that if you have a block filled with bytes of a single
|
||||
* value "X" (regardless of that value!) and calculate the cksum
|
||||
* of the block (excluding the checksum byte), you will _always_
|
||||
* end up with a checksum of X. (Do the math; that can be derived
|
||||
* from the checksum calculation function!) That means that
|
||||
* blocks which contain bytes which all have the same value will
|
||||
* always checksum properly. That's a _very_ unlikely occurence
|
||||
* (probably impossible, actually) for a valid filecore boot block,
|
||||
* so we treat such blocks as invalid.
|
||||
*/
|
||||
int
|
||||
filecore_bbchecksum(bb)
|
||||
void *bb;
|
||||
{
|
||||
u_char *bootblock = bb;
|
||||
u_char byte0, accum_diff;
|
||||
u_int sum;
|
||||
int i;
|
||||
|
||||
sum = 0;
|
||||
accum_diff = 0;
|
||||
byte0 = bootblock[0];
|
||||
|
||||
/*
|
||||
* Sum the contents of the block, keeping track of whether
|
||||
* or not all bytes are the same. If 'accum_diff' ends up
|
||||
* being zero, all of the bytes are, in fact, the same.
|
||||
*/
|
||||
for (i = 0; i < 511; ++i) {
|
||||
sum += bootblock[i];
|
||||
accum_diff |= bootblock[i] ^ byte0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check to see if the checksum byte is the same as the
|
||||
* rest of the bytes, too. (Note that if all of the bytes
|
||||
* are the same except the checksum, a checksum compare
|
||||
* won't succeed, but that's not our problem.)
|
||||
*/
|
||||
accum_diff |= bootblock[i] ^ byte0;
|
||||
sum = (sum - ((sum - 1) / 255) * 255);
|
||||
|
||||
/*
|
||||
* If all bytes in block are the same
|
||||
* or the checksum does not match ; call it invalid.
|
||||
*/
|
||||
if (accum_diff == 0 || sum != bootblock[511])
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mode_t
|
||||
filecore_mode(ip)
|
||||
struct filecore_node *ip;
|
||||
{
|
||||
mode_t m=0;
|
||||
int rf=0;
|
||||
|
||||
if ((ip->i_dirent.attr & FILECORE_ATTR_READ) ||
|
||||
(ip->i_mnt->fc_mntflags & FILECOREMNT_OWNREAD) ||
|
||||
(ip->i_dirent.attr & FILECORE_ATTR_DIR)) rf=1;
|
||||
if (ip->i_mnt->fc_mntflags & FILECOREMNT_ALLACCESS) {
|
||||
m|=S_IRUSR|S_IXUSR;
|
||||
if (rf || (ip->i_dirent.attr & FILECORE_ATTR_OREAD))
|
||||
m|=S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
|
||||
} else if (ip->i_mnt->fc_mntflags & FILECOREMNT_OWNACCESS) {
|
||||
if (rf) m|=S_IRUSR|S_IXUSR;
|
||||
if (ip->i_dirent.attr & FILECORE_ATTR_OREAD)
|
||||
m|=S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
|
||||
} else {
|
||||
m|=S_IRUSR|S_IXUSR;
|
||||
if (rf) m|=S_IRGRP|S_IXGRP;
|
||||
if (ip->i_dirent.attr & FILECORE_ATTR_OREAD)
|
||||
m|=S_IROTH|S_IXOTH;
|
||||
}
|
||||
if (ip->i_dirent.attr & FILECORE_ATTR_DIR) {
|
||||
m|=S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH;
|
||||
} else m|=S_IFREG;
|
||||
return m;
|
||||
}
|
||||
|
||||
struct timespec
|
||||
filecore_time(ip)
|
||||
struct filecore_node *ip;
|
||||
{
|
||||
struct timespec ts;
|
||||
u_int64_t cs;
|
||||
|
||||
cs=(((u_int64_t)(ip->i_dirent.load&0xFF))<<32) + ip->i_dirent.exec -
|
||||
((u_int64_t)1725772500 << 7);
|
||||
ts.tv_sec = cs/100;
|
||||
ts.tv_nsec = (cs%100)*10000000;
|
||||
return ts;
|
||||
}
|
||||
|
||||
ino_t
|
||||
filecore_getparent(ip)
|
||||
struct filecore_node *ip;
|
||||
{
|
||||
struct buf *pbp;
|
||||
u_int32_t addr;
|
||||
u_int32_t paddr;
|
||||
int error=0;
|
||||
int i=0;
|
||||
|
||||
#ifdef FILECORE_DEBUG
|
||||
printf("filecore_getparent(ino=%x)\n",ip->i_number);
|
||||
#endif
|
||||
if (ip->i_parent != -2) {
|
||||
return ip->i_parent;
|
||||
}
|
||||
if (ip->i_number == FILECORE_ROOTINO) {
|
||||
ip->i_parent = ip->i_number;
|
||||
return ip->i_number;
|
||||
}
|
||||
addr=ip->i_number & FILECORE_INO_MASK;
|
||||
/* Read directory data for parent dir to find its parent */
|
||||
#ifdef FILECORE_DEBUG
|
||||
printf("filecore_getparent() read parent dir contents\n");
|
||||
#endif
|
||||
error=filecore_bread(ip->i_mnt, addr,
|
||||
FILECORE_DIR_SIZE, NOCRED, &pbp);
|
||||
if (error)
|
||||
return error;
|
||||
paddr=fcdirtail(pbp->b_data)->parent1 | fcdirtail(pbp->b_data)->parent2<<16;
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) ut1\n",pbp);
|
||||
#endif
|
||||
brelse(pbp);
|
||||
|
||||
/* If parent's parent is the parent then parent is root dir */
|
||||
if (paddr == addr) {
|
||||
ip->i_parent = FILECORE_ROOTINO;
|
||||
return FILECORE_ROOTINO;
|
||||
}
|
||||
|
||||
#ifdef FILECORE_DEBUG
|
||||
printf("filecore_getparent() read grand-parent dir contents\n");
|
||||
#endif
|
||||
error=filecore_bread(ip->i_mnt, paddr,
|
||||
FILECORE_DIR_SIZE, NOCRED, &pbp);
|
||||
if (error)
|
||||
return error;
|
||||
while (fcdirentry(pbp->b_data,i)->addr != addr) {
|
||||
if (fcdirentry(pbp->b_data,i++)->name[0]==0) {
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) ut2\n",pbp);
|
||||
#endif
|
||||
brelse(pbp);
|
||||
return FILECORE_ROOTINO;
|
||||
}
|
||||
}
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) ut3\n",pbp);
|
||||
#endif
|
||||
brelse(pbp);
|
||||
ip->i_parent = paddr + (i<<FILECORE_INO_INDEX);
|
||||
return (paddr + (i<<FILECORE_INO_INDEX));
|
||||
}
|
||||
|
||||
/*static char filecore_hexchar[16]="0123456789abcdef";*/
|
||||
|
||||
int
|
||||
filecore_fn2unix(fcfn, ufn, len)
|
||||
char *fcfn;
|
||||
char *ufn;
|
||||
u_int8_t *len;
|
||||
{
|
||||
int i=0;
|
||||
|
||||
if (*fcfn==0) return (-1);
|
||||
while (i++<10 && *fcfn>=' ') {
|
||||
if (*fcfn=='/') *ufn++ = '.';
|
||||
else *ufn++ = *fcfn;
|
||||
fcfn++;
|
||||
}
|
||||
/* if (ip->i_mnt->fc_mntflags & FILECOREMNT_FILETYPE) {
|
||||
*ufn++ = ',';
|
||||
*ufn++ = filecore_hexchar[(ip->i_dirent.load>>10) & 15];
|
||||
*ufn++ = filecore_hexchar[(ip->i_dirent.load>>9) & 15];
|
||||
*ufn++ = filecore_hexchar[(ip->i_dirent.load>>8) & 15];
|
||||
} */
|
||||
*ufn=0;
|
||||
*len=i-1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
filecore_fncmp(fcfn, ufn, len)
|
||||
const char *fcfn;
|
||||
const char *ufn;
|
||||
u_short len;
|
||||
{
|
||||
char f, u;
|
||||
int i=0;
|
||||
|
||||
if (*fcfn==0 || len>10) return -1;
|
||||
while (i++<len) {
|
||||
if (*fcfn<' ') return 1;
|
||||
f = *fcfn++;
|
||||
u = *ufn++;
|
||||
if (u=='.') u = '/';
|
||||
if (u>='a' && u<='z') u -= 'a'-'A';
|
||||
if (f>='a' && f<='z') f -= 'a'-'A';
|
||||
if (f<u) return 1;
|
||||
else if (f>u) return -1;
|
||||
}
|
||||
if (len==10 || *fcfn<' ') return 0;
|
||||
return -1;
|
||||
}
|
665
sys/filecorefs/filecore_vfsops.c
Normal file
665
sys/filecorefs/filecore_vfsops.c
Normal file
@ -0,0 +1,665 @@
|
||||
/* $NetBSD: filecore_vfsops.c,v 1.1 1998/08/14 03:26:13 mark Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1994 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore_vfsops.c 1.1 1998/6/26
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <miscfs/specfs/specdev.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/device.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <filecorefs/filecore.h>
|
||||
#include <filecorefs/filecore_extern.h>
|
||||
#include <filecorefs/filecore_node.h>
|
||||
#include <filecorefs/filecore_mount.h>
|
||||
|
||||
extern struct vnodeopv_desc filecore_vnodeop_opv_desc;
|
||||
|
||||
struct vnodeopv_desc *filecore_vnodeopv_descs[] = {
|
||||
&filecore_vnodeop_opv_desc,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct vfsops filecore_vfsops = {
|
||||
MOUNT_FILECORE,
|
||||
filecore_mount,
|
||||
filecore_start,
|
||||
filecore_unmount,
|
||||
filecore_root,
|
||||
filecore_quotactl,
|
||||
filecore_statfs,
|
||||
filecore_sync,
|
||||
filecore_vget,
|
||||
filecore_fhtovp,
|
||||
filecore_vptofh,
|
||||
filecore_init,
|
||||
filecore_sysctl,
|
||||
NULL, /* filecore_mountroot */
|
||||
filecore_vnodeopv_descs,
|
||||
};
|
||||
|
||||
/*
|
||||
* Called by vfs_mountroot when iso is going to be mounted as root.
|
||||
*
|
||||
* Name is updated by mount(8) after booting.
|
||||
*/
|
||||
|
||||
static int filecore_mountfs __P((struct vnode *devvp, struct mount *mp,
|
||||
struct proc *p, struct filecore_args *argp));
|
||||
|
||||
#if 0
|
||||
int
|
||||
filecore_mountroot()
|
||||
{
|
||||
struct mount *mp;
|
||||
extern struct vnode *rootvp;
|
||||
struct proc *p = curproc; /* XXX */
|
||||
int error;
|
||||
struct filecore_args args;
|
||||
|
||||
if (root_device->dv_class != DV_DISK)
|
||||
return (ENODEV);
|
||||
|
||||
/*
|
||||
* Get vnodes for swapdev and rootdev.
|
||||
*/
|
||||
if (bdevvp(rootdev, &rootvp))
|
||||
panic("filecore_mountroot: can't setup rootvp");
|
||||
|
||||
if ((error = vfs_rootmountalloc(MOUNT_FILECORE, "root_device", &mp)) != 0)
|
||||
return (error);
|
||||
|
||||
args.flags = FILECOREMNT_ROOT;
|
||||
if ((error = filecore_mountfs(rootvp, mp, p, &args)) != 0) {
|
||||
mp->mnt_op->vfs_refcount--;
|
||||
vfs_unbusy(mp);
|
||||
free(mp, M_MOUNT);
|
||||
return (error);
|
||||
}
|
||||
simple_lock(&mountlist_slock);
|
||||
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
|
||||
simple_unlock(&mountlist_slock);
|
||||
(void)filecore_statfs(mp, &mp->mnt_stat, p);
|
||||
vfs_unbusy(mp);
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* VFS Operations.
|
||||
*
|
||||
* mount system call
|
||||
*/
|
||||
int
|
||||
filecore_mount(mp, path, data, ndp, p)
|
||||
struct mount *mp;
|
||||
const char *path;
|
||||
void *data;
|
||||
struct nameidata *ndp;
|
||||
struct proc *p;
|
||||
{
|
||||
struct vnode *devvp;
|
||||
struct filecore_args args;
|
||||
size_t size;
|
||||
int error;
|
||||
struct filecore_mnt *fcmp = NULL;
|
||||
|
||||
error = copyin(data, (caddr_t)&args, sizeof (struct filecore_args));
|
||||
if (error)
|
||||
return (error);
|
||||
|
||||
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) {
|
||||
fcmp = VFSTOFILECORE(mp);
|
||||
if (args.fspec == 0)
|
||||
return (vfs_export(mp, &fcmp->fc_export, &args.export));
|
||||
}
|
||||
/*
|
||||
* 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 ((mp->mnt_flag & MNT_UPDATE) == 0)
|
||||
error = filecore_mountfs(devvp, mp, p, &args);
|
||||
else {
|
||||
if (devvp != fcmp->fc_devvp)
|
||||
error = EINVAL; /* needs translation */
|
||||
else
|
||||
vrele(devvp);
|
||||
}
|
||||
if (error) {
|
||||
vrele(devvp);
|
||||
return error;
|
||||
}
|
||||
fcmp = VFSTOFILECORE(mp);
|
||||
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
|
||||
memset(mp->mnt_stat.f_mntonname + size, 0, MNAMELEN - size);
|
||||
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
|
||||
&size);
|
||||
memset(mp->mnt_stat.f_mntfromname + size, 0, MNAMELEN - size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common code for mount and mountroot
|
||||
*/
|
||||
static int
|
||||
filecore_mountfs(devvp, mp, p, argp)
|
||||
register struct vnode *devvp;
|
||||
struct mount *mp;
|
||||
struct proc *p;
|
||||
struct filecore_args *argp;
|
||||
{
|
||||
register struct filecore_mnt *fcmp = (struct filecore_mnt *)0;
|
||||
struct buf *bp = NULL;
|
||||
dev_t dev = devvp->v_rdev;
|
||||
int error = EINVAL;
|
||||
int ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
|
||||
extern struct vnode *rootvp;
|
||||
struct filecore_disc_record *fcdr;
|
||||
unsigned map;
|
||||
unsigned log2secsize;
|
||||
|
||||
if (!ronly)
|
||||
return EROFS;
|
||||
|
||||
/*
|
||||
* 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);
|
||||
|
||||
error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* Read the filecore boot block to check FS validity and to find the map */
|
||||
error = bread(devvp, FILECORE_BOOTBLOCK_BLKN,
|
||||
FILECORE_BOOTBLOCK_SIZE, NOCRED, &bp);
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("bread(%p, %x, %d, CRED, %p)=%d\n",devvp,
|
||||
FILECORE_BOOTBLOCK_BLKN, FILECORE_BOOTBLOCK_SIZE,
|
||||
bp, error);
|
||||
#endif
|
||||
if (error != 0)
|
||||
goto out;
|
||||
if (filecore_bbchecksum(bp->b_data) != 0) {
|
||||
error = EINVAL;
|
||||
goto out;
|
||||
}
|
||||
fcdr = (struct filecore_disc_record *)(bp->b_data+FILECORE_BB_DISCREC);
|
||||
map = ((((8<<fcdr->log2secsize)-fcdr->zone_spare)*(fcdr->nzones/2) -
|
||||
8*FILECORE_DISCREC_SIZE) << fcdr->log2bpmb) >> fcdr->log2secsize;
|
||||
log2secsize = fcdr->log2secsize;
|
||||
bp->b_flags |= B_AGE;
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) vf1\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
bp = NULL;
|
||||
|
||||
/* Read the bootblock in the map */
|
||||
error = bread(devvp, map, 1<<log2secsize, NOCRED, &bp);
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("bread(%p, %x, %d, CRED, %p)=%d\n",devvp,
|
||||
map, 1<<log2secsize, bp, error);
|
||||
#endif
|
||||
if (error != 0)
|
||||
goto out;
|
||||
fcdr = (struct filecore_disc_record *)(bp->b_data+4);
|
||||
fcmp = malloc(sizeof *fcmp, M_FILECOREMNT, M_WAITOK);
|
||||
memset((caddr_t)fcmp, 0, sizeof *fcmp);
|
||||
if (fcdr->log2bpmb > fcdr->log2secsize)
|
||||
fcmp->log2bsize = fcdr->log2bpmb;
|
||||
else fcmp->log2bsize = fcdr->log2secsize;
|
||||
fcmp->blksize = 1<<fcmp->log2bsize;
|
||||
memcpy((caddr_t)&fcmp->drec, (caddr_t)fcdr, sizeof(*fcdr));
|
||||
fcmp->map=map;
|
||||
fcmp->idspz=((8<<fcdr->log2secsize)-fcdr->zone_spare)/(fcdr->idlen+1);
|
||||
fcmp->mask=(1<<fcdr->idlen)-1;
|
||||
if (fcdr->big_flag & 1) {
|
||||
fcmp->nblks=((((u_int64_t)fcdr->disc_size_2)<<32)+fcdr->disc_size) /
|
||||
fcmp->blksize;
|
||||
} else {
|
||||
fcmp->nblks=fcdr->disc_size / fcmp->blksize;
|
||||
}
|
||||
|
||||
bp->b_flags |= B_AGE;
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) vf2\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
bp = NULL;
|
||||
|
||||
mp->mnt_data = (qaddr_t)fcmp;
|
||||
mp->mnt_stat.f_fsid.val[0] = (long)dev;
|
||||
mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_FILECORE);
|
||||
mp->mnt_maxsymlinklen = 0;
|
||||
mp->mnt_flag |= MNT_LOCAL;
|
||||
fcmp->fc_mountp = mp;
|
||||
fcmp->fc_dev = dev;
|
||||
fcmp->fc_devvp = devvp;
|
||||
fcmp->fc_mntflags = argp->flags;
|
||||
if (argp->flags & FILECOREMNT_USEUID) {
|
||||
fcmp->fc_uid = p->p_cred->p_ruid;
|
||||
fcmp->fc_gid = p->p_cred->p_rgid;
|
||||
} else {
|
||||
fcmp->fc_uid = argp->uid;
|
||||
fcmp->fc_gid = argp->gid;
|
||||
}
|
||||
|
||||
devvp->v_specflags |= SI_MOUNTEDON;
|
||||
|
||||
return 0;
|
||||
out:
|
||||
if (bp) {
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) vf3\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
}
|
||||
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
|
||||
if (fcmp) {
|
||||
free((caddr_t)fcmp, M_FILECOREMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
}
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a filesystem operational.
|
||||
* Nothing to do at the moment.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
filecore_start(mp, flags, p)
|
||||
struct mount *mp;
|
||||
int flags;
|
||||
struct proc *p;
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* unmount system call
|
||||
*/
|
||||
int
|
||||
filecore_unmount(mp, mntflags, p)
|
||||
struct mount *mp;
|
||||
int mntflags;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct filecore_mnt *fcmp;
|
||||
int error, flags = 0;
|
||||
|
||||
if (mntflags & MNT_FORCE)
|
||||
flags |= FORCECLOSE;
|
||||
#if 0
|
||||
mntflushbuf(mp, 0);
|
||||
if (mntinvalbuf(mp))
|
||||
return EBUSY;
|
||||
#endif
|
||||
if ((error = vflush(mp, NULLVP, flags)) != 0)
|
||||
return (error);
|
||||
|
||||
fcmp = VFSTOFILECORE(mp);
|
||||
|
||||
fcmp->fc_devvp->v_specflags &= ~SI_MOUNTEDON;
|
||||
error = VOP_CLOSE(fcmp->fc_devvp, FREAD, NOCRED, p);
|
||||
vrele(fcmp->fc_devvp);
|
||||
free((caddr_t)fcmp, M_FILECOREMNT);
|
||||
mp->mnt_data = (qaddr_t)0;
|
||||
mp->mnt_flag &= ~MNT_LOCAL;
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return root of a filesystem
|
||||
*/
|
||||
int
|
||||
filecore_root(mp, vpp)
|
||||
struct mount *mp;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
struct vnode *nvp;
|
||||
int error;
|
||||
|
||||
if ((error = VFS_VGET(mp, FILECORE_ROOTINO, &nvp)) != 0)
|
||||
return (error);
|
||||
*vpp = nvp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Do operations associated with quotas, not supported
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
filecore_quotactl(mp, cmd, uid, arg, p)
|
||||
struct mount *mp;
|
||||
int cmd;
|
||||
uid_t uid;
|
||||
caddr_t arg;
|
||||
struct proc *p;
|
||||
{
|
||||
|
||||
return (EOPNOTSUPP);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get file system statistics.
|
||||
*/
|
||||
int
|
||||
filecore_statfs(mp, sbp, p)
|
||||
struct mount *mp;
|
||||
register struct statfs *sbp;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct filecore_mnt *fcmp = VFSTOFILECORE(mp);
|
||||
|
||||
#ifdef COMPAT_09
|
||||
sbp->f_type = 255;
|
||||
#else
|
||||
sbp->f_type = 0;
|
||||
#endif
|
||||
sbp->f_bsize = fcmp->blksize;
|
||||
sbp->f_iosize = sbp->f_bsize; /* XXX */
|
||||
sbp->f_blocks = fcmp->nblks;
|
||||
sbp->f_bfree = 0; /* total free blocks */
|
||||
sbp->f_bavail = 0; /* blocks free for non superuser */
|
||||
sbp->f_files = 0; /* total files */
|
||||
sbp->f_ffree = 0; /* free file nodes */
|
||||
if (sbp != &mp->mnt_stat) {
|
||||
memcpy(sbp->f_mntonname, mp->mnt_stat.f_mntonname, MNAMELEN);
|
||||
memcpy(sbp->f_mntfromname, mp->mnt_stat.f_mntfromname, MNAMELEN);
|
||||
}
|
||||
strncpy(sbp->f_fstypename, mp->mnt_op->vfs_name, MFSNAMELEN);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
filecore_sync(mp, waitfor, cred, p)
|
||||
struct mount *mp;
|
||||
int waitfor;
|
||||
struct ucred *cred;
|
||||
struct proc *p;
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
|
||||
struct ifid {
|
||||
ushort ifid_len;
|
||||
ushort ifid_pad;
|
||||
u_int32_t ifid_ino;
|
||||
};
|
||||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
filecore_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
|
||||
register struct mount *mp;
|
||||
struct fid *fhp;
|
||||
struct mbuf *nam;
|
||||
struct vnode **vpp;
|
||||
int *exflagsp;
|
||||
struct ucred **credanonp;
|
||||
{
|
||||
struct ifid *ifhp = (struct ifid *)fhp;
|
||||
register struct netcred *np;
|
||||
register struct filecore_mnt *fcmp = VFSTOFILECORE(mp);
|
||||
struct vnode *nvp;
|
||||
struct filecore_node *ip;
|
||||
int error;
|
||||
|
||||
/*
|
||||
* Get the export permission structure for this <mp, client> tuple.
|
||||
*/
|
||||
np = vfs_export_lookup(mp, &fcmp->fc_export, nam);
|
||||
if (np == NULL)
|
||||
return (EACCES);
|
||||
|
||||
if ((error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) != 0) {
|
||||
*vpp = NULLVP;
|
||||
return (error);
|
||||
}
|
||||
ip = VTOI(nvp);
|
||||
if (filecore_staleinode(ip)) {
|
||||
vput(nvp);
|
||||
*vpp = NULLVP;
|
||||
return (ESTALE);
|
||||
} *vpp = nvp;
|
||||
*exflagsp = np->netc_exflags;
|
||||
*credanonp = &np->netc_anon;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* This looks complicated. Look at other vgets as well as the iso9660 one.
|
||||
|
||||
The filecore inode number is made up of 1 byte directory entry index and
|
||||
3 bytes of the internal disc address of the directory. On a read-only
|
||||
filesystem this is unique. For a read-write version we may not be able to
|
||||
do vget, see msdosfs.
|
||||
*/
|
||||
|
||||
int
|
||||
filecore_vget(mp, ino, vpp)
|
||||
struct mount *mp;
|
||||
ino_t ino;
|
||||
struct vnode **vpp;
|
||||
{
|
||||
register struct filecore_mnt *fcmp;
|
||||
struct filecore_node *ip;
|
||||
struct buf *bp;
|
||||
struct vnode *vp;
|
||||
dev_t dev;
|
||||
int error;
|
||||
|
||||
fcmp = VFSTOFILECORE(mp);
|
||||
dev = fcmp->fc_dev;
|
||||
if ((*vpp = filecore_ihashget(dev, ino)) != NULLVP)
|
||||
return (0);
|
||||
|
||||
/* Allocate a new vnode/filecore_node. */
|
||||
if ((error=getnewvnode(VT_FILECORE,mp,filecore_vnodeop_p,&vp)) != 0) {
|
||||
*vpp = NULLVP;
|
||||
return (error);
|
||||
}
|
||||
MALLOC(ip, struct filecore_node *, sizeof(struct filecore_node),
|
||||
M_FILECORENODE, M_WAITOK);
|
||||
memset((caddr_t)ip, 0, sizeof(struct filecore_node));
|
||||
lockinit(&ip->i_lock, PINOD, "filecorenode", 0, 0);
|
||||
vp->v_data = ip;
|
||||
ip->i_vnode = vp;
|
||||
ip->i_dev = dev;
|
||||
ip->i_number = ino;
|
||||
ip->i_block = -1;
|
||||
ip->i_parent = -2;
|
||||
|
||||
/*
|
||||
* Put it onto its hash chain and lock it so that other requests for
|
||||
* this inode will block if they arrive while we are sleeping waiting
|
||||
* for old data structures to be purged or for the contents of the
|
||||
* disk portion of this inode to be read.
|
||||
*/
|
||||
filecore_ihashins(ip);
|
||||
|
||||
if (ino==FILECORE_ROOTINO) {
|
||||
/* Here we need to construct a root directory inode */
|
||||
memcpy((caddr_t)ip->i_dirent.name,(caddr_t)"root",4);
|
||||
ip->i_dirent.load=0;
|
||||
ip->i_dirent.exec=0;
|
||||
ip->i_dirent.len=FILECORE_DIR_SIZE;
|
||||
ip->i_dirent.addr=fcmp->drec.root;
|
||||
ip->i_dirent.attr=FILECORE_ATTR_DIR | FILECORE_ATTR_READ;
|
||||
|
||||
} else {
|
||||
/* Read in Data from Directory Entry */
|
||||
if ((error=filecore_bread(fcmp, ino & FILECORE_INO_MASK,
|
||||
FILECORE_DIR_SIZE, NOCRED, &bp)) != 0) {
|
||||
vput(vp);
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) vf4\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
*vpp = NULL;
|
||||
return (error);
|
||||
}
|
||||
|
||||
memcpy((caddr_t)&ip->i_dirent,
|
||||
(caddr_t)fcdirentry(bp->b_data, ino>>FILECORE_INO_INDEX),
|
||||
sizeof(struct filecore_direntry));
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) vf5\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
}
|
||||
|
||||
ip->i_mnt = fcmp;
|
||||
ip->i_devvp = fcmp->fc_devvp;
|
||||
ip->i_diroff = 0;
|
||||
VREF(ip->i_devvp);
|
||||
|
||||
/*
|
||||
* Setup type
|
||||
*/
|
||||
vp->v_type = VREG;
|
||||
if (ip->i_dirent.attr & FILECORE_ATTR_DIR) vp->v_type = VDIR;
|
||||
|
||||
/*
|
||||
* Initialize the associated vnode
|
||||
*/
|
||||
switch (vp->v_type) {
|
||||
case VFIFO:
|
||||
case VCHR:
|
||||
case VBLK:
|
||||
/*
|
||||
* Devices not supported.
|
||||
*/
|
||||
vput(vp);
|
||||
return (EOPNOTSUPP);
|
||||
case VLNK:
|
||||
case VNON:
|
||||
case VSOCK:
|
||||
case VDIR:
|
||||
case VBAD:
|
||||
case VREG:
|
||||
break;
|
||||
}
|
||||
|
||||
if (ino == FILECORE_ROOTINO)
|
||||
vp->v_flag |= VROOT;
|
||||
|
||||
/*
|
||||
* XXX need generation number?
|
||||
*/
|
||||
|
||||
*vpp = vp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode pointer to File handle
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
filecore_vptofh(vp, fhp)
|
||||
struct vnode *vp;
|
||||
struct fid *fhp;
|
||||
{
|
||||
register struct filecore_node *ip = VTOI(vp);
|
||||
register struct ifid *ifhp;
|
||||
|
||||
ifhp = (struct ifid *)fhp;
|
||||
ifhp->ifid_len = sizeof(struct ifid);
|
||||
ifhp->ifid_ino = ip->i_number;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
filecore_sysctl(name, namelen, oldp, oldlenp, newp, newlen, p)
|
||||
int *name;
|
||||
u_int namelen;
|
||||
void *oldp;
|
||||
size_t *oldlenp;
|
||||
void *newp;
|
||||
size_t newlen;
|
||||
struct proc *p;
|
||||
{
|
||||
return (EOPNOTSUPP);
|
||||
}
|
616
sys/filecorefs/filecore_vnops.c
Normal file
616
sys/filecorefs/filecore_vnops.c
Normal file
@ -0,0 +1,616 @@
|
||||
/* $NetBSD: filecore_vnops.c,v 1.1 1998/08/14 03:26:13 mark Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 1998 Andrew McMurry
|
||||
* Copyright (c) 1994 The Regents of the University of California.
|
||||
* 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 the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
|
||||
*
|
||||
* filecore_vnops.c 1.1 1998/6/26
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/namei.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/conf.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/vnode.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/dirent.h>
|
||||
|
||||
#include <miscfs/genfs/genfs.h>
|
||||
#include <miscfs/specfs/specdev.h>
|
||||
|
||||
#include <filecorefs/filecore.h>
|
||||
#include <filecorefs/filecore_extern.h>
|
||||
#include <filecorefs/filecore_node.h>
|
||||
|
||||
/*
|
||||
* Check mode permission on inode pointer. Mode is READ, WRITE or EXEC.
|
||||
* The mode is shifted to select the owner/group/other fields. The
|
||||
* super user is granted all permissions.
|
||||
*/
|
||||
int
|
||||
filecore_access(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_access_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_mode;
|
||||
struct ucred *a_cred;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct filecore_node *ip = VTOI(vp);
|
||||
struct filecore_mnt *fcmp = ip->i_mnt;
|
||||
|
||||
/*
|
||||
* Disallow write attempts unless the file is a socket,
|
||||
* fifo, or a block or character device resident on the
|
||||
* file system.
|
||||
*/
|
||||
if (ap->a_mode & VWRITE) {
|
||||
switch (vp->v_type) {
|
||||
case VDIR:
|
||||
case VLNK:
|
||||
case VREG:
|
||||
return (EROFS);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return (vaccess(vp->v_type, filecore_mode(ip),
|
||||
fcmp->fc_uid, fcmp->fc_gid, ap->a_mode, ap->a_cred));
|
||||
}
|
||||
|
||||
int
|
||||
filecore_getattr(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_getattr_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct vattr *a_vap;
|
||||
struct ucred *a_cred;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
struct filecore_node *ip = VTOI(vp);
|
||||
register struct vattr *vap = ap->a_vap;
|
||||
struct filecore_mnt *fcmp = ip->i_mnt;
|
||||
|
||||
vap->va_fsid = ip->i_dev;
|
||||
vap->va_fileid = ip->i_number;
|
||||
|
||||
vap->va_mode = filecore_mode(ip);
|
||||
vap->va_nlink = 1;
|
||||
vap->va_uid = fcmp->fc_uid;
|
||||
vap->va_gid = fcmp->fc_gid;
|
||||
vap->va_atime = filecore_time(ip);
|
||||
vap->va_mtime = filecore_time(ip);
|
||||
vap->va_ctime = filecore_time(ip);
|
||||
vap->va_rdev = 0; /* We don't support specials */
|
||||
|
||||
vap->va_size = (u_quad_t) ip->i_size;
|
||||
vap->va_flags = 0;
|
||||
vap->va_gen = 1;
|
||||
vap->va_blocksize = fcmp->blksize;
|
||||
vap->va_bytes = vap->va_size;
|
||||
vap->va_type = vp->v_type;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode op for reading.
|
||||
*/
|
||||
int
|
||||
filecore_read(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_read_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
int a_ioflag;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap = v;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
register struct uio *uio = ap->a_uio;
|
||||
register struct filecore_node *ip = VTOI(vp);
|
||||
register struct filecore_mnt *fcmp;
|
||||
struct buf *bp;
|
||||
daddr_t lbn, rablock;
|
||||
off_t diff;
|
||||
int rasize, error = 0;
|
||||
long size, n, on;
|
||||
|
||||
if (uio->uio_resid == 0)
|
||||
return (0);
|
||||
if (uio->uio_offset < 0)
|
||||
return (EINVAL);
|
||||
ip->i_flag |= IN_ACCESS;
|
||||
fcmp = ip->i_mnt;
|
||||
do {
|
||||
lbn = lblkno(fcmp, uio->uio_offset);
|
||||
on = blkoff(fcmp, uio->uio_offset);
|
||||
n = min((u_int)(blksize(fcmp, ip, lbn) - on),
|
||||
uio->uio_resid);
|
||||
diff = (off_t)ip->i_size - uio->uio_offset;
|
||||
if (diff <= 0)
|
||||
return (0);
|
||||
if (diff < n)
|
||||
n = diff;
|
||||
size = blksize(fcmp, ip, lbn);
|
||||
rablock = lbn + 1;
|
||||
if (ip->i_dirent.attr & FILECORE_ATTR_DIR) {
|
||||
error = filecore_dbread(ip, &bp);
|
||||
on = uio->uio_offset;
|
||||
n = min(FILECORE_DIR_SIZE-on, uio->uio_resid);
|
||||
size = FILECORE_DIR_SIZE;
|
||||
} else {
|
||||
if (vp->v_lastr + 1 == lbn &&
|
||||
lblktosize(fcmp, rablock) < ip->i_size) {
|
||||
rasize = blksize(fcmp, ip, rablock);
|
||||
error = breadn(vp, lbn, size, &rablock,
|
||||
&rasize, 1, NOCRED, &bp);
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("breadn(%p, %x, %ld, CRED, %p)=%d\n",vp,
|
||||
lbn, size, bp, error);
|
||||
#endif
|
||||
} else {
|
||||
error = bread(vp, lbn, size, NOCRED, &bp);
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("bread(%p, %x, %ld, CRED, %p)=%d\n",vp, lbn, size,
|
||||
bp, error);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
vp->v_lastr = lbn;
|
||||
n = min(n, size - bp->b_resid);
|
||||
if (error) {
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) vn1\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
return (error);
|
||||
}
|
||||
|
||||
error = uiomove(bp->b_data + on, (int)n, uio);
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) vn2\n",bp);
|
||||
#endif
|
||||
brelse(bp);
|
||||
} while (error == 0 && uio->uio_resid > 0 && n != 0);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mmap a file
|
||||
*
|
||||
* NB Currently unsupported.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
filecore_mmap(v)
|
||||
void *v;
|
||||
{
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Vnode op for readdir
|
||||
*/
|
||||
int
|
||||
filecore_readdir(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_readdir_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
struct ucred *a_cred;
|
||||
int *a_eofflag;
|
||||
off_t **a_cookies;
|
||||
int *a_ncookies;
|
||||
} */ *ap = v;
|
||||
register struct uio *uio = ap->a_uio;
|
||||
struct vnode *vdp = ap->a_vp;
|
||||
struct filecore_node *dp;
|
||||
struct filecore_mnt *fcmp;
|
||||
struct buf *bp = NULL;
|
||||
struct dirent de;
|
||||
struct filecore_direntry *dep = NULL;
|
||||
int error = 0;
|
||||
off_t *cookies = NULL;
|
||||
int ncookies = 0;
|
||||
int nent, i;
|
||||
|
||||
dp = VTOI(vdp);
|
||||
|
||||
if ((dp->i_dirent.attr & FILECORE_ATTR_DIR) == 0)
|
||||
return (ENOTDIR);
|
||||
|
||||
if (uio->uio_offset % FILECORE_DIRENT_SIZE !=0 ||
|
||||
uio->uio_resid < FILECORE_DIRENT_SIZE)
|
||||
return (EINVAL);
|
||||
nent=uio->uio_resid / FILECORE_DIRENT_SIZE;
|
||||
i=uio->uio_offset / FILECORE_DIRENT_SIZE;
|
||||
uio->uio_resid=nent * FILECORE_DIRENT_SIZE;
|
||||
|
||||
fcmp = dp->i_mnt;
|
||||
|
||||
error = filecore_dbread(dp, &bp);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
if (ap->a_ncookies == NULL)
|
||||
cookies = NULL;
|
||||
else {
|
||||
ncookies = nent;
|
||||
MALLOC(cookies, off_t *, ncookies * sizeof(off_t), M_TEMP,
|
||||
M_WAITOK);
|
||||
}
|
||||
|
||||
nent+=i;
|
||||
for (; i<nent; i++) {
|
||||
switch (i) {
|
||||
case 0:
|
||||
/* Fake the '.' entry */
|
||||
de.d_fileno = dp->i_number;
|
||||
de.d_type = DT_DIR;
|
||||
de.d_namlen = 1;
|
||||
strcpy(de.d_name, ".");
|
||||
break;
|
||||
case 1:
|
||||
/* Fake the '..' entry */
|
||||
de.d_fileno = filecore_getparent(dp);
|
||||
de.d_type = DT_DIR;
|
||||
de.d_namlen = 2;
|
||||
strcpy(de.d_name, "..");
|
||||
break;
|
||||
default:
|
||||
de.d_fileno = dp->i_dirent.addr +
|
||||
((i-2)<<FILECORE_INO_INDEX);
|
||||
dep = fcdirentry(bp->b_data, i-2);
|
||||
if (dep->attr & FILECORE_ATTR_DIR)
|
||||
de.d_type = DT_DIR;
|
||||
else
|
||||
de.d_type = DT_REG;
|
||||
if (filecore_fn2unix(dep->name, de.d_name,
|
||||
&de.d_namlen))
|
||||
goto out;
|
||||
break;
|
||||
}
|
||||
de.d_reclen = DIRENT_SIZE(&de);
|
||||
if (uio->uio_resid < de.d_reclen)
|
||||
goto out;
|
||||
error = uiomove((caddr_t) &de, de.d_reclen, uio);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
if (cookies) {
|
||||
*cookies++ = i*FILECORE_DIRENT_SIZE;
|
||||
(*ap->a_ncookies)++;
|
||||
}
|
||||
}
|
||||
out:
|
||||
if (ap->a_ncookies) {
|
||||
if (error) {
|
||||
FREE(cookies, M_TEMP);
|
||||
*ap->a_ncookies = 0;
|
||||
*ap->a_cookies = NULL;
|
||||
}
|
||||
}
|
||||
if (dep != NULL && dep->name[0]==0)
|
||||
*ap->a_eofflag = 1;
|
||||
else
|
||||
*ap->a_eofflag = 0;
|
||||
|
||||
#ifdef FILECORE_DEBUG_BR
|
||||
printf("brelse(%p) vn3\n",bp);
|
||||
#endif
|
||||
brelse (bp);
|
||||
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return target name of a symbolic link
|
||||
* Shouldn't we get the parent vnode and read the data from there?
|
||||
* This could eventually result in deadlocks in filecore_lookup.
|
||||
* But otherwise the block read here is in the block buffer two times.
|
||||
*/
|
||||
int
|
||||
filecore_readlink(v)
|
||||
void *v;
|
||||
{
|
||||
#if 0
|
||||
struct vop_readlink_args /* {
|
||||
struct vnode *a_vp;
|
||||
struct uio *a_uio;
|
||||
struct ucred *a_cred;
|
||||
} */ *ap = v;
|
||||
#endif
|
||||
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
int
|
||||
filecore_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
|
||||
filecore_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 an inode.
|
||||
*/
|
||||
int
|
||||
filecore_lock(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_lock_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_flags;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
register struct vnode *vp = ap->a_vp;
|
||||
|
||||
return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags, &vp->v_interlock));
|
||||
}
|
||||
|
||||
/*
|
||||
* Unlock an inode.
|
||||
*/
|
||||
int
|
||||
filecore_unlock(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_unlock_args /* {
|
||||
struct vnode *a_vp;
|
||||
int a_flags;
|
||||
struct proc *a_p;
|
||||
} */ *ap = v;
|
||||
struct vnode *vp = ap->a_vp;
|
||||
|
||||
return (lockmgr(&VTOI(vp)->i_lock, ap->a_flags | LK_RELEASE,
|
||||
&vp->v_interlock));
|
||||
}
|
||||
|
||||
/*
|
||||
* Calculate the logical to physical mapping if not done already,
|
||||
* then call the device strategy routine.
|
||||
*/
|
||||
int
|
||||
filecore_strategy(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_strategy_args /* {
|
||||
struct buf *a_bp;
|
||||
} */ *ap = v;
|
||||
register struct buf *bp = ap->a_bp;
|
||||
register struct vnode *vp = bp->b_vp;
|
||||
register struct filecore_node *ip;
|
||||
int error;
|
||||
|
||||
ip = VTOI(vp);
|
||||
if (bp->b_blkno == bp->b_lblkno) {
|
||||
error = VOP_BMAP(vp, bp->b_lblkno, NULL, &bp->b_blkno, NULL);
|
||||
if (error) {
|
||||
bp->b_error = error;
|
||||
bp->b_flags |= B_ERROR;
|
||||
biodone(bp);
|
||||
return (error);
|
||||
}
|
||||
if ((long)bp->b_blkno == -1)
|
||||
clrbuf(bp);
|
||||
}
|
||||
if ((long)bp->b_blkno == -1) {
|
||||
biodone(bp);
|
||||
return (0);
|
||||
}
|
||||
vp = ip->i_devvp;
|
||||
bp->b_dev = vp->v_rdev;
|
||||
VOCALL (vp->v_op, VOFFSET(vop_strategy), ap);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print out the contents of an inode.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
int
|
||||
filecore_print(v)
|
||||
void *v;
|
||||
{
|
||||
|
||||
printf("tag VT_FILECORE, filecore vnode\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for a locked inode.
|
||||
*/
|
||||
int
|
||||
filecore_islocked(v)
|
||||
void *v;
|
||||
{
|
||||
struct vop_islocked_args /* {
|
||||
struct vnode *a_vp;
|
||||
} */ *ap = v;
|
||||
|
||||
return (lockstatus(&VTOI(ap->a_vp)->i_lock));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return POSIX pathconf information applicable to filecore filesystems.
|
||||
*/
|
||||
int
|
||||
filecore_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_LINK_MAX:
|
||||
*ap->a_retval = 1;
|
||||
return (0);
|
||||
case _PC_NAME_MAX:
|
||||
*ap->a_retval = 10;
|
||||
return (0);
|
||||
case _PC_PATH_MAX:
|
||||
*ap->a_retval = 256;
|
||||
return (0);
|
||||
case _PC_CHOWN_RESTRICTED:
|
||||
*ap->a_retval = 1;
|
||||
return (0);
|
||||
case _PC_NO_TRUNC:
|
||||
*ap->a_retval = 1;
|
||||
return (0);
|
||||
default:
|
||||
return (EINVAL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/*
|
||||
* Global vfs data structures for isofs
|
||||
*/
|
||||
#define filecore_create genfs_eopnotsupp
|
||||
#define filecore_mknod genfs_eopnotsupp
|
||||
#define filecore_write genfs_eopnotsupp
|
||||
#define filecore_setattr genfs_eopnotsupp
|
||||
#ifdef NFSSERVER
|
||||
int lease_check __P((void *));
|
||||
#define filecore_lease_check lease_check
|
||||
#else
|
||||
#define filecore_lease_check genfs_nullop
|
||||
#endif
|
||||
#define filecore_ioctl genfs_enoioctl
|
||||
#define filecore_fsync genfs_nullop
|
||||
#define filecore_remove genfs_eopnotsupp
|
||||
#define filecore_rename genfs_eopnotsupp
|
||||
#define filecore_mkdir genfs_eopnotsupp
|
||||
#define filecore_rmdir genfs_eopnotsupp
|
||||
#define filecore_advlock genfs_eopnotsupp
|
||||
#define filecore_valloc genfs_eopnotsupp
|
||||
#define filecore_vfree genfs_nullop
|
||||
#define filecore_truncate genfs_eopnotsupp
|
||||
#define filecore_update genfs_nullop
|
||||
#define filecore_bwrite genfs_eopnotsupp
|
||||
#define filecore_revoke genfs_revoke
|
||||
#define filecore_blkatoff genfs_eopnotsupp
|
||||
|
||||
/*
|
||||
* Global vfs data structures for filecore
|
||||
*/
|
||||
int (**filecore_vnodeop_p) __P((void *));
|
||||
struct vnodeopv_entry_desc filecore_vnodeop_entries[] = {
|
||||
{ &vop_default_desc, vn_default_error },
|
||||
{ &vop_lookup_desc, filecore_lookup }, /* lookup */
|
||||
{ &vop_create_desc, filecore_create }, /* create */
|
||||
{ &vop_mknod_desc, filecore_mknod }, /* mknod */
|
||||
{ &vop_open_desc, filecore_open }, /* open */
|
||||
{ &vop_close_desc, filecore_close }, /* close */
|
||||
{ &vop_access_desc, filecore_access }, /* access */
|
||||
{ &vop_getattr_desc, filecore_getattr }, /* getattr */
|
||||
{ &vop_setattr_desc, filecore_setattr }, /* setattr */
|
||||
{ &vop_read_desc, filecore_read }, /* read */
|
||||
{ &vop_write_desc, filecore_write }, /* write */
|
||||
{ &vop_lease_desc, filecore_lease_check }, /* lease */
|
||||
{ &vop_ioctl_desc, filecore_ioctl }, /* ioctl */
|
||||
{ &vop_poll_desc, filecore_poll }, /* poll */
|
||||
{ &vop_revoke_desc, filecore_revoke }, /* revoke */
|
||||
{ &vop_mmap_desc, filecore_mmap }, /* mmap */
|
||||
{ &vop_fsync_desc, filecore_fsync }, /* fsync */
|
||||
{ &vop_seek_desc, filecore_seek }, /* seek */
|
||||
{ &vop_remove_desc, filecore_remove }, /* remove */
|
||||
{ &vop_link_desc, filecore_link }, /* link */
|
||||
{ &vop_rename_desc, filecore_rename }, /* rename */
|
||||
{ &vop_mkdir_desc, filecore_mkdir }, /* mkdir */
|
||||
{ &vop_rmdir_desc, filecore_rmdir }, /* rmdir */
|
||||
{ &vop_symlink_desc, filecore_symlink }, /* symlink */
|
||||
{ &vop_readdir_desc, filecore_readdir }, /* readdir */
|
||||
{ &vop_readlink_desc, filecore_readlink }, /* readlink */
|
||||
{ &vop_abortop_desc, filecore_abortop }, /* abortop */
|
||||
{ &vop_inactive_desc, filecore_inactive }, /* inactive */
|
||||
{ &vop_reclaim_desc, filecore_reclaim }, /* reclaim */
|
||||
{ &vop_lock_desc, filecore_lock }, /* lock */
|
||||
{ &vop_unlock_desc, filecore_unlock }, /* unlock */
|
||||
{ &vop_bmap_desc, filecore_bmap }, /* bmap */
|
||||
{ &vop_strategy_desc, filecore_strategy }, /* strategy */
|
||||
{ &vop_print_desc, filecore_print }, /* print */
|
||||
{ &vop_islocked_desc, filecore_islocked }, /* islocked */
|
||||
{ &vop_pathconf_desc, filecore_pathconf }, /* pathconf */
|
||||
{ &vop_advlock_desc, filecore_advlock }, /* advlock */
|
||||
{ &vop_blkatoff_desc, filecore_blkatoff }, /* blkatoff */
|
||||
{ &vop_valloc_desc, filecore_valloc }, /* valloc */
|
||||
{ &vop_vfree_desc, filecore_vfree }, /* vfree */
|
||||
{ &vop_truncate_desc, filecore_truncate }, /* truncate */
|
||||
{ &vop_update_desc, filecore_update }, /* update */
|
||||
{ &vop_bwrite_desc, vn_bwrite }, /* bwrite */
|
||||
{ (struct vnodeop_desc*)NULL, (int(*) __P((void *)))NULL }
|
||||
};
|
||||
struct vnodeopv_desc filecore_vnodeop_opv_desc =
|
||||
{ &filecore_vnodeop_p, filecore_vnodeop_entries };
|
Loading…
Reference in New Issue
Block a user