This is the kernel Lite/2 commit. There are some requisite userland

changes, so don't expect to be able to run the kernel as-is (very well)
without the appropriate Lite/2 userland changes.

The system boots and can mount UFS filesystems.

Untested: ext2fs, msdosfs, NFS
Known problems: Incorrect Berkeley ID strings in some files.
		Mount_std mounts will not work until the getfsent
		library routine is changed.

Reviewed by:	various people
Submitted by:	Jeffery Hsu <hsu@freebsd.org>
This commit is contained in:
John Dyson 1997-02-10 02:22:35 +00:00
parent d243e2f7f4
commit 996c772f58
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=22521
302 changed files with 13597 additions and 9927 deletions

View File

@ -53,6 +53,7 @@
#include <sys/reboot.h>
#include <sys/kernel.h>
#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/sysctl.h>
#include <machine/bootinfo.h>
@ -88,31 +89,15 @@
static void configure __P((void *));
SYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure, NULL)
#ifdef MFS_ROOT
extern struct vfsops mfs_vfsops;
#endif
#ifdef FFS
extern struct vfsops ufs_vfsops;
#endif
#ifdef LFS
extern struct vfsops lfs_vfsops;
#endif
#ifdef NFS
extern int nfs_mountroot __P((void *));
#endif
#ifdef CD9660
extern int cd9660_mountroot __P((void *));
#endif
#ifdef MSDOSFS
extern int msdosfs_mountroot __P((void *));
#endif
static void configure_finish __P((void));
static void configure_start __P((void));
static int setdumpdev __P((dev_t dev));
static void setroot __P((void));
#ifdef CD9660
#include <isofs/cd9660/iso.h>
/* We need to try out all our potential CDROM drives, so we need a table. */
static struct {
char *name;
@ -138,7 +123,7 @@ find_cdrom_root(dummy)
rootdev = makedev(try_cdrom[k].major,j*8);
printf("trying rootdev=0x%lx (%s%d)\n",
rootdev, try_cdrom[k].name,j);
i = (*cd9660_mountroot)((void *)NULL);
i = (*cd9660_mountroot)();
if (!i) return i;
}
return EINVAL;
@ -176,6 +161,11 @@ configure(dummy)
enable_intr();
INTREN(IRQ_SLAVE);
#if NCRD > 0
/* Before isa_configure to avoid ISA drivers finding our cards */
pccard_configure();
#endif
#if NEISA > 0
eisa_configure();
#endif
@ -188,11 +178,6 @@ configure(dummy)
isa_configure();
#endif
#if NCRD > 0
/* After everyone else has a chance at grabbing resources */
pccard_configure();
#endif
if (setdumpdev(dumpdev) != 0)
dumpdev = NODEV;
@ -235,19 +220,26 @@ configure(dummy)
}
#ifdef CD9660
if ((boothowto & RB_CDROM) && !mountroot) {
if ((boothowto & RB_CDROM)) {
if (bootverbose)
printf("Considering CD-ROM root f/s.\n");
mountroot = find_cdrom_root;
mountrootfsname = "cd9660";
}
#endif
#ifdef NFS
if (!mountrootfsname && nfs_diskless_valid) {
if (bootverbose)
printf("Considering NFS root f/s.\n");
mountrootfsname = "nfs";
}
#endif /* NFS */
#ifdef MFS_ROOT
if (!mountroot) {
if (!mountrootfsname) {
if (bootverbose)
printf("Considering MFS root f/s.\n");
mountroot = vfs_mountroot; /* XXX goes away*/
mountrootvfsops = &mfs_vfsops;
mountrootfsname = "mfs";
/*
* Ignore the -a flag if this kernel isn't compiled
* with a generic root/swap configuration: if we skip
@ -260,21 +252,11 @@ configure(dummy)
setroot();
}
#endif
#ifdef NFS
if (!mountroot && nfs_diskless_valid) {
if (bootverbose)
printf("Considering NFS root f/s.\n");
mountroot = nfs_mountroot;
}
#endif /* NFS */
#ifdef FFS
if (!mountroot) {
if (!mountrootfsname) {
mountrootfsname = "ufs";
if (bootverbose)
printf("Considering FFS root f/s.\n");
mountroot = vfs_mountroot; /* XXX goes away*/
mountrootvfsops = &ufs_vfsops;
/*
* Ignore the -a flag if this kernel isn't compiled
* with a generic root/swap configuration: if we skip
@ -288,11 +270,10 @@ configure(dummy)
}
#endif
#ifdef LFS
if (!mountroot) {
if (!mountrootfsname) {
if (bootverbose)
printf("Considering LFS root f/s.\n");
mountroot = vfs_mountroot; /* XXX goes away*/
mountrootvfsops = &lfs_vfsops;
mountrootfsname = "lfs";
/*
* Ignore the -a flag if this kernel isn't compiled
* with a generic root/swap configuration: if we skip
@ -305,8 +286,7 @@ configure(dummy)
setroot();
}
#endif
if (!mountroot) {
if (!mountrootfsname) {
panic("Nobody wants to mount my root for me");
}
@ -417,4 +397,4 @@ sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS
}
SYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW,
0, sizeof dumpdev, sysctl_kern_dumpdev, "T,dev_t", "");
0, sizeof dumpdev, sysctl_kern_dumpdev, "I", "");

View File

@ -34,7 +34,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_prot.h>
#include <vm/pmap.h>
#include <ddb/ddb.h>

View File

@ -61,13 +61,15 @@
#include <sys/vmmeter.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <sys/user.h>
#include <net/if.h>
#include <netinet/in.h>
#include <nfs/nfsv2.h>
#include <nfs/rpcv2.h>
#include <nfs/nfs.h>
#include <nfs/nfsdiskless.h>
extern int main __P((void));

View File

@ -82,7 +82,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_kern.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>

View File

@ -68,7 +68,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_prot.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>

View File

@ -85,7 +85,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>

View File

@ -44,7 +44,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_extern.h>

View File

@ -61,7 +61,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_kern.h>
#include <vm/vm_map.h>

View File

@ -58,7 +58,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>

View File

@ -450,7 +450,7 @@ linux_getdents(struct proc *p, struct linux_getdents_args *args, int *retval)
buflen = max(DIRBLKSIZ, nbytes + blockoff);
buflen = min(buflen, MAXBSIZE);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
again:
aiov.iov_base = buf;
aiov.iov_len = buflen;
@ -530,7 +530,7 @@ linux_getdents(struct proc *p, struct linux_getdents_args *args, int *retval)
eof:
*retval = nbytes - resid;
out:
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, p);
free(buf, M_TEMP);
return error;
}

View File

@ -237,7 +237,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval)
/*
* Lock no longer needed
*/
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, p);
locked = 0;
/*
@ -392,7 +392,7 @@ printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]);
* Unlock vnode if needed
*/
if (locked)
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, p);
/*
* Release the kernel mapping.

View File

@ -52,6 +52,7 @@ kern/kern_exit.c standard
kern/kern_fork.c standard
kern/kern_ktrace.c standard
kern/kern_lkm.c standard
kern/kern_lock.c standard
kern/kern_lockf.c standard
kern/kern_malloc.c standard
kern/kern_mib.c standard
@ -373,7 +374,6 @@ ufs/ufs/ufs_vfsops.c standard
ufs/ufs/ufs_vnops.c standard
vm/default_pager.c standard
vm/device_pager.c standard
vm/kern_lock.c standard
vm/swap_pager.c standard
vm/vm_fault.c standard
vm/vm_glue.c standard

View File

@ -35,7 +35,7 @@
#include <sys/systm.h>
#include <vm/vm.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_prot.h>

View File

@ -277,7 +277,7 @@ static d_strategy_t fdstrategy;
static struct cdevsw fd_cdevsw;
static struct bdevsw fd_bdevsw =
{ Fdopen, fdclose, fdstrategy, fdioctl, /*2*/
nodump, nopsize, 0, "fd", &fd_cdevsw, -1 };
nodump, nopsize, D_DISK, "fd", &fd_cdevsw, -1 };
static struct isa_device *fdcdevs[NFDC];

View File

@ -457,11 +457,11 @@ vnioctl(dev_t dev, int cmd, caddr_t data, int flag, struct proc *p)
return(error);
error = VOP_GETATTR(nd.ni_vp, &vattr, p->p_ucred, p);
if (error) {
VOP_UNLOCK(nd.ni_vp);
VOP_UNLOCK(nd.ni_vp, 0, p);
(void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
return(error);
}
VOP_UNLOCK(nd.ni_vp);
VOP_UNLOCK(nd.ni_vp, 0, p);
vn->sc_vp = nd.ni_vp;
vn->sc_size = btodb(vattr.va_size); /* note truncation */
error = vnsetcred(vn, p->p_ucred);

View File

@ -25,16 +25,6 @@
There is some preliminary stuff in there that (ab-)uses the mknod
system call, but this needs a writable filesystem
3) should be called cdfs, as there are other ISO file system soon possible
Not yet. Probably we should make another file system when the ECMA draft
is valid and do it. For doing Rock Ridge Support, I can use almost same
code. So I just use the same file system interface...
4) should have file handles implemented for use with NFS, etc
Yes. we have already this one, and I based it for this release.
5) should have name translation enabled by mount flag
Yes. we can disable the Rock Ridge Extension by follows option;
@ -57,23 +47,3 @@
clean. As far as I know, if you export the cdrom by NFS, the client
can access the 8 bit clean (ie. Solaris Japanese with EUC code )
9) Access checks in isofs_access
Not yet.
10) Support for generation numbers
Yes. Default is to list only the last file (the one with the highest
generation number). If you mount with -gen, all files are shown with
their generation numbers. In both cases you can specify the generation
number on opening files (if you happen to know it) or leave it off,
when it will again find the last file.
11) Support for extended attributes
Yes. Since this requires an extra block buffer for the attributes
this must be enabled on mounting with the option -extattr.
----------
Last update July 19, '93 by Atsushi Murai. (amurai@spec.co.jp)
Last update August 19, '93 by Wolfgang Solfrank. (ws@tools.de)

View File

@ -67,7 +67,7 @@ cd9660_bmap(ap)
{
struct iso_node *ip = VTOI(ap->a_vp);
daddr_t lblkno = ap->a_bn;
long bsize;
int bshift;
/*
* Check for underlying vnode requests and ensure that logical
@ -81,8 +81,8 @@ cd9660_bmap(ap)
/*
* Compute the requested block number
*/
bsize = ip->i_mnt->logical_block_size;
*ap->a_bnp = (ip->iso_start + lblkno) * btodb(bsize);
bshift = ip->i_mnt->im_bshift;
*ap->a_bnp = (ip->iso_start + lblkno) << (bshift - DEV_BSHIFT);
/*
* Determine maximum number of readahead blocks following the
@ -91,11 +91,11 @@ cd9660_bmap(ap)
if (ap->a_runp) {
int nblk;
nblk = (ip->i_size - (lblkno + 1) * bsize) / bsize;
nblk = (ip->i_size >> bshift) - (lblkno + 1);
if (nblk <= 0)
*ap->a_runp = 0;
else if (nblk >= MAXBSIZE/bsize)
*ap->a_runp = MAXBSIZE/bsize - 1;
else if (nblk >= (MAXBSIZE >> bshift))
*ap->a_runp = (MAXBSIZE >> bshift) - 1;
else
*ap->a_runp = nblk;
}

View File

@ -108,8 +108,9 @@ cd9660_lookup(ap)
int saveoffset = 0; /* offset of last directory entry in dir */
int numdirpasses; /* strategy for directory search */
doff_t endsearch; /* offset to end directory search */
struct iso_node *pdp; /* saved dp during symlink work */
struct iso_node *tdp; /* returned by iget */
struct vnode *pdp; /* saved dp during symlink work */
struct vnode *tdp; /* returned by cd9660_vget_internal */
u_long bmask; /* block offset mask */
int lockparent; /* 1 => lockparent flag is set */
int wantparent; /* 1 => wantparent or lockparent flag */
int error;
@ -126,6 +127,7 @@ cd9660_lookup(ap)
struct ucred *cred = cnp->cn_cred;
int flags = cnp->cn_flags;
int nameiop = cnp->cn_nameiop;
struct proc *p = cnp->cn_proc;
bp = NULL;
*vpp = NULL;
@ -139,13 +141,13 @@ cd9660_lookup(ap)
* Check accessiblity of directory.
*/
if (vdp->v_type != VDIR)
return (ENOTDIR);
if ((error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc)))
return (ENOTDIR);
if (error = VOP_ACCESS(vdp, VEXEC, cred, cnp->cn_proc))
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.
*
@ -160,29 +162,29 @@ cd9660_lookup(ap)
return (error);
#ifdef PARANOID
if ((vdp->v_flag & VROOT) && (flags & ISDOTDOT))
panic("ufs_lookup: .. through root");
panic("cd9660_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 = dp;
pdp = vdp;
dp = VTOI(*vpp);
vdp = *vpp;
vpid = vdp->v_id;
if (pdp == dp) {
if (pdp == vdp) {
VREF(vdp);
error = 0;
} else if (flags & ISDOTDOT) {
ISO_IUNLOCK(pdp);
error = vget(vdp, 1);
VOP_UNLOCK(pdp, 0, p);
error = vget(vdp, LK_EXCLUSIVE, p);
if (!error && lockparent && (flags & ISLASTCN))
ISO_ILOCK(pdp);
error = vn_lock(pdp, LK_EXCLUSIVE, p);
} else {
error = vget(vdp, 1);
error = vget(vdp, LK_EXCLUSIVE, p);
if (!lockparent || error || !(flags & ISLASTCN))
ISO_IUNLOCK(pdp);
VOP_UNLOCK(pdp, 0, p);
}
/*
* Check that the capability number did not change
@ -191,13 +193,14 @@ cd9660_lookup(ap)
if (!error) {
if (vpid == vdp->v_id)
return (0);
iso_iput(dp);
if (lockparent && pdp != dp && (flags & ISLASTCN))
ISO_IUNLOCK(pdp);
vput(vdp);
if (lockparent && pdp != vdp && (flags & ISLASTCN))
VOP_UNLOCK(pdp, 0, p);
}
ISO_ILOCK(pdp);
dp = pdp;
vdp = ITOV(dp);
if (error = vn_lock(pdp, LK_EXCLUSIVE, p))
return (error);
vdp = pdp;
dp = VTOI(pdp);
*vpp = NULL;
}
@ -223,6 +226,7 @@ cd9660_lookup(ap)
* profiling time and hence has been removed in the interest
* of simplicity.
*/
bmask = imp->im_bmask;
if (nameiop != LOOKUP || dp->i_diroff == 0 ||
dp->i_diroff > dp->i_size) {
entryoffsetinblock = 0;
@ -230,16 +234,14 @@ cd9660_lookup(ap)
numdirpasses = 1;
} else {
dp->i_offset = dp->i_diroff;
entryoffsetinblock = iso_blkoff(imp, dp->i_offset);
if (entryoffsetinblock != 0) {
if ((error = iso_blkatoff(dp, dp->i_offset, &bp)))
if ((entryoffsetinblock = dp->i_offset & bmask) &&
(error = VOP_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp)))
return (error);
}
numdirpasses = 2;
iso_nchstats.ncs_2passes++;
}
endsearch = roundup(dp->i_size, imp->logical_block_size);
endsearch = dp->i_size;
searchloop:
while (dp->i_offset < endsearch) {
/*
@ -247,10 +249,11 @@ cd9660_lookup(ap)
* read the next directory block.
* Release previous if it exists.
*/
if (iso_blkoff(imp, dp->i_offset) == 0) {
if ((dp->i_offset & bmask) == 0) {
if (bp != NULL)
brelse(bp);
if ((error = iso_blkatoff(dp, dp->i_offset, &bp)))
if (error =
VOP_BLKATOFF(vdp, (off_t)dp->i_offset, NULL, &bp))
return (error);
entryoffsetinblock = 0;
}
@ -258,13 +261,13 @@ cd9660_lookup(ap)
* Get pointer to next entry.
*/
ep = (struct iso_directory_record *)
(bp->b_un.b_addr + entryoffsetinblock);
reclen = isonum_711 (ep->length);
((char *)bp->b_data + entryoffsetinblock);
reclen = isonum_711(ep->length);
if (reclen == 0) {
/* skip to next block, if any */
dp->i_offset =
roundup(dp->i_offset, imp->logical_block_size);
(dp->i_offset & ~bmask) + imp->logical_block_size;
continue;
}
@ -275,10 +278,7 @@ cd9660_lookup(ap)
if (entryoffsetinblock + reclen > imp->logical_block_size)
/* entries are not allowed to cross boundaries */
break;
/*
* Check for a name match.
*/
namelen = isonum_711(ep->name_len);
isoflags = isonum_711(imp->iso_ftype == ISO_FTYPE_HIGH_SIERRA?
&ep->date[6]: ep->flags);
@ -286,7 +286,10 @@ cd9660_lookup(ap)
if (reclen < ISO_DIRECTORY_RECORD_SIZE + namelen)
/* illegal entry, stop */
break;
/*
* Check for a name match.
*/
switch (imp->iso_ftype) {
default:
if (!(isoflags & 4) == !assoc) {
@ -297,10 +300,9 @@ cd9660_lookup(ap)
&& ep->name[0] == ((flags & ISDOTDOT) ? 1 : 0)) {
/*
* Save directory entry's inode number and
* reclen in ndp->ni_ufs area, and release
* directory buffer.
* release directory buffer.
*/
isodirino(&dp->i_ino,ep,imp);
dp->i_ino = isodirino(ep, imp);
goto found;
}
if (namelen != 1
@ -308,8 +310,8 @@ cd9660_lookup(ap)
goto notfound;
} else if (!(res = isofncmp(name,len,
ep->name,namelen))) {
if (isoflags & 2)
isodirino(&ino,ep,imp);
if (isonum_711(ep->flags)&2)
ino = isodirino(ep, imp);
else
ino = dbtob(bp->b_blkno)
+ entryoffsetinblock;
@ -326,7 +328,7 @@ cd9660_lookup(ap)
break;
case ISO_FTYPE_RRIP:
if (isonum_711(ep->flags)&2)
isodirino(&ino,ep,imp);
ino = isodirino(ep, imp);
else
ino = dbtob(bp->b_blkno) + entryoffsetinblock;
dp->i_ino = ino;
@ -344,15 +346,17 @@ cd9660_lookup(ap)
foundino:
dp->i_ino = ino;
if (saveoffset != dp->i_offset) {
if (iso_lblkno(imp,dp->i_offset)
!= iso_lblkno(imp,saveoffset)) {
if (lblkno(imp, dp->i_offset) !=
lblkno(imp, saveoffset)) {
if (bp != NULL)
brelse(bp);
if ((error = iso_blkatoff(dp, saveoffset, &bp)))
if (error = VOP_BLKATOFF(vdp,
(off_t)saveoffset, NULL, &bp))
return (error);
}
ep = (struct iso_directory_record *)(bp->b_un.b_addr
+ iso_blkoff(imp,saveoffset));
entryoffsetinblock = saveoffset & bmask;
ep = (struct iso_directory_record *)
((char *)bp->b_data + entryoffsetinblock);
dp->i_offset = saveoffset;
}
goto found;
@ -370,6 +374,7 @@ cd9660_lookup(ap)
}
if (bp != NULL)
brelse(bp);
/*
* Insert name into cache (as non-existent) if appropriate.
*/
@ -382,9 +387,7 @@ cd9660_lookup(ap)
found:
if (numdirpasses == 2)
iso_nchstats.ncs_pass2++;
if (bp != NULL)
brelse(bp);
/*
* Found component in pathname.
* If the final component of path name, save information
@ -412,31 +415,39 @@ cd9660_lookup(ap)
* work if the file system has any hard links other than ".."
* that point backwards in the directory structure.
*/
pdp = dp;
pdp = vdp;
/*
* If ino is different from dp->i_ino,
* it's a relocated directory.
*/
if (flags & ISDOTDOT) {
ISO_IUNLOCK(pdp); /* race to get the inode */
if ((error = iso_iget(dp,dp->i_ino,
dp->i_ino != ino,
&tdp,ep))) {
ISO_ILOCK(pdp);
VOP_UNLOCK(pdp, 0, p); /* race to get the inode */
error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp,
dp->i_ino != ino, ep);
brelse(bp);
if (error) {
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
}
if (lockparent && (flags & ISLASTCN))
ISO_ILOCK(pdp);
*vpp = ITOV(tdp);
if (lockparent && (flags & ISLASTCN) &&
(error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
vput(tdp);
return (error);
}
*vpp = tdp;
} else if (dp->i_number == dp->i_ino) {
brelse(bp);
VREF(vdp); /* we want ourself, ie "." */
*vpp = vdp;
} else {
if ((error = iso_iget(dp,dp->i_ino,dp->i_ino!=ino,&tdp,ep)))
error = cd9660_vget_internal(vdp->v_mount, dp->i_ino, &tdp,
dp->i_ino != ino, ep);
brelse(bp);
if (error)
return (error);
if (!lockparent || !(flags & ISLASTCN))
ISO_IUNLOCK(pdp);
*vpp = ITOV(tdp);
VOP_UNLOCK(pdp, 0, p);
*vpp = tdp;
}
/*
@ -448,29 +459,37 @@ cd9660_lookup(ap)
}
/*
* Return buffer with contents of block "offset"
* from the beginning of directory "ip". If "res"
* is non-zero, fill it in with a pointer to the
* Return buffer with the contents of block "offset" from the beginning of
* directory "ip". If "res" is non-zero, fill it in with a pointer to the
* remaining space in the directory.
*/
int
iso_blkatoff(ip, offset, bpp)
struct iso_node *ip;
doff_t offset;
struct buf **bpp;
cd9660_blkatoff(ap)
struct vop_blkatoff_args /* {
struct vnode *a_vp;
off_t a_offset;
char **a_res;
struct buf **a_bpp;
} */ *ap;
{
register struct iso_mnt *imp = ip->i_mnt;
daddr_t lbn = iso_lblkno(imp,offset);
int bsize = iso_blksize(imp,ip,lbn);
struct iso_node *ip;
register struct iso_mnt *imp;
struct buf *bp;
int error;
daddr_t lbn;
int bsize, error;
if ((error = bread(ITOV(ip),lbn,bsize,NOCRED,&bp))) {
ip = VTOI(ap->a_vp);
imp = ip->i_mnt;
lbn = lblkno(imp, ap->a_offset);
bsize = blksize(imp, ip, lbn);
if (error = bread(ap->a_vp, lbn, bsize, NOCRED, &bp)) {
brelse(bp);
*bpp = 0;
*ap->a_bpp = NULL;
return (error);
}
*bpp = bp;
if (ap->a_res)
*ap->a_res = (char *)bp->b_data + blkoff(imp, ap->a_offset);
*ap->a_bpp = bp;
return (0);
}

View File

@ -1,5 +1,5 @@
/*-
* Copyright (c) 1982, 1986, 1989, 1994
* Copyright (c) 1982, 1986, 1989, 1994, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley
@ -52,32 +52,21 @@
#include <isofs/cd9660/iso.h>
#include <isofs/cd9660/cd9660_node.h>
#include <isofs/cd9660/cd9660_mount.h>
#include <isofs/cd9660/iso_rrip.h>
#define INOHSZ 512
#if ((INOHSZ&(INOHSZ-1)) == 0)
#define INOHASH(dev,ino) (((dev)+((ino)>>12))&(INOHSZ-1))
#else
#define INOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%INOHSZ)
#endif
/*
* Structures associated with iso_node caching.
*/
struct iso_node **isohashtbl;
u_long isohash;
#define INOHASH(device, inum) (((device) + ((inum)>>12)) & isohash)
struct simplelock cd9660_ihash_slock;
union iso_ihead {
union iso_ihead *ih_head[2];
struct iso_node *ih_chain[2];
} iso_ihead[INOHSZ];
#ifdef ISODEVMAP
#define DNOHSZ 64
#if ((DNOHSZ&(DNOHSZ-1)) == 0)
#define DNOHASH(dev,ino) (((dev)+((ino)>>12))&(DNOHSZ-1))
#else
#define DNOHASH(dev,ino) (((unsigned)((dev)+((ino)>>12)))%DNOHSZ)
#endif
union iso_dhead {
union iso_dhead *dh_head[2];
struct iso_dnode *dh_chain[2];
} iso_dhead[DNOHSZ];
#ifdef ISODEVMAP
struct iso_node **idvhashtbl;
u_long idvhash;
#define DNOHASH(device, inum) (((device) + ((inum)>>12)) & idvhash)
#endif
static unsigned cd9660_chars2ui __P((unsigned char *begin, int len));
@ -86,73 +75,68 @@ static unsigned cd9660_chars2ui __P((unsigned char *begin, int len));
* Initialize hash links for inodes and dnodes.
*/
int
cd9660_init()
cd9660_init(vfsp)
struct vfsconf *vfsp;
{
register int i;
register union iso_ihead *ih = iso_ihead;
#ifdef ISODEVMAP
register union iso_dhead *dh = iso_dhead;
#endif
for (i = INOHSZ; --i >= 0; ih++) {
ih->ih_head[0] = ih;
ih->ih_head[1] = ih;
}
#ifdef ISODEVMAP
for (i = DNOHSZ; --i >= 0; dh++) {
dh->dh_head[0] = dh;
dh->dh_head[1] = dh;
}
isohashtbl = hashinit(desiredvnodes, M_ISOFSMNT, &isohash);
simple_lock_init(&cd9660_ihash_slock);
#ifdef ISODEVMAP
idvhashtbl = hashinit(desiredvnodes / 8, M_ISOFSMNT, &idvhash);
#endif
return (0);
}
#ifdef ISODEVMAP
#ifdef ISODEVMAP
/*
* Enter a new node into the device hash list
*/
struct iso_dnode *
iso_dmap(dev,ino,create)
dev_t dev;
ino_t ino;
iso_dmap(device, inum, create)
dev_t device;
ino_t inum;
int create;
{
struct iso_dnode *dp;
union iso_dhead *dh;
register struct iso_dnode **dpp, *dp, *dq;
dh = &iso_dhead[DNOHASH(dev, ino)];
for (dp = dh->dh_chain[0];
dp != (struct iso_dnode *)dh;
dp = dp->d_forw)
if (ino == dp->i_number && dev == dp->i_dev)
return dp;
dpp = &idvhashtbl[DNOHASH(device, inum)];
for (dp = *dpp;; dp = dp->d_next) {
if (dp == NULL)
return (NULL);
if (inum == dp->i_number && device == dp->i_dev)
return (dp);
if (!create)
return (struct iso_dnode *)0;
return (NULL);
MALLOC(dp,struct iso_dnode *,sizeof(struct iso_dnode),M_CACHE,M_WAITOK);
MALLOC(dp, struct iso_dnode *, sizeof(struct iso_dnode), M_CACHE,
M_WAITOK);
dp->i_dev = dev;
dp->i_number = ino;
insque(dp,dh);
return dp;
if (dq = *dpp)
dq->d_prev = dp->d_next;
dp->d_next = dq;
dp->d_prev = dpp;
*dpp = dp;
return (dp);
}
void
iso_dunmap(dev)
dev_t dev;
iso_dunmap(device)
dev_t device;
{
struct iso_dnode *dp, *dq;
union iso_dhead *dh;
for (dh = iso_dhead; dh < iso_dhead + DNOHSZ; dh++) {
for (dp = dh->dh_chain[0];
dp != (struct iso_dnode *)dh;
dp = dq) {
dq = dp->d_forw;
if (dev == dp->i_dev) {
remque(dp);
FREE(dp,M_CACHE);
struct iso_dnode **dpp, *dp, *dq;
for (dpp = idvhashtbl; dpp <= idvhashtbl + idvhash; dpp++) {
for (dp = *dpp; dp != NULL; dp = dq)
dq = dp->d_next;
if (device == dp->i_dev) {
if (dq)
dq->d_prev = dp->d_prev;
*dp->d_prev = dq;
FREE(dp, M_CACHE);
}
}
}
@ -160,197 +144,74 @@ iso_dunmap(dev)
#endif
/*
* Look up a ISOFS dinode number to find its incore vnode.
* If it is not in core, read it in from the specified device.
* If it is in core, wait for the lock bit to clear, then
* return the inode locked. Detection and handling of mount
* points must be done by the calling routine.
* 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.
*/
int
iso_iget(xp, ino, relocated, ipp, isodir)
struct iso_node *xp;
ino_t ino;
int relocated;
struct iso_node **ipp;
struct iso_directory_record *isodir;
struct vnode *
cd9660_ihashget(dev, inum)
dev_t dev;
ino_t inum;
{
dev_t dev = xp->i_dev;
struct mount *mntp = ITOV(xp)->v_mount;
register struct iso_node *ip, *iq;
register struct vnode *vp;
#ifdef ISODEVMAP
register struct iso_dnode *dp;
#endif
struct vnode *nvp;
struct buf *bp = NULL, *bp2 = NULL;
union iso_ihead *ih;
int error, result;
struct iso_mnt *imp;
struct proc *p = curproc; /* XXX */
struct iso_node *ip;
struct vnode *vp;
ih = &iso_ihead[INOHASH(dev, ino)];
loop:
for (ip = ih->ih_chain[0];
ip != (struct iso_node *)ih;
ip = ip->i_forw) {
if (ino != ip->i_number || dev != ip->i_dev)
continue;
if ((ip->i_flag&ILOCKED) != 0) {
ip->i_flag |= IWANT;
(void) tsleep((caddr_t)ip, PINOD, "isoigt", 0);
goto loop;
}
if (vget(ITOV(ip), 1))
goto loop;
*ipp = ip;
return 0;
}
/*
* Do the MALLOC before the getnewvnode since doing so afterward
* might cause a bogus v_data pointer to get dereferenced
* elsewhere if MALLOC should block.
*/
MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE, M_WAITOK);
/*
* Allocate a new vnode/iso_node.
*/
if ((error = getnewvnode(VT_ISOFS, mntp, cd9660_vnodeop_p, &nvp))) {
*ipp = NULL;
FREE(ip, M_ISOFSNODE);
return error;
}
bzero((caddr_t)ip, sizeof(struct iso_node));
nvp->v_data = ip;
ip->i_vnode = nvp;
ip->i_flag = 0;
ip->i_devvp = 0;
ip->i_diroff = 0;
ip->i_lockf = 0;
/*
* 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.
*/
ip->i_dev = dev;
ip->i_number = ino;
insque(ip, ih);
ISO_ILOCK(ip);
imp = VFSTOISOFS (mntp);
ip->i_mnt = imp;
ip->i_devvp = imp->im_devvp;
VREF(ip->i_devvp);
if (relocated) {
/*
* On relocated directories we must
* read the `.' entry out of a dir.
*/
ip->iso_start = ino >> imp->im_bshift;
if ((error = iso_blkatoff(ip,0,&bp))) {
vrele(ip->i_devvp);
remque(ip);
ip->i_forw = ip;
ip->i_back = ip;
iso_iput(ip);
*ipp = 0;
return error;
}
isodir = (struct iso_directory_record *)bp->b_un.b_addr;
}
ip->iso_extent = isonum_733(isodir->extent);
ip->i_size = isonum_733(isodir->size);
ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent;
vp = ITOV(ip);
/*
* Setup time stamp, attribute
*/
vp->v_type = VNON;
switch (imp->iso_ftype) {
default: /* ISO_FTYPE_9660 || ISO_FTYPE_HIGH_SIERRA */
if ((imp->im_flags&ISOFSMNT_EXTATT)
&& isonum_711(isodir->ext_attr_length))
iso_blkatoff(ip,-isonum_711(isodir->ext_attr_length),
&bp2);
cd9660_defattr(isodir,ip,bp2,imp->iso_ftype );
cd9660_deftstamp(isodir,ip,bp2,imp->iso_ftype );
break;
case ISO_FTYPE_RRIP:
result = cd9660_rrip_analyze(isodir,ip,imp);
break;
}
if (bp2)
brelse(bp2);
if (bp)
brelse(bp);
/*
* Initialize the associated vnode
*/
vp->v_type = IFTOVT(ip->inode.iso_mode);
if ( vp->v_type == VFIFO ) {
vp->v_op = cd9660_fifoop_p;
} else if ( vp->v_type == VCHR || vp->v_type == VBLK ) {
/*
* if device, look at device number table for translation
*/
#ifdef ISODEVMAP
if (dp = iso_dmap(dev,ino,0))
ip->inode.iso_rdev = dp->d_dev;
#endif
vp->v_op = cd9660_specop_p;
if ((nvp = checkalias(vp, ip->inode.iso_rdev, mntp))) {
/*
* Reinitialize aliased inode.
*/
vp = nvp;
iq = VTOI(vp);
iq->i_vnode = vp;
iq->i_flag = 0;
ISO_ILOCK(iq);
iq->i_dev = dev;
iq->i_number = ino;
iq->i_mnt = ip->i_mnt;
bcopy(&ip->iso_extent,&iq->iso_extent,
(char *)(ip + 1) - (char *)&ip->iso_extent);
insque(iq, ih);
/*
* Discard unneeded vnode
* (This introduces the need of INACTIVE modification)
*/
ip->inode.iso_mode = 0;
iso_iput(ip);
ip = iq;
simple_lock(&cd9660_ihash_slock);
for (ip = isohashtbl[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(&cd9660_ihash_slock);
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
goto loop;
return (vp);
}
}
if (ip->iso_extent == imp->root_extent)
vp->v_flag |= VROOT;
*ipp = ip;
return 0;
simple_unlock(&cd9660_ihash_slock);
return (NULL);
}
/*
* Unlock and decrement the reference count of an inode structure.
* Insert the inode into the hash table, and return it locked.
*/
int
iso_iput(ip)
void
cd9660_ihashins(ip)
struct iso_node *ip;
{
struct proc *p = curproc; /* XXX */
struct iso_node **ipp, *iq;
simple_lock(&cd9660_ihash_slock);
ipp = &isohashtbl[INOHASH(ip->i_dev, ip->i_number)];
if (iq = *ipp)
iq->i_prev = &ip->i_next;
ip->i_next = iq;
ip->i_prev = ipp;
*ipp = ip;
simple_unlock(&cd9660_ihash_slock);
lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p);
}
/*
* Remove the inode from the hash table.
*/
void
cd9660_ihashrem(ip)
register struct iso_node *ip;
{
register struct iso_node *iq;
if ((ip->i_flag & ILOCKED) == 0)
panic("iso_iput");
ISO_IUNLOCK(ip);
vrele(ITOV(ip));
return (0);
simple_lock(&cd9660_ihash_slock);
if (iq = ip->i_next)
iq->i_prev = ip->i_prev;
*ip->i_prev = iq;
#ifdef DIAGNOSTIC
ip->i_next = NULL;
ip->i_prev = NULL;
#endif
simple_unlock(&cd9660_ihash_slock);
}
/*
@ -361,9 +222,11 @@ int
cd9660_inactive(ap)
struct vop_inactive_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
struct proc *p = ap->a_p;
register struct iso_node *ip = VTOI(vp);
int error = 0;
@ -371,12 +234,13 @@ cd9660_inactive(ap)
vprint("cd9660_inactive: pushing active", vp);
ip->i_flag = 0;
VOP_UNLOCK(vp, 0, p);
/*
* If we are done with the inode, reclaim it
* so that it can be reused immediately.
*/
if (vp->v_usecount == 0 && ip->inode.iso_mode == 0)
vgone(vp);
if (ip->inode.iso_mode == 0)
vrecycle(vp, (struct simplelock *)0, p);
return error;
}
@ -387,6 +251,7 @@ int
cd9660_reclaim(ap)
struct vop_reclaim_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
register struct vnode *vp = ap->a_vp;
@ -397,9 +262,7 @@ cd9660_reclaim(ap)
/*
* Remove the inode from its hash chain.
*/
remque(ip);
ip->i_forw = ip;
ip->i_back = ip;
cd9660_ihashrem(ip);
/*
* Purge old data structures associated with the inode.
*/
@ -410,46 +273,6 @@ cd9660_reclaim(ap)
}
FREE(vp->v_data, M_ISOFSNODE);
vp->v_data = NULL;
return 0;
}
/*
* Lock an inode. If its already locked, set the WANT bit and sleep.
*/
int
iso_ilock(ip)
register struct iso_node *ip;
{
while (ip->i_flag & ILOCKED) {
ip->i_flag |= IWANT;
if (ip->i_spare0 == curproc->p_pid)
panic("locking against myself");
ip->i_spare1 = curproc->p_pid;
(void) tsleep((caddr_t)ip, PINOD, "isoilk", 0);
}
ip->i_spare1 = 0;
ip->i_spare0 = curproc->p_pid;
ip->i_flag |= ILOCKED;
return (0);
}
/*
* Unlock an inode. If WANT bit is on, wakeup.
*/
int
iso_iunlock(ip)
register struct iso_node *ip;
{
if ((ip->i_flag & ILOCKED) == 0)
vprint("iso_iunlock: unlocked inode", ITOV(ip));
ip->i_spare0 = 0;
ip->i_flag &= ~ILOCKED;
if (ip->i_flag&IWANT) {
ip->i_flag &= ~IWANT;
wakeup((caddr_t)ip);
}
return (0);
}
@ -457,7 +280,7 @@ iso_iunlock(ip)
* File attributes
*/
void
cd9660_defattr(isodir,inop,bp,ftype)
cd9660_defattr(isodir, inop, bp, ftype)
struct iso_directory_record *isodir;
struct iso_node *inop;
struct buf *bp;
@ -482,14 +305,15 @@ cd9660_defattr(isodir,inop,bp,ftype)
inop->inode.iso_links = 1;
}
if (!bp
&& ((imp = inop->i_mnt)->im_flags&ISOFSMNT_EXTATT)
&& ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
&& (off = isonum_711(isodir->ext_attr_length))) {
iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
VOP_BLKATOFF(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL,
&bp2);
bp = bp2;
}
if (bp) {
ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
ap = (struct iso_extended_attributes *)bp->b_data;
if (isonum_711(ap->version) == 1) {
if (!(ap->perm[0]&0x40))
inop->inode.iso_mode |= VEXEC >> 6;
@ -533,16 +357,16 @@ cd9660_deftstamp(isodir,inop,bp,ftype)
int off;
if (!bp
&& ((imp = inop->i_mnt)->im_flags&ISOFSMNT_EXTATT)
&& ((imp = inop->i_mnt)->im_flags & ISOFSMNT_EXTATT)
&& (off = isonum_711(isodir->ext_attr_length))) {
iso_blkatoff(inop,-off * imp->logical_block_size,&bp2);
VOP_BLKATOFF(ITOV(inop), (off_t)-(off << imp->im_bshift), NULL,
&bp2);
bp = bp2;
}
if (bp) {
ap = (struct iso_extended_attributes *)bp->b_un.b_addr;
if (ftype != ISO_FTYPE_HIGH_SIERRA
&& isonum_711(ap->version) == 1) {
ap = (struct iso_extended_attributes *)bp->b_data;
if (isonum_711(ap->version) == 1) {
if (!cd9660_tstamp_conv17(ap->ftime,&inop->inode.iso_atime))
cd9660_tstamp_conv17(ap->ctime,&inop->inode.iso_atime);
if (!cd9660_tstamp_conv17(ap->ctime,&inop->inode.iso_ctime))
@ -563,9 +387,9 @@ cd9660_deftstamp(isodir,inop,bp,ftype)
int
cd9660_tstamp_conv7(pi,pu,ftype)
char *pi;
struct timespec *pu;
enum ISO_FTYPE ftype;
u_char *pi;
struct timespec *pu;
enum ISO_FTYPE ftype;
{
int crtime, days;
int y, m, d, hour, minute, second, tz;
@ -609,13 +433,13 @@ enum ISO_FTYPE ftype;
return 1;
}
static unsigned
static u_int
cd9660_chars2ui(begin,len)
unsigned char *begin;
u_char *begin;
int len;
{
unsigned rc;
u_int rc;
for (rc = 0; --len >= 0;) {
rc *= 10;
rc += *begin++ - '0';
@ -625,12 +449,12 @@ cd9660_chars2ui(begin,len)
int
cd9660_tstamp_conv17(pi,pu)
unsigned char *pi;
u_char *pi;
struct timespec *pu;
{
unsigned char buf[7];
/* year:"0001"-"9999" -> -1900 */
u_char buf[7];
/* year:"0001"-"9999" -> -1900 */
buf[0] = cd9660_chars2ui(pi,4) - 1900;
/* month: " 1"-"12" -> 1 - 12 */
@ -654,12 +478,14 @@ cd9660_tstamp_conv17(pi,pu)
return cd9660_tstamp_conv7(buf, pu, ISO_FTYPE_DEFAULT);
}
void
isodirino(inump,isodir,imp)
ino_t *inump;
ino_t
isodirino(isodir, imp)
struct iso_directory_record *isodir;
struct iso_mnt *imp;
{
*inump = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
* imp->logical_block_size;
ino_t ino;
ino = (isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length))
<< imp->im_bshift;
return (ino);
}

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)cd9660_node.h 8.2 (Berkeley) 1/23/94
* @(#)cd9660_node.h 8.6 (Berkeley) 5/14/95
* $FreeBSD$
*/
@ -59,22 +59,20 @@ typedef struct {
dev_t iso_rdev; /* Major/Minor number for special */
} ISO_RRIP_INODE;
#ifdef ISODEVMAP
#ifdef ISODEVMAP
/*
* FOr device# (major,minor) translation table
*/
struct iso_dnode {
struct iso_dnode *d_chain[2]; /* hash chain, MUST be first */
struct iso_dnode *d_next, **d_prev; /* hash chain */
dev_t i_dev; /* device where dnode resides */
ino_t i_number; /* the identity of the inode */
dev_t d_dev; /* device # for translation */
};
#define d_forw d_chain[0]
#define d_back d_chain[1]
#endif
struct iso_node {
struct iso_node *i_chain[2]; /* hash chain, MUST be first */
struct iso_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 */
@ -87,8 +85,7 @@ struct iso_node {
doff_t i_diroff; /* offset in dir, where we found last entry */
doff_t i_offset; /* offset of free space in directory */
ino_t i_ino; /* inode number of found directory */
long i_spare0;
long i_spare1;
struct lock i_lock; /* node lock */
long iso_extent; /* extent of file */
long i_size;
@ -101,19 +98,11 @@ struct iso_node {
#define i_back i_chain[1]
/* flags */
#define ILOCKED 0x0001 /* inode is locked */
#define IWANT 0x0002 /* some process waiting on lock */
#define IACC 0x0020 /* inode access time to be updated */
#define IN_ACCESS 0x0020 /* inode access time to be updated */
#define VTOI(vp) ((struct iso_node *)(vp)->v_data)
#define ITOV(ip) ((ip)->i_vnode)
#define ISO_ILOCK(ip) iso_ilock(ip)
#define ISO_IUNLOCK(ip) iso_iunlock(ip)
extern vop_t **cd9660_fifoop_p;
extern vop_t **cd9660_specop_p;
/*
* Prototypes for ISOFS vnode operations
*/
@ -121,14 +110,19 @@ int cd9660_lookup __P((struct vop_lookup_args *));
int cd9660_inactive __P((struct vop_inactive_args *));
int cd9660_reclaim __P((struct vop_reclaim_args *));
int cd9660_bmap __P((struct vop_bmap_args *));
int cd9660_pathconf __P((struct vop_pathconf_args *));
int cd9660_blkatoff __P((struct vop_blkatoff_args *));
#define cd9660_revoke vop_revoke
void cd9660_defattr __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE));
void cd9660_deftstamp __P((struct iso_directory_record *,
struct iso_node *, struct buf *, enum ISO_FTYPE));
int cd9660_tstamp_conv7 __P((char *pi, struct timespec *pu, enum ISO_FTYPE));
int cd9660_tstamp_conv17 __P((unsigned char *pi, struct timespec *pu));
void isodirino __P((ino_t *inump, struct iso_directory_record *isodir,
struct iso_mnt *imp));
struct vnode *cd9660_ihashget __P((dev_t, ino_t));
void cd9660_ihashins __P((struct iso_node *));
void cd9660_ihashrem __P((struct iso_node *));
int cd9660_tstamp_conv7 __P((u_char *, struct timespec *, enum ISO_FTYPE));
int cd9660_tstamp_conv17 __P((u_char *, struct timespec *));
#ifdef ISODEVMAP
struct iso_dnode *iso_dmap __P((dev_t, ino_t, int));
void iso_dunmap __P((dev_t));

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)cd9660_rrip.c 8.2 (Berkeley) 1/23/94
* @(#)cd9660_rrip.c 8.6 (Berkeley) 12/5/94
* $FreeBSD$
*/
@ -104,10 +104,10 @@ cd9660_rrip_attr(p,ana)
ISO_RRIP_ATTR *p;
ISO_RRIP_ANALYZE *ana;
{
ana->inop->inode.iso_mode = isonum_731(p->mode_l);
ana->inop->inode.iso_uid = (uid_t)isonum_731(p->uid_l);
ana->inop->inode.iso_gid = (gid_t)isonum_731(p->gid_l);
ana->inop->inode.iso_links = isonum_731(p->links_l);
ana->inop->inode.iso_mode = isonum_733(p->mode);
ana->inop->inode.iso_uid = isonum_733(p->uid);
ana->inop->inode.iso_gid = isonum_733(p->gid);
ana->inop->inode.iso_links = isonum_733(p->links);
ana->fields &= ~ISO_SUSP_ATTR;
return ISO_SUSP_ATTR;
}
@ -352,8 +352,8 @@ cd9660_rrip_tstamp(p,ana)
ISO_RRIP_TSTAMP *p;
ISO_RRIP_ANALYZE *ana;
{
unsigned char *ptime;
u_char *ptime;
ptime = p->time;
/* Check a format of time stamp (7bytes/17bytes) */
@ -367,7 +367,7 @@ cd9660_rrip_tstamp(p,ana)
ptime += 7;
} else
bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec));
if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
cd9660_tstamp_conv7(ptime,&ana->inop->inode.iso_atime,
ISO_FTYPE_RRIP);
@ -390,7 +390,7 @@ cd9660_rrip_tstamp(p,ana)
ptime += 17;
} else
bzero(&ana->inop->inode.iso_mtime,sizeof(struct timespec));
if (*p->flags&ISO_SUSP_TSTAMP_ACCESS) {
cd9660_tstamp_conv17(ptime,&ana->inop->inode.iso_atime);
ptime += 17;
@ -423,16 +423,15 @@ cd9660_rrip_device(p,ana)
ISO_RRIP_DEVICE *p;
ISO_RRIP_ANALYZE *ana;
{
unsigned high, low;
high = isonum_733(p->dev_t_high_l);
low = isonum_733(p->dev_t_low_l);
if ( high == 0 ) {
ana->inop->inode.iso_rdev = makedev( major(low), minor(low) );
} else {
ana->inop->inode.iso_rdev = makedev( high, minor(low) );
}
u_int high, low;
high = isonum_733(p->dev_t_high);
low = isonum_733(p->dev_t_low);
if (high == 0)
ana->inop->inode.iso_rdev = makedev(major(low), minor(low));
else
ana->inop->inode.iso_rdev = makedev(high, minor(low));
ana->fields &= ~ISO_SUSP_DEVICE;
return ISO_SUSP_DEVICE;
}
@ -475,8 +474,6 @@ cd9660_rrip_stop(p,ana)
ISO_SUSP_HEADER *p;
ISO_RRIP_ANALYZE *ana;
{
/* stop analyzing */
ana->fields = 0;
return ISO_SUSP_STOP;
}
@ -545,22 +542,30 @@ cd9660_rrip_loop(isodir,ana,table)
if (!ana->fields)
break;
}
if (result&ISO_SUSP_STOP) {
result &= ~ISO_SUSP_STOP;
break;
}
/* plausibility check */
if (isonum_711(phead->length) < sizeof(*phead))
break;
/*
* move to next SUSP
* Hopefully this works with newer versions, too
*/
phead = (ISO_SUSP_HEADER *)((char *)phead + isonum_711(phead->length));
}
if ( ana->fields && ana->iso_ce_len ) {
if (ana->fields && ana->iso_ce_len) {
if (ana->iso_ce_blk >= ana->imp->volume_space_size
|| ana->iso_ce_off + ana->iso_ce_len > ana->imp->logical_block_size
|| bread(ana->imp->im_devvp,
iso_lblktodaddr(ana->imp, ana->iso_ce_blk),
ana->imp->logical_block_size,NOCRED,&bp))
ana->iso_ce_blk <<
(ana->imp->im_bshift - DEV_BSHIFT),
ana->imp->logical_block_size, NOCRED, &bp))
/* what to do now? */
break;
phead = (ISO_SUSP_HEADER *)(bp->b_un.b_addr + ana->iso_ce_off);
phead = (ISO_SUSP_HEADER *)(bp->b_data + ana->iso_ce_off);
pend = (ISO_SUSP_HEADER *) ((char *)phead + ana->iso_ce_len);
} else
break;
@ -569,7 +574,7 @@ cd9660_rrip_loop(isodir,ana,table)
brelse(bp);
/*
* If we don't find the Basic SUSP stuffs, just set default value
* ( attribute/time stamp )
* (attribute/time stamp)
*/
for (ptable = table; ptable->func2; ptable++)
if (!(ptable->result&result))
@ -578,6 +583,9 @@ cd9660_rrip_loop(isodir,ana,table)
return result;
}
/*
* Get Attributes.
*/
/*
* XXX the casts are bogus but will do for now.
*/
@ -607,10 +615,8 @@ cd9660_rrip_analyze(isodir,inop,imp)
return cd9660_rrip_loop(isodir,&analyze,rrip_table_analyze);
}
/*
* Get Alternate Name from 'AL' record
* If either no AL record or 0 length,
* it will be return the translated ISO9660 name,
/*
* Get Alternate Name.
*/
static RRIP_TABLE rrip_table_getname[] = {
{ "NM", BC cd9660_rrip_altname, cd9660_rrip_defname, ISO_SUSP_ALTNAME },
@ -654,10 +660,8 @@ cd9660_rrip_getname(isodir,outbuf,outlen,inump,imp)
return cd9660_rrip_loop(isodir,&analyze,tab);
}
/*
* Get Symbolic Name from 'SL' record
*
* Note: isodir should contains SL record!
/*
* Get Symbolic Link.
*/
static RRIP_TABLE rrip_table_getsymname[] = {
{ "SL", BC cd9660_rrip_slink, 0, ISO_SUSP_SLINK },
@ -696,7 +700,7 @@ static RRIP_TABLE rrip_table_extref[] = {
/*
* Check for Rock Ridge Extension and return offset of its fields.
* Note: We require the ER field.
* Note: We insist on the ER field.
*/
int
cd9660_rrip_offset(isodir,imp)

View File

@ -35,36 +35,30 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)cd9660_rrip.h 8.1 (Berkeley) 1/21/94
* $FreeBSD$
* @(#)cd9660_rrip.h 8.2 (Berkeley) 12/5/94
* $Id: cd9660_rrip.h,v 1.3.2000.1 1996/09/30 12:46:48 dfr Exp $
*/
typedef struct {
char type [ISODCL ( 0, 1)];
unsigned char length [ISODCL ( 2, 2)]; /* 711 */
unsigned char version [ISODCL ( 3, 3)];
char type [ISODCL ( 0, 1)];
u_char length [ISODCL ( 2, 2)]; /* 711 */
u_char version [ISODCL ( 3, 3)];
} ISO_SUSP_HEADER;
typedef struct {
ISO_SUSP_HEADER h;
char mode_l [ISODCL ( 4, 7)]; /* 731 */
char mode_m [ISODCL ( 8, 11)]; /* 732 */
char links_l [ISODCL ( 12, 15)]; /* 731 */
char links_m [ISODCL ( 16, 19)]; /* 732 */
char uid_l [ISODCL ( 20, 23)]; /* 731 */
char uid_m [ISODCL ( 24, 27)]; /* 732 */
char gid_l [ISODCL ( 28, 31)]; /* 731 */
char gid_m [ISODCL ( 32, 35)]; /* 732 */
char mode [ISODCL ( 4, 11)]; /* 733 */
char links [ISODCL ( 12, 19)]; /* 733 */
char uid [ISODCL ( 20, 27)]; /* 733 */
char gid [ISODCL ( 28, 35)]; /* 733 */
} ISO_RRIP_ATTR;
typedef struct {
ISO_SUSP_HEADER h;
char dev_t_high_l [ISODCL ( 4, 7)]; /* 731 */
char dev_t_high_m [ISODCL ( 8, 11)]; /* 732 */
char dev_t_low_l [ISODCL ( 12, 15)]; /* 731 */
char dev_t_low_m [ISODCL ( 16, 19)]; /* 732 */
char dev_t_high [ISODCL ( 4, 11)]; /* 733 */
char dev_t_low [ISODCL ( 12, 19)]; /* 733 */
} ISO_RRIP_DEVICE;
#define ISO_SUSP_CFLAG_CONTINUE 0x01
#define ISO_SUSP_CFLAG_CURRENT 0x02
#define ISO_SUSP_CFLAG_PARENT 0x04
@ -73,9 +67,9 @@ typedef struct {
#define ISO_SUSP_CFLAG_HOST 0x20
typedef struct {
u_char cflag [ISODCL ( 1, 1)];
u_char clen [ISODCL ( 2, 2)];
u_char name [0];
u_char cflag [ISODCL ( 1, 1)];
u_char clen [ISODCL ( 2, 2)];
u_char name [1]; /* XXX */
} ISO_RRIP_SLINK_COMPONENT;
#define ISO_RRIP_SLSIZ 2
@ -116,13 +110,13 @@ typedef struct {
typedef struct {
ISO_SUSP_HEADER h;
unsigned char flags [ISODCL ( 4, 4)];
unsigned char time [ISODCL ( 5, 5)];
u_char flags [ISODCL ( 4, 4)];
u_char time [ISODCL ( 5, 5)];
} ISO_RRIP_TSTAMP;
typedef struct {
ISO_SUSP_HEADER h;
unsigned char flags [ISODCL ( 4, 4)];
u_char flags [ISODCL ( 4, 4)];
} ISO_RRIP_IDFLAG;
typedef struct {

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)cd9660_util.c 8.1 (Berkeley) 1/21/94
* @(#)cd9660_util.c 8.3 (Berkeley) 12/5/94
* $FreeBSD$
*/
@ -58,104 +58,14 @@
#include <isofs/cd9660/iso.h>
#ifdef __notanymore__
int
isonum_711 (p)
unsigned char *p;
{
return (*p);
}
int
isonum_712 (p)
signed char *p;
{
return (*p);
}
int
isonum_721 (p)
unsigned char *p;
{
/* little endian short */
#if BYTE_ORDER != LITTLE_ENDIAN
printf ("isonum_721 called on non little-endian machine!\n");
#endif
return *(short *)p;
}
int
isonum_722 (p)
unsigned char *p;
{
/* big endian short */
#if BYTE_ORDER != BIG_ENDIAN
printf ("isonum_722 called on non big-endian machine!\n");
#endif
return *(short *)p;
}
int
isonum_723 (p)
unsigned char *p;
{
#if BYTE_ORDER == BIG_ENDIAN
return isonum_722 (p + 2);
#elif BYTE_ORDER == LITTLE_ENDIAN
return isonum_721 (p);
#else
printf ("isonum_723 unsupported byte order!\n");
return 0;
#endif
}
int
isonum_731 (p)
unsigned char *p;
{
/* little endian long */
#if BYTE_ORDER != LITTLE_ENDIAN
printf ("isonum_731 called on non little-endian machine!\n");
#endif
return *(long *)p;
}
int
isonum_732 (p)
unsigned char *p;
{
/* big endian long */
#if BYTE_ORDER != BIG_ENDIAN
printf ("isonum_732 called on non big-endian machine!\n");
#endif
return *(long *)p;
}
int
isonum_733 (p)
unsigned char *p;
{
#if BYTE_ORDER == BIG_ENDIAN
return isonum_732 (p + 4);
#elif BYTE_ORDER == LITTLE_ENDIAN
return isonum_731 (p);
#else
printf ("isonum_733 unsupported byte order!\n");
return 0;
#endif
}
#endif /* __notanymore__ */
/*
* translate and compare a filename
* Note: Version number plus ';' may be omitted.
*/
int
isofncmp(unsigned char *fn,int fnlen,unsigned char *isofn,int isolen)
isofncmp(fn, fnlen, isofn, isolen)
u_char *fn, *isofn;
int fnlen, isolen;
{
int i, j;
unsigned char c;
@ -211,9 +121,12 @@ isofncmp(unsigned char *fn,int fnlen,unsigned char *isofn,int isolen)
* translate a filename
*/
void
isofntrans(unsigned char *infn,int infnlen,
unsigned char *outfn,unsigned short *outfnlen,
int original,int assoc)
isofntrans(infn, infnlen, outfn, outfnlen, original, assoc)
u_char *infn, *outfn;
int infnlen;
u_short *outfnlen;
int original;
int assoc;
{
int fnidx = 0;

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)cd9660_vfsops.c 8.3 (Berkeley) 1/31/94
* @(#)cd9660_vfsops.c 8.18 (Berkeley) 5/22/95
* $FreeBSD$
*/
@ -52,10 +52,12 @@
#include <sys/ioctl.h>
#include <sys/errno.h>
#include <sys/malloc.h>
#include <sys/stat.h>
#include <isofs/cd9660/iso.h>
#include <isofs/cd9660/cd9660_node.h>
#include <isofs/cd9660/iso_rrip.h>
#include <isofs/cd9660/cd9660_node.h>
#include <isofs/cd9660/cd9660_mount.h>
static int cd9660_mount __P((struct mount *,
@ -84,17 +86,14 @@ static struct vfsops cd9660_vfsops = {
cd9660_vget,
cd9660_fhtovp,
cd9660_vptofh,
cd9660_init,
cd9660_init
};
VFS_SET(cd9660_vfsops, cd9660, MOUNT_CD9660, VFCF_READONLY);
/*
* Called by vfs_mountroot when iso is going to be mounted as root.
*
* Name is updated by mount(8) after booting.
*/
#define ROOTNAME "root_device"
static int iso_mountfs __P((struct vnode *devvp, struct mount *mp,
struct proc *p, struct iso_args *argp));
@ -102,54 +101,37 @@ static int iso_mountfs __P((struct vnode *devvp, struct mount *mp,
int
cd9660_mountroot()
{
register struct mount *mp;
struct mount *mp;
struct proc *p = curproc; /* XXX */
struct iso_mnt *imp;
u_int size;
int error;
struct iso_args args;
int error;
/*
* Get vnode for rootdev.
*/
if (bdevvp(rootdev, &rootvp))
panic("cd9660_mountroot: can't setup bdevvp for rootdev");
if ((error = bdevvp(swapdev, &swapdev_vp)) ||
(error = bdevvp(rootdev, &rootvp))) {
printf("cd9660_mountroot: can't setup bdevvp's");
return (error);
}
mp = malloc((u_long)sizeof(struct mount), M_MOUNT, M_WAITOK);
bzero((char *)mp, (u_long)sizeof(struct mount));
mp->mnt_op = &cd9660_vfsops;
mp->mnt_flag = MNT_RDONLY;
if (error = vfs_rootmountalloc("cd9660", "root_device", &mp))
return (error);
args.flags = ISOFSMNT_ROOT;
if ((error = iso_mountfs(rootvp, mp, p, &args))) {
free(mp, M_MOUNT);
return (error);
}
if ((error = vfs_lock(mp))) {
(void)cd9660_unmount(mp, 0, p);
if (error = iso_mountfs(rootvp, mp, p, &args)) {
mp->mnt_vfc->vfc_refcount--;
vfs_unbusy(mp, p);
free(mp, M_MOUNT);
return (error);
}
simple_lock(&mountlist_slock);
CIRCLEQ_INSERT_TAIL(&mountlist, mp, mnt_list);
mp->mnt_flag |= MNT_ROOTFS;
mp->mnt_vnodecovered = NULLVP;
imp = VFSTOISOFS(mp);
bzero(imp->im_fsmnt, sizeof(imp->im_fsmnt));
imp->im_fsmnt[0] = '/';
bcopy((caddr_t)imp->im_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
MNAMELEN);
(void) copystr(ROOTNAME, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
(void) cd9660_statfs(mp, &mp->mnt_stat, p);
vfs_unlock(mp);
simple_unlock(&mountlist_slock);
(void)cd9660_statfs(mp, &mp->mnt_stat, p);
vfs_unbusy(mp, p);
return (0);
}
/*
* Flag to allow forcible unmounting.
*/
static int iso_doforce = 1;
/*
* VFS Operations.
*
@ -214,10 +196,8 @@ cd9660_mount(mp, path, data, ndp, p)
return error;
}
imp = VFSTOISOFS(mp);
(void) copyinstr(path, imp->im_fsmnt, sizeof(imp->im_fsmnt)-1, &size);
bzero(imp->im_fsmnt + size, sizeof(imp->im_fsmnt) - size);
bcopy((caddr_t)imp->im_fsmnt, (caddr_t)mp->mnt_stat.f_mntonname,
MNAMELEN);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
(void) copyinstr(args.fspec, mp->mnt_stat.f_mntfromname, MNAMELEN - 1,
&size);
bzero(mp->mnt_stat.f_mntfromname + size, MNAMELEN - size);
@ -277,11 +257,11 @@ iso_mountfs(devvp, mp, p, argp)
iso_bsize = ISO_DEFAULT_BLOCK_SIZE;
for (iso_blknum = 16; iso_blknum < 100; iso_blknum++) {
if ((error = bread (devvp, btodb(iso_blknum * iso_bsize),
iso_bsize, NOCRED, &bp)))
if (error = bread(devvp, iso_blknum * btodb(iso_bsize),
iso_bsize, NOCRED, &bp))
goto out;
vdp = (struct iso_volume_descriptor *)bp->b_un.b_addr;
vdp = (struct iso_volume_descriptor *)bp->b_data;
if (bcmp (vdp->id, ISO_STANDARD_ID, sizeof vdp->id) != 0) {
if (bcmp (vdp->id_sierra, ISO_SIERRA_ID,
sizeof vdp->id) != 0) {
@ -347,7 +327,7 @@ iso_mountfs(devvp, mp, p, argp)
mp->mnt_data = (qaddr_t)isomp;
mp->mnt_stat.f_fsid.val[0] = (long)dev;
mp->mnt_stat.f_fsid.val[1] = MOUNT_CD9660;
mp->mnt_stat.f_fsid.val[1] = mp->mnt_vfc->vfc_typenum;
mp->mnt_maxsymlinklen = 0;
mp->mnt_flag |= MNT_LOCAL;
isomp->im_mountp = mp;
@ -358,14 +338,14 @@ iso_mountfs(devvp, mp, p, argp)
/* Check the Rock Ridge Extention support */
if (!(argp->flags & ISOFSMNT_NORRIP)) {
if ((error = bread (isomp->im_devvp,
(isomp->root_extent + isonum_711(rootp->ext_attr_length))
* isomp->logical_block_size / DEV_BSIZE,
isomp->logical_block_size,NOCRED,&bp)))
if (error = bread(isomp->im_devvp,
(isomp->root_extent + isonum_711(rootp->ext_attr_length)) <<
(isomp->im_bshift - DEV_BSHIFT),
isomp->logical_block_size, NOCRED, &bp))
goto out;
rootp = (struct iso_directory_record *)bp->b_un.b_addr;
rootp = (struct iso_directory_record *)bp->b_data;
if ((isomp->rr_skip = cd9660_rrip_offset(rootp,isomp)) < 0) {
argp->flags |= ISOFSMNT_NORRIP;
} else {
@ -436,12 +416,9 @@ cd9660_unmount(mp, mntflags, p)
{
register struct iso_mnt *isomp;
int error, flags = 0;
if (mntflags & MNT_FORCE) {
if (!iso_doforce)
return (EINVAL);
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
}
#if 0
mntflushbuf(mp, 0);
if (mntinvalbuf(mp))
@ -474,33 +451,17 @@ cd9660_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
register struct iso_node *ip;
struct iso_node tip, *nip;
struct vnode tvp;
int error;
struct iso_mnt *imp = VFSTOISOFS (mp);
struct iso_directory_record *dp;
tvp.v_mount = mp;
tvp.v_data = &tip;
ip = VTOI(&tvp);
ip->i_vnode = &tvp;
ip->i_dev = imp->im_dev;
ip->i_diroff = 0;
dp = (struct iso_directory_record *)imp->root;
isodirino(&ip->i_number,dp,imp);
struct iso_mnt *imp = VFSTOISOFS(mp);
struct iso_directory_record *dp =
(struct iso_directory_record *)imp->root;
ino_t ino = isodirino(dp, imp);
/*
* With RRIP we must use the `.' entry of the root directory.
* Simply tell iget, that it's a relocated directory.
* Simply tell vget, that it's a relocated directory.
*/
error = iso_iget(ip,ip->i_number,
imp->iso_ftype == ISO_FTYPE_RRIP,
&nip,dp);
if (error)
return error;
*vpp = ITOV(nip);
return 0;
return (cd9660_vget_internal(mp, ino, vpp,
imp->iso_ftype == ISO_FTYPE_RRIP, dp));
}
/*
@ -541,10 +502,8 @@ cd9660_statfs(mp, sbp, p)
sbp->f_files = 0; /* total files */
sbp->f_ffree = 0; /* free file nodes */
if (sbp != &mp->mnt_stat) {
bcopy((caddr_t)mp->mnt_stat.f_mntonname,
(caddr_t)&sbp->f_mntonname[0], MNAMELEN);
bcopy((caddr_t)mp->mnt_stat.f_mntfromname,
(caddr_t)&sbp->f_mntfromname[0], MNAMELEN);
bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
}
/* Use the first spare for flags: */
sbp->f_spare[0] = isomp->im_flags;
@ -562,21 +521,6 @@ cd9660_sync(mp, waitfor, cred, p)
return (0);
}
/*
* Flat namespace lookup.
* Currently unsupported.
*/
/* ARGSUSED */
static int
cd9660_vget(mp, ino, vpp)
struct mount *mp;
ino_t ino;
struct vnode **vpp;
{
return (EOPNOTSUPP);
}
/*
* File handle to vnode
*
@ -604,92 +548,262 @@ cd9660_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
int *exflagsp;
struct ucred **credanonp;
{
struct vnode tvp;
int error;
int lbn, off;
struct ifid *ifhp;
struct iso_mnt *imp;
struct buf *bp;
struct iso_directory_record *dirp;
struct iso_node tip, *ip, *nip;
struct netcred *np;
imp = VFSTOISOFS (mp);
ifhp = (struct ifid *)fhp;
struct ifid *ifhp = (struct ifid *)fhp;
register struct iso_node *ip;
register struct netcred *np;
register struct iso_mnt *imp = VFSTOISOFS(mp);
struct vnode *nvp;
int error;
#ifdef ISOFS_DBG
printf("fhtovp: ino %d, start %ld\n",
ifhp->ifid_ino, ifhp->ifid_start);
#endif
/*
* Get the export permission structure for this <mp, client> tuple.
*/
np = vfs_export_lookup(mp, &imp->im_export, nam);
if (np == NULL)
return (EACCES);
lbn = iso_lblkno(imp, ifhp->ifid_ino);
if (lbn >= imp->volume_space_size) {
printf("fhtovp: lbn exceed volume space %d\n", lbn);
return (ESTALE);
}
off = iso_blkoff(imp, ifhp->ifid_ino);
if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) {
printf("fhtovp: crosses block boundary %d\n",
off + ISO_DIRECTORY_RECORD_SIZE);
return (ESTALE);
}
error = bread(imp->im_devvp, btodb(lbn * imp->logical_block_size),
imp->logical_block_size, NOCRED, &bp);
if (error) {
printf("fhtovp: bread error %d\n",error);
brelse(bp);
return (error);
}
dirp = (struct iso_directory_record *)(bp->b_un.b_addr + off);
if (off + isonum_711(dirp->length) > imp->logical_block_size) {
brelse(bp);
printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
off+isonum_711(dirp->length), off,
isonum_711(dirp->length));
return (ESTALE);
}
if (isonum_733(dirp->extent) + isonum_711(dirp->ext_attr_length) !=
ifhp->ifid_start) {
brelse(bp);
printf("fhtovp: file start miss %d vs %ld\n",
isonum_733(dirp->extent)+isonum_711(dirp->ext_attr_length),
ifhp->ifid_start);
return (ESTALE);
}
brelse(bp);
ip = &tip;
tvp.v_mount = mp;
tvp.v_data = ip;
ip->i_vnode = &tvp;
ip->i_dev = imp->im_dev;
if ((error = iso_iget(ip, ifhp->ifid_ino, 0, &nip, dirp))) {
if (error = VFS_VGET(mp, ifhp->ifid_ino, &nvp)) {
*vpp = NULLVP;
printf("fhtovp: failed to get inode\n");
return (error);
}
ip = nip;
ip = VTOI(nvp);
if (ip->inode.iso_mode == 0) {
vput(nvp);
*vpp = NULLVP;
return (ESTALE);
}
*vpp = nvp;
*exflagsp = np->netc_exflags;
*credanonp = &np->netc_anon;
return (0);
}
int
cd9660_vget(mp, ino, vpp)
struct mount *mp;
ino_t ino;
struct vnode **vpp;
{
/*
* XXXX
* It would be nice if we didn't always set the `relocated' flag
* and force the extra read, but I don't want to think about fixing
* that right now.
*/
return (cd9660_vget_internal(mp, ino, vpp,
#if 0
VFSTOISOFS(mp)->iso_ftype == ISO_FTYPE_RRIP,
#else
0,
#endif
(struct iso_directory_record *)0));
}
int
cd9660_vget_internal(mp, ino, vpp, relocated, isodir)
struct mount *mp;
ino_t ino;
struct vnode **vpp;
int relocated;
struct iso_directory_record *isodir;
{
struct iso_mnt *imp;
struct iso_node *ip;
struct buf *bp;
struct vnode *vp, *nvp;
dev_t dev;
int error;
imp = VFSTOISOFS(mp);
dev = imp->im_dev;
if ((*vpp = cd9660_ihashget(dev, ino)) != NULLVP)
return (0);
/* Allocate a new vnode/iso_node. */
if (error = getnewvnode(VT_ISOFS, mp, cd9660_vnodeop_p, &vp)) {
*vpp = NULLVP;
return (error);
}
MALLOC(ip, struct iso_node *, sizeof(struct iso_node), M_ISOFSNODE,
M_WAITOK);
bzero((caddr_t)ip, sizeof(struct iso_node));
lockinit(&ip->i_lock, PINOD, "isonode", 0, 0);
vp->v_data = ip;
ip->i_vnode = vp;
ip->i_dev = dev;
ip->i_number = ino;
/*
* 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.
*/
cd9660_ihashins(ip);
if (isodir == 0) {
int lbn, off;
lbn = lblkno(imp, ino);
if (lbn >= imp->volume_space_size) {
vput(vp);
printf("fhtovp: lbn exceed volume space %d\n", lbn);
return (ESTALE);
}
off = blkoff(imp, ino);
if (off + ISO_DIRECTORY_RECORD_SIZE > imp->logical_block_size) {
vput(vp);
printf("fhtovp: crosses block boundary %d\n",
off + ISO_DIRECTORY_RECORD_SIZE);
return (ESTALE);
}
error = bread(imp->im_devvp,
lbn << (imp->im_bshift - DEV_BSHIFT),
imp->logical_block_size, NOCRED, &bp);
if (error) {
vput(vp);
brelse(bp);
printf("fhtovp: bread error %d\n",error);
return (error);
}
isodir = (struct iso_directory_record *)(bp->b_data + off);
if (off + isonum_711(isodir->length) >
imp->logical_block_size) {
vput(vp);
if (bp != 0)
brelse(bp);
printf("fhtovp: directory crosses block boundary %d[off=%d/len=%d]\n",
off +isonum_711(isodir->length), off,
isonum_711(isodir->length));
return (ESTALE);
}
#if 0
if (isonum_733(isodir->extent) +
isonum_711(isodir->ext_attr_length) != ifhp->ifid_start) {
if (bp != 0)
brelse(bp);
printf("fhtovp: file start miss %d vs %d\n",
isonum_733(isodir->extent) + isonum_711(isodir->ext_attr_length),
ifhp->ifid_start);
return (ESTALE);
}
#endif
} else
bp = 0;
ip->i_mnt = imp;
ip->i_devvp = imp->im_devvp;
VREF(ip->i_devvp);
if (relocated) {
/*
* On relocated directories we must
* read the `.' entry out of a dir.
*/
ip->iso_start = ino >> imp->im_bshift;
if (bp != 0)
brelse(bp);
if (error = VOP_BLKATOFF(vp, (off_t)0, NULL, &bp)) {
vput(vp);
return (error);
}
isodir = (struct iso_directory_record *)bp->b_data;
}
ip->iso_extent = isonum_733(isodir->extent);
ip->i_size = isonum_733(isodir->size);
ip->iso_start = isonum_711(isodir->ext_attr_length) + ip->iso_extent;
/*
* Setup time stamp, attribute
*/
vp->v_type = VNON;
switch (imp->iso_ftype) {
default: /* ISO_FTYPE_9660 */
{
struct buf *bp2;
int off;
if ((imp->im_flags & ISOFSMNT_EXTATT)
&& (off = isonum_711(isodir->ext_attr_length)))
VOP_BLKATOFF(vp, (off_t)-(off << imp->im_bshift), NULL,
&bp2);
else
bp2 = NULL;
cd9660_defattr(isodir, ip, bp2, ISO_FTYPE_9660);
cd9660_deftstamp(isodir, ip, bp2, ISO_FTYPE_9660);
if (bp2)
brelse(bp2);
break;
}
case ISO_FTYPE_RRIP:
cd9660_rrip_analyze(isodir, ip, imp);
break;
}
if (bp != 0)
brelse(bp);
/*
* Initialize the associated vnode
*/
switch (vp->v_type = IFTOVT(ip->inode.iso_mode)) {
case VFIFO:
#ifdef FIFO
vp->v_op = cd9660_fifoop_p;
break;
#else
vput(vp);
return (EOPNOTSUPP);
#endif /* FIFO */
case VCHR:
case VBLK:
/*
* if device, look at device number table for translation
*/
#ifdef ISODEVMAP
if (dp = iso_dmap(dev, ino, 0))
ip->inode.iso_rdev = dp->d_dev;
#endif
vp->v_op = cd9660_specop_p;
if (nvp = checkalias(vp, ip->inode.iso_rdev, mp)) {
/*
* Discard unneeded vnode, but save its iso_node.
* Note that the lock is carried over in the iso_node
* to the replacement vnode.
*/
nvp->v_data = vp->v_data;
vp->v_data = NULL;
vp->v_op = spec_vnodeop_p;
vrele(vp);
vgone(vp);
/*
* Reinitialize aliased inode.
*/
vp = nvp;
ip->i_vnode = vp;
}
break;
}
if (ip->iso_extent == imp->root_extent)
vp->v_flag |= VROOT;
/*
* XXX need generation number?
*/
if (ip->inode.iso_mode == 0) {
iso_iput(ip);
*vpp = NULLVP;
printf("fhtovp: inode mode == 0\n");
return (ESTALE);
}
*vpp = ITOV(ip);
*exflagsp = np->netc_exflags;
*credanonp = &np->netc_anon;
return 0;
*vpp = vp;
return (0);
}
/*

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)iso.h 8.2 (Berkeley) 1/23/94
* @(#)iso.h 8.6 (Berkeley) 5/10/95
* $FreeBSD$
*/
@ -138,37 +138,37 @@ struct iso_sierra_primary_descriptor {
struct iso_directory_record {
char length [ISODCL (1, 1)]; /* 711 */
char ext_attr_length [ISODCL (2, 2)]; /* 711 */
unsigned char extent [ISODCL (3, 10)]; /* 733 */
unsigned char size [ISODCL (11, 18)]; /* 733 */
u_char extent [ISODCL (3, 10)]; /* 733 */
u_char size [ISODCL (11, 18)]; /* 733 */
char date [ISODCL (19, 25)]; /* 7 by 711 */
char flags [ISODCL (26, 26)];
char file_unit_size [ISODCL (27, 27)]; /* 711 */
char interleave [ISODCL (28, 28)]; /* 711 */
char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
char name_len [ISODCL (33, 33)]; /* 711 */
char name [0];
char name [1]; /* XXX */
};
/* can't take sizeof(iso_directory_record), because of possible alignment
of the last entry (34 instead of 33) */
#define ISO_DIRECTORY_RECORD_SIZE 33
struct iso_extended_attributes {
unsigned char owner [ISODCL (1, 4)]; /* 723 */
unsigned char group [ISODCL (5, 8)]; /* 723 */
unsigned char perm [ISODCL (9, 10)]; /* 9.5.3 */
u_char owner [ISODCL (1, 4)]; /* 723 */
u_char group [ISODCL (5, 8)]; /* 723 */
u_char perm [ISODCL (9, 10)]; /* 9.5.3 */
char ctime [ISODCL (11, 27)]; /* 8.4.26.1 */
char mtime [ISODCL (28, 44)]; /* 8.4.26.1 */
char xtime [ISODCL (45, 61)]; /* 8.4.26.1 */
char ftime [ISODCL (62, 78)]; /* 8.4.26.1 */
char recfmt [ISODCL (79, 79)]; /* 711 */
char recattr [ISODCL (80, 80)]; /* 711 */
unsigned char reclen [ISODCL (81, 84)]; /* 723 */
u_char reclen [ISODCL (81, 84)]; /* 723 */
char system_id [ISODCL (85, 116)]; /* achars */
char system_use [ISODCL (117, 180)];
char version [ISODCL (181, 181)]; /* 711 */
char len_esc [ISODCL (182, 182)]; /* 711 */
char reserved [ISODCL (183, 246)];
unsigned char len_au [ISODCL (247, 250)]; /* 723 */
u_char len_au [ISODCL (247, 250)]; /* 723 */
};
/* CD-ROM Format type */
@ -191,7 +191,6 @@ struct iso_mnt {
int im_bmask;
int volume_space_size;
char im_fsmnt[50];
struct netexport im_export;
char root[ISODCL (157, 190)];
@ -205,94 +204,102 @@ struct iso_mnt {
#define VFSTOISOFS(mp) ((struct iso_mnt *)((mp)->mnt_data))
#define iso_blkoff(imp, loc) ((loc) & (imp)->im_bmask)
#define iso_lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
#define iso_blksize(imp, ip, lbn) ((imp)->logical_block_size)
#define iso_lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
#define iso_lblktodaddr(imp, lbn) btodb(iso_lblktosize(imp, lbn))
#define iso_dblkinc(imp, lbn) ((lbn) + iso_lblktodaddr(imp, 1))
#define iso_dblkno(imp, loc) iso_lblktodaddr(imp, iso_lblkno(imp, loc))
int cd9660_init __P((void));
#define blkoff(imp, loc) ((loc) & (imp)->im_bmask)
#define lblktosize(imp, blk) ((blk) << (imp)->im_bshift)
#define lblkno(imp, loc) ((loc) >> (imp)->im_bshift)
#define blksize(imp, ip, lbn) ((imp)->logical_block_size)
struct iso_node;
int iso_blkatoff __P((struct iso_node *ip, long offset, struct buf **bpp));
int iso_iget __P((struct iso_node *xp, ino_t ino, int relocated,
struct iso_node **ipp, struct iso_directory_record *isodir));
int iso_iput __P((struct iso_node *ip));
int iso_ilock __P((struct iso_node *ip));
int iso_iunlock __P((struct iso_node *ip));
int cd9660_mountroot __P((void));
int cd9660_vget_internal __P((struct mount *, ino_t, struct vnode **, int,
struct iso_directory_record *));
int cd9660_init __P((struct vfsconf *));
#define cd9660_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
size_t, struct proc *)))eopnotsupp)
int cd9660_mountroot __P((void));
extern vop_t **cd9660_vnodeop_p;
extern vop_t **cd9660_specop_p;
#ifdef FIFO
extern vop_t **cd9660_fifoop_p;
#endif
static int isonum_711 __P((unsigned char *p));
static int isonum_712 __P((char *p));
static int isonum_721 __P((unsigned char *p));
static int isonum_722 __P((unsigned char *p));
static int isonum_723 __P((unsigned char *p));
static int isonum_731 __P((unsigned char *p));
static int isonum_732 __P((unsigned char *p));
static int isonum_733 __P((unsigned char *p));
static inline int
static __inline int isonum_711 __P((u_char *));
static __inline int
isonum_711(p)
unsigned char *p;
u_char *p;
{
return *p;
}
static inline int
static __inline int isonum_712 __P((char *));
static __inline int
isonum_712(p)
char *p;
{
return *p;
}
static inline int
isonum_721(p)
unsigned char *p;
{
return *p|((char)p[1] << 8);
}
#ifndef UNALIGNED_ACCESS
static inline int
isonum_722(p)
unsigned char *p;
{
return ((char)*p << 8)|p[1];
}
static inline int
static __inline int isonum_723 __P((u_char *));
static __inline int
isonum_723(p)
unsigned char *p;
u_char *p;
{
return isonum_721(p);
return *p|(p[1] << 8);
}
static inline int
isonum_731(p)
unsigned char *p;
static __inline int isonum_733 __P((u_char *));
static __inline int
isonum_733(p)
u_char *p;
{
return *p|(p[1] << 8)|(p[2] << 16)|(p[3] << 24);
}
static inline int
isonum_732(p)
unsigned char *p;
#else /* UNALIGNED_ACCESS */
#if BYTE_ORDER == LITTLE_ENDIAN
static __inline int
isonum_723(p)
u_char *p
{
return (*p << 24)|(p[1] << 16)|(p[2] << 8)|p[3];
return *(u_int16t *)p;
}
static inline int
static __inline int
isonum_733(p)
unsigned char *p;
u_char *p;
{
return isonum_731(p);
return *(u_int32t *)p;
}
int isofncmp __P((unsigned char *, int, unsigned char *, int));
void isofntrans __P((unsigned char *, int, unsigned char *, unsigned short *,
int, int));
#endif
#if BYTE_ORDER == BIG_ENDIAN
static __inline int
isonum_723(p)
u_char *p
{
return *(u_int16t *)(p + 2);
}
static __inline int
isonum_733(p)
u_char *p;
{
return *(u_int32t *)(p + 4);
}
#endif
#endif /* UNALIGNED_ACCESS */
int isofncmp __P((u_char *, int, u_char *, int));
void isofntrans __P((u_char *, int, u_char *, u_short *, int, int));
ino_t isodirino __P((struct iso_directory_record *, struct iso_mnt *));
/*
* Associated files have a leading '='.

View File

@ -77,11 +77,11 @@ static int dead_select __P((struct vop_select_args *));
#define dead_inactive ((int (*) __P((struct vop_inactive_args *)))nullop)
#define dead_reclaim ((int (*) __P((struct vop_reclaim_args *)))nullop)
static int dead_lock __P((struct vop_lock_args *));
#define dead_unlock ((int (*) __P((struct vop_unlock_args *)))nullop)
#define dead_unlock ((int (*) __P((struct vop_unlock_args *)))vop_nounlock)
static int dead_bmap __P((struct vop_bmap_args *));
static int dead_strategy __P((struct vop_strategy_args *));
static int dead_print __P((struct vop_print_args *));
#define dead_islocked ((int (*) __P((struct vop_islocked_args *)))nullop)
#define dead_islocked ((int(*) __P((struct vop_islocked_args *)))vop_noislocked)
#define dead_pathconf ((int (*) __P((struct vop_pathconf_args *)))dead_ebadf)
#define dead_advlock ((int (*) __P((struct vop_advlock_args *)))dead_ebadf)
#define dead_blkatoff ((int (*) __P((struct vop_blkatoff_args *)))dead_badop)
@ -191,11 +191,20 @@ dead_read(ap)
if (chkvnlock(ap->a_vp))
panic("dead_read: lock");
#if 0
/* Lite2 behaviour */
/*
* Return EOF for tty devices, EIO for others
*/
if ((ap->a_vp->v_flag & VISTTY) == 0)
return (EIO);
#else
/*
* Return EOF for character devices, EIO for others
*/
if (ap->a_vp->v_type != VCHR)
return (EIO);
#endif
return (0);
}
@ -282,12 +291,23 @@ static int
dead_lock(ap)
struct vop_lock_args /* {
struct vnode *a_vp;
int a_flags;
struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
if (!chkvnlock(ap->a_vp))
/*
* Since we are not using the lock manager, we must clear
* the interlock here.
*/
if (ap->a_flags & LK_INTERLOCK) {
simple_unlock(&vp->v_interlock);
ap->a_flags &= ~LK_INTERLOCK;
}
if (!chkvnlock(vp))
return (0);
return (VCALL(ap->a_vp, VOFFSET(vop_lock), ap));
return (VCALL(vp, VOFFSET(vop_lock), ap));
}
/*

View File

@ -61,8 +61,7 @@ typedef enum {
} fdntype;
struct fdescnode {
struct fdescnode *fd_forw; /* Hash chain */
struct fdescnode *fd_back;
LIST_ENTRY(fdescnode) fd_hash; /* Hash list */
struct vnode *fd_vnode; /* Back ptr to vnode */
fdntype fd_type; /* Type of this node */
unsigned fd_fd; /* Fd to be dup'ed */
@ -74,7 +73,7 @@ struct fdescnode {
#define VTOFDESC(vp) ((struct fdescnode *)(vp)->v_data)
extern dev_t devctty;
extern int fdesc_init __P((void));
extern int fdesc_init __P((struct vfsconf *));
extern int fdesc_root __P((struct mount *, struct vnode **));
extern int fdesc_allocvp __P((fdntype, int, struct mount *, struct vnode **));
extern vop_t **fdesc_vnodeop_p;

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1992, 1993
* Copyright (c) 1992, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
@ -108,7 +108,7 @@ fdesc_mount(mp, path, data, ndp, p)
/* XXX -- don't mark as local to work around fts() problems */
/*mp->mnt_flag |= MNT_LOCAL;*/
mp->mnt_data = (qaddr_t) fmp;
getnewfsid(mp, MOUNT_FDESC);
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
@ -137,12 +137,8 @@ fdesc_unmount(mp, mntflags, p)
int flags = 0;
struct vnode *rootvp = VFSTOFDESC(mp)->f_root;
if (mntflags & MNT_FORCE) {
/* fdesc can never be rootfs so don't check for it */
if (!doforce)
return (EINVAL);
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
}
/*
* Clear out buffer cache. I don't think we
@ -176,6 +172,7 @@ fdesc_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
struct proc *p = curproc; /* XXX */
struct vnode *vp;
/*
@ -183,23 +180,11 @@ fdesc_root(mp, vpp)
*/
vp = VFSTOFDESC(mp)->f_root;
VREF(vp);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
*vpp = vp;
return (0);
}
static int
fdesc_quotactl(mp, cmd, uid, arg, p)
struct mount *mp;
int cmd;
uid_t uid;
caddr_t arg;
struct proc *p;
{
return (EOPNOTSUPP);
}
static int
fdesc_statfs(mp, sbp, p)
struct mount *mp;
@ -233,7 +218,6 @@ fdesc_statfs(mp, sbp, p)
if (fdp->fd_nfiles < lim)
freefd += (lim - fdp->fd_nfiles);
sbp->f_type = MOUNT_FDESC;
sbp->f_flags = 0;
sbp->f_bsize = DEV_BSIZE;
sbp->f_iosize = DEV_BSIZE;
@ -243,6 +227,7 @@ fdesc_statfs(mp, sbp, p)
sbp->f_files = lim + 1; /* Allow for "." */
sbp->f_ffree = freefd; /* See comments above */
if (sbp != &mp->mnt_stat) {
sbp->f_type = mp->mnt_vfc->vfc_typenum;
bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
@ -261,41 +246,15 @@ fdesc_sync(mp, waitfor, cred, p)
return (0);
}
/*
* Fdesc flat namespace lookup.
* Currently unsupported.
*/
static int
fdesc_vget(mp, ino, vpp)
struct mount *mp;
ino_t ino;
struct vnode **vpp;
{
return (EOPNOTSUPP);
}
static int
fdesc_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
struct mount *mp;
struct fid *fhp;
struct mbuf *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
return (EOPNOTSUPP);
}
static int
fdesc_vptofh(vp, fhp)
struct vnode *vp;
struct fid *fhp;
{
return (EOPNOTSUPP);
}
#define fdesc_fhtovp ((int (*) __P((struct mount *, struct fid *, \
struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp)
#define fdesc_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \
struct proc *)))eopnotsupp)
#define fdesc_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
size_t, struct proc *)))eopnotsupp)
#define fdesc_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \
eopnotsupp)
#define fdesc_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp)
static struct vfsops fdesc_vfsops = {
fdesc_mount,

View File

@ -77,22 +77,14 @@ FD_STDIN, FD_STDOUT, FD_STDERR must be a sequence n, n+1, n+2
#endif
#define NFDCACHE 4
#define FD_NHASH(ix) ((ix) & NFDCACHE-1)
/*
* Cache head
*/
struct fdcache {
struct fdescnode *fc_forw;
struct fdescnode *fc_back;
};
static struct fdcache fdcache[NFDCACHE];
#define FD_NHASH(ix) \
(&fdhashtbl[(ix) & fdhash])
LIST_HEAD(fdhashhead, fdescnode) *fdhashtbl;
u_long fdhash;
static int fdesc_attr __P((int fd, struct vattr *vap, struct ucred *cred,
struct proc *p));
static int fdesc_badop __P((void));
static int fdesc_enotsupp __P((void));
static int fdesc_getattr __P((struct vop_getattr_args *ap));
static struct fdcache *
fdesc_hash __P((int ix));
@ -115,28 +107,15 @@ static int fdesc_write __P((struct vop_write_args *ap));
* Initialise cache headers
*/
int
fdesc_init()
fdesc_init(vfsp)
struct vfsconf *vfsp;
{
struct fdcache *fc;
devctty = makedev(nchrdev, 0);
for (fc = fdcache; fc < fdcache + NFDCACHE; fc++)
fc->fc_forw = fc->fc_back = (struct fdescnode *) fc;
fdhashtbl = hashinit(NFDCACHE, M_CACHE, &fdhash);
return (0);
}
/*
* Compute hash list for given target vnode
*/
static struct fdcache *
fdesc_hash(ix)
int ix;
{
return (&fdcache[FD_NHASH(ix)]);
}
int
fdesc_allocvp(ftype, ix, mp, vpp)
fdntype ftype;
@ -144,15 +123,16 @@ fdesc_allocvp(ftype, ix, mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
struct fdcache *fc;
struct proc *p = curproc; /* XXX */
struct fdhashhead *fc;
struct fdescnode *fd;
int error = 0;
fc = FD_NHASH(ix);
loop:
fc = fdesc_hash(ix);
for (fd = fc->fc_forw; fd != (struct fdescnode *) fc; fd = fd->fd_forw) {
for (fd = fc->lh_first; fd != 0; fd = fd->fd_hash.le_next) {
if (fd->fd_ix == ix && fd->fd_vnode->v_mount == mp) {
if (vget(fd->fd_vnode, 0))
if (vget(fd->fd_vnode, 0, p))
goto loop;
*vpp = fd->fd_vnode;
return (error);
@ -188,8 +168,7 @@ fdesc_allocvp(ftype, ix, mp, vpp)
fd->fd_fd = -1;
fd->fd_link = 0;
fd->fd_ix = ix;
fc = fdesc_hash(ix);
insque(fd, fc);
LIST_INSERT_HEAD(fc, fd, fd_hash);
out:;
fdcache_lock &= ~FDL_LOCKED;
@ -216,31 +195,28 @@ fdesc_lookup(ap)
{
struct vnode **vpp = ap->a_vpp;
struct vnode *dvp = ap->a_dvp;
char *pname;
struct proc *p;
int nfiles;
unsigned fd = 0;
struct componentname *cnp = ap->a_cnp;
char *pname = cnp->cn_nameptr;
struct proc *p = cnp->cn_proc;
int nfiles = p->p_fd->fd_nfiles;
unsigned fd;
int error;
struct vnode *fvp;
char *ln;
if (ap->a_cnp->cn_nameiop == DELETE ||
ap->a_cnp->cn_nameiop == RENAME) {
if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME) {
error = EROFS;
goto bad;
}
pname = ap->a_cnp->cn_nameptr;
if (ap->a_cnp->cn_namelen == 1 && *pname == '.') {
VOP_UNLOCK(dvp, 0, p);
if (cnp->cn_namelen == 1 && *pname == '.') {
*vpp = dvp;
VREF(dvp);
VOP_LOCK(dvp);
VREF(dvp);
vn_lock(dvp, LK_SHARED | LK_RETRY, p);
return (0);
}
p = ap->a_cnp->cn_proc;
nfiles = p->p_fd->fd_nfiles;
switch (VTOFDESC(dvp)->fd_type) {
default:
case Flink:
@ -250,17 +226,17 @@ fdesc_lookup(ap)
goto bad;
case Froot:
if (ap->a_cnp->cn_namelen == 2 && bcmp(pname, "fd", 2) == 0) {
if (cnp->cn_namelen == 2 && bcmp(pname, "fd", 2) == 0) {
error = fdesc_allocvp(Fdevfd, FD_DEVFD, dvp->v_mount, &fvp);
if (error)
goto bad;
*vpp = fvp;
fvp->v_type = VDIR;
VOP_LOCK(fvp);
vn_lock(fvp, LK_SHARED | LK_RETRY, p);
return (0);
}
if (ap->a_cnp->cn_namelen == 3 && bcmp(pname, "tty", 3) == 0) {
if (cnp->cn_namelen == 3 && bcmp(pname, "tty", 3) == 0) {
struct vnode *ttyvp = cttyvp(p);
if (ttyvp == NULL) {
error = ENXIO;
@ -271,12 +247,12 @@ fdesc_lookup(ap)
goto bad;
*vpp = fvp;
fvp->v_type = VFIFO;
VOP_LOCK(fvp);
vn_lock(fvp, LK_SHARED | LK_RETRY, p);
return (0);
}
ln = 0;
switch (ap->a_cnp->cn_namelen) {
switch (cnp->cn_namelen) {
case 5:
if (bcmp(pname, "stdin", 5) == 0) {
ln = "fd/0";
@ -302,7 +278,7 @@ fdesc_lookup(ap)
VTOFDESC(fvp)->fd_link = ln;
*vpp = fvp;
fvp->v_type = VLNK;
VOP_LOCK(fvp);
vn_lock(fvp, LK_SHARED | LK_RETRY, p);
return (0);
} else {
error = ENOENT;
@ -312,9 +288,10 @@ fdesc_lookup(ap)
/* FALL THROUGH */
case Fdevfd:
if (ap->a_cnp->cn_namelen == 2 && bcmp(pname, "..", 2) == 0) {
error = fdesc_root(dvp->v_mount, vpp);
return (error);
if (cnp->cn_namelen == 2 && bcmp(pname, "..", 2) == 0) {
if (error = fdesc_root(dvp->v_mount, vpp))
goto bad;
return (0);
}
fd = 0;
@ -338,11 +315,13 @@ fdesc_lookup(ap)
if (error)
goto bad;
VTOFDESC(fvp)->fd_fd = fd;
vn_lock(fvp, LK_SHARED | LK_RETRY, p);
*vpp = fvp;
return (0);
}
bad:;
vn_lock(dvp, LK_SHARED | LK_RETRY, p);
*vpp = NULL;
return (error);
}
@ -402,10 +381,10 @@ fdesc_attr(fd, vap, cred, p)
error = VOP_GETATTR((struct vnode *) fp->f_data, vap, cred, p);
if (error == 0 && vap->va_type == VDIR) {
/*
* don't allow directories to show up because
* that causes loops in the namespace.
* directories can cause loops in the namespace,
* so turn off the 'x' bits to avoid trouble.
*/
vap->va_type = VFIFO;
vap->va_mode &= ~((VEXEC)|(VEXEC>>3)|(VEXEC>>6));
}
break;
@ -591,6 +570,9 @@ fdesc_readdir(ap)
struct vnode *a_vp;
struct uio *a_uio;
struct ucred *a_cred;
int *a_eofflag;
u_long *a_cookies;
int a_ncookies;
} */ *ap;
{
struct uio *uio = ap->a_uio;
@ -598,6 +580,13 @@ fdesc_readdir(ap)
int i;
int error;
/*
* We don't allow exporting fdesc mounts, and currently local
* requests do not need cookies.
*/
if (ap->a_ncookies)
panic("fdesc_readdir: not hungry");
switch (VTOFDESC(ap->a_vp)->fd_type) {
case Fctty:
return (0);
@ -814,6 +803,7 @@ static int
fdesc_inactive(ap)
struct vop_inactive_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
@ -822,6 +812,7 @@ fdesc_inactive(ap)
* Clear out the v_type field to avoid
* nasty things happening in vgone().
*/
VOP_UNLOCK(vp, 0, ap->a_p);
vp->v_type = VNON;
return (0);
}
@ -833,8 +824,9 @@ fdesc_reclaim(ap)
} */ *ap;
{
struct vnode *vp = ap->a_vp;
struct fdescnode *fd = VTOFDESC(vp);
remque(VTOFDESC(vp));
LIST_REMOVE(fd, fd_hash);
FREE(vp->v_data, M_TEMP);
vp->v_data = 0;
@ -906,16 +898,6 @@ fdesc_vfree(ap)
return (0);
}
/*
* /dev/fd vnode unsupported operation
*/
static int
fdesc_enotsupp()
{
return (EOPNOTSUPP);
}
/*
* /dev/fd "should never get here" operation
*/
@ -927,38 +909,39 @@ fdesc_badop()
/* NOTREACHED */
}
#define fdesc_create ((int (*) __P((struct vop_create_args *)))fdesc_enotsupp)
#define fdesc_mknod ((int (*) __P((struct vop_mknod_args *)))fdesc_enotsupp)
#define fdesc_create ((int (*) __P((struct vop_create_args *)))eopnotsupp)
#define fdesc_mknod ((int (*) __P((struct vop_mknod_args *)))eopnotsupp)
#define fdesc_close ((int (*) __P((struct vop_close_args *)))nullop)
#define fdesc_access ((int (*) __P((struct vop_access_args *)))nullop)
#define fdesc_mmap ((int (*) __P((struct vop_mmap_args *)))fdesc_enotsupp)
#define fdesc_mmap ((int (*) __P((struct vop_mmap_args *)))eopnotsupp)
#define fdesc_revoke vop_revoke
#define fdesc_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
#define fdesc_seek ((int (*) __P((struct vop_seek_args *)))nullop)
#define fdesc_remove ((int (*) __P((struct vop_remove_args *)))fdesc_enotsupp)
#define fdesc_link ((int (*) __P((struct vop_link_args *)))fdesc_enotsupp)
#define fdesc_rename ((int (*) __P((struct vop_rename_args *)))fdesc_enotsupp)
#define fdesc_mkdir ((int (*) __P((struct vop_mkdir_args *)))fdesc_enotsupp)
#define fdesc_rmdir ((int (*) __P((struct vop_rmdir_args *)))fdesc_enotsupp)
#define fdesc_symlink ((int (*) __P((struct vop_symlink_args *)))fdesc_enotsupp)
#define fdesc_remove ((int (*) __P((struct vop_remove_args *)))eopnotsupp)
#define fdesc_link ((int (*) __P((struct vop_link_args *)))eopnotsupp)
#define fdesc_rename ((int (*) __P((struct vop_rename_args *)))eopnotsupp)
#define fdesc_mkdir ((int (*) __P((struct vop_mkdir_args *)))eopnotsupp)
#define fdesc_rmdir ((int (*) __P((struct vop_rmdir_args *)))eopnotsupp)
#define fdesc_symlink ((int (*) __P((struct vop_symlink_args *)))eopnotsupp)
#define fdesc_abortop ((int (*) __P((struct vop_abortop_args *)))nullop)
#define fdesc_lock ((int (*) __P((struct vop_lock_args *)))nullop)
#define fdesc_unlock ((int (*) __P((struct vop_unlock_args *)))nullop)
#define fdesc_lock ((int (*) __P((struct vop_lock_args *)))vop_nolock)
#define fdesc_unlock ((int (*) __P((struct vop_unlock_args *)))vop_nounlock)
#define fdesc_bmap ((int (*) __P((struct vop_bmap_args *)))fdesc_badop)
#define fdesc_strategy ((int (*) __P((struct vop_strategy_args *)))fdesc_badop)
#define fdesc_islocked ((int (*) __P((struct vop_islocked_args *)))nullop)
#define fdesc_advlock ((int (*) __P((struct vop_advlock_args *)))fdesc_enotsupp)
#define fdesc_islocked \
((int (*) __P((struct vop_islocked_args *)))vop_noislocked)
#define fdesc_advlock ((int (*) __P((struct vop_advlock_args *)))eopnotsupp)
#define fdesc_blkatoff \
((int (*) __P((struct vop_blkatoff_args *)))fdesc_enotsupp)
#define fdesc_vget ((int (*) __P((struct vop_vget_args *)))fdesc_enotsupp)
((int (*) __P((struct vop_blkatoff_args *)))eopnotsupp)
#define fdesc_valloc ((int(*) __P(( \
struct vnode *pvp, \
int mode, \
struct ucred *cred, \
struct vnode **vpp))) fdesc_enotsupp)
struct vnode **vpp))) eopnotsupp)
#define fdesc_truncate \
((int (*) __P((struct vop_truncate_args *)))fdesc_enotsupp)
#define fdesc_update ((int (*) __P((struct vop_update_args *)))fdesc_enotsupp)
#define fdesc_bwrite ((int (*) __P((struct vop_bwrite_args *)))fdesc_enotsupp)
((int (*) __P((struct vop_truncate_args *)))eopnotsupp)
#define fdesc_update ((int (*) __P((struct vop_update_args *)))eopnotsupp)
#define fdesc_bwrite ((int (*) __P((struct vop_bwrite_args *)))eopnotsupp)
static vop_t **fdesc_vnodeop_p;
static struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {
@ -975,6 +958,7 @@ static struct vnodeopv_entry_desc fdesc_vnodeop_entries[] = {
{ &vop_write_desc, (vop_t *)fdesc_write }, /* write */
{ &vop_ioctl_desc, (vop_t *)fdesc_ioctl }, /* ioctl */
{ &vop_select_desc, (vop_t *)fdesc_select }, /* select */
{ &vop_revoke_desc, (vop_t *)fdesc_revoke }, /* revoke */
{ &vop_mmap_desc, (vop_t *)fdesc_mmap }, /* mmap */
{ &vop_fsync_desc, (vop_t *)fdesc_fsync }, /* fsync */
{ &vop_seek_desc, (vop_t *)fdesc_seek }, /* seek */

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)fifo.h 8.2 (Berkeley) 2/2/94
* @(#)fifo.h 8.6 (Berkeley) 5/21/95
* $FreeBSD$
*/
@ -51,8 +51,10 @@ int fifo_close __P((struct vop_close_args *));
#define fifo_setattr ((int (*) __P((struct vop_setattr_args *)))fifo_ebadf)
int fifo_read __P((struct vop_read_args *));
int fifo_write __P((struct vop_write_args *));
#define fifo_lease_check ((int (*) __P((struct vop_lease_args *)))nullop)
int fifo_ioctl __P((struct vop_ioctl_args *));
int fifo_select __P((struct vop_select_args *));
#define fifo_revoke vop_revoke
#define fifo_mmap ((int (*) __P((struct vop_mmap_args *)))fifo_badop)
#define fifo_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
#define fifo_seek ((int (*) __P((struct vop_seek_args *)))fifo_badop)
@ -65,11 +67,13 @@ int fifo_select __P((struct vop_select_args *));
#define fifo_readdir ((int (*) __P((struct vop_readdir_args *)))fifo_badop)
#define fifo_readlink ((int (*) __P((struct vop_readlink_args *)))fifo_badop)
#define fifo_abortop ((int (*) __P((struct vop_abortop_args *)))fifo_badop)
#define fifo_inactive ((int (*) __P((struct vop_inactive_args *)))nullop)
int fifo_inactive __P((struct vop_inactive_args *));
#define fifo_reclaim ((int (*) __P((struct vop_reclaim_args *)))nullop)
#define fifo_lock ((int (*) __P((struct vop_lock_args *)))vop_nolock)
#define fifo_unlock ((int (*) __P((struct vop_unlock_args *)))vop_nounlock)
int fifo_bmap __P((struct vop_bmap_args *));
#define fifo_strategy ((int (*) __P((struct vop_strategy_args *)))fifo_badop)
#define fifo_islocked ((int (*) __P((struct vop_islocked_args *)))nullop)
#define fifo_islocked ((int(*) __P((struct vop_islocked_args *)))vop_noislocked)
int fifo_pathconf __P((struct vop_pathconf_args *));
int fifo_advlock __P((struct vop_advlock_args *));
#define fifo_blkatoff ((int (*) __P((struct vop_blkatoff_args *)))fifo_badop)

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1990, 1993
* Copyright (c) 1990, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -30,12 +30,12 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)fifo_vnops.c 8.2 (Berkeley) 1/4/94
* @(#)fifo_vnops.c 8.10 (Berkeley) 5/27/95
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/namei.h>
@ -44,7 +44,6 @@
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <sys/stat.h>
#include <sys/systm.h>
#include <sys/ioctl.h>
#include <sys/file.h>
#include <sys/errno.h>
@ -64,8 +63,6 @@ struct fifoinfo {
};
static int fifo_ebadf __P((void));
static int fifo_unlock __P((struct vop_unlock_args *));
static int fifo_lock __P((struct vop_lock_args *));
static int fifo_print __P((struct vop_print_args *));
vop_t **fifo_vnodeop_p;
@ -81,8 +78,10 @@ static struct vnodeopv_entry_desc fifo_vnodeop_entries[] = {
{ &vop_setattr_desc, (vop_t *)fifo_setattr }, /* setattr */
{ &vop_read_desc, (vop_t *)fifo_read }, /* read */
{ &vop_write_desc, (vop_t *)fifo_write }, /* write */
{ &vop_lease_desc, (vop_t *)fifo_lease_check }, /* lease */
{ &vop_ioctl_desc, (vop_t *)fifo_ioctl }, /* ioctl */
{ &vop_select_desc, (vop_t *)fifo_select }, /* select */
{ &vop_revoke_desc, (vop_t *)fifo_revoke }, /* revoke */
{ &vop_mmap_desc, (vop_t *)fifo_mmap }, /* mmap */
{ &vop_fsync_desc, (vop_t *)fifo_fsync }, /* fsync */
{ &vop_seek_desc, (vop_t *)fifo_seek }, /* seek */
@ -149,8 +148,9 @@ fifo_open(ap)
struct proc *a_p;
} */ *ap;
{
register struct vnode *vp = ap->a_vp;
register struct fifoinfo *fip;
struct vnode *vp = ap->a_vp;
struct fifoinfo *fip;
struct proc *p = ap->a_p;
struct socket *rso, *wso;
int error;
static char openstr[] = "fifo";
@ -158,14 +158,14 @@ fifo_open(ap)
if ((fip = vp->v_fifoinfo) == NULL) {
MALLOC(fip, struct fifoinfo *, sizeof(*fip), M_VNODE, M_WAITOK);
vp->v_fifoinfo = fip;
error = socreate(AF_UNIX, &rso, SOCK_STREAM, 0, ap->a_p);
error = socreate(AF_LOCAL, &rso, SOCK_STREAM, 0, ap->a_p);
if (error) {
free(fip, M_VNODE);
vp->v_fifoinfo = NULL;
return (error);
}
fip->fi_readsock = rso;
error = socreate(AF_UNIX, &wso, SOCK_STREAM, 0, ap->a_p);
error = socreate(AF_LOCAL, &wso, SOCK_STREAM, 0, ap->a_p);
if (error) {
(void)soclose(rso);
free(fip, M_VNODE);
@ -185,60 +185,52 @@ fifo_open(ap)
wso->so_state |= SS_CANTRCVMORE;
rso->so_state |= SS_CANTSENDMORE;
}
error = 0;
if ((ap->a_mode & (FREAD|FWRITE)) == (FREAD|FWRITE)) {
if (fip->fi_readers == 0) {
fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
if (fip->fi_writers > 0)
wakeup((caddr_t)&fip->fi_writers);
}
if (fip->fi_writers == 0) {
fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
if (fip->fi_readers > 0)
wakeup((caddr_t)&fip->fi_readers);
}
fip->fi_readers++;
fip->fi_writers++;
}
else if (ap->a_mode & FREAD) {
if (ap->a_mode & FREAD) {
fip->fi_readers++;
if (fip->fi_readers == 1) {
fip->fi_writesock->so_state &= ~SS_CANTSENDMORE;
if (fip->fi_writers > 0)
wakeup((caddr_t)&fip->fi_writers);
}
if (!(ap->a_mode & O_NONBLOCK))
while (fip->fi_writers == 0) {
VOP_UNLOCK(vp);
error = tsleep((caddr_t)&fip->fi_readers,
PCATCH | PSOCK, openstr, 0);
VOP_LOCK(vp);
if (error)
break;
}
}
else {
if (ap->a_mode & FWRITE) {
fip->fi_writers++;
if (fip->fi_readers == 0 && (ap->a_mode & O_NONBLOCK)) {
error = ENXIO;
} else {
if (fip->fi_writers == 1) {
fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
if (fip->fi_readers > 0)
wakeup((caddr_t)&fip->fi_readers);
if (fip->fi_writers == 1) {
fip->fi_readsock->so_state &= ~SS_CANTRCVMORE;
if (fip->fi_readers > 0)
wakeup((caddr_t)&fip->fi_readers);
}
}
if ((ap->a_mode & FREAD) && (ap->a_mode & O_NONBLOCK) == 0) {
while (fip->fi_writers == 0) {
VOP_UNLOCK(vp, 0, p);
error = tsleep((caddr_t)&fip->fi_readers,
PCATCH | PSOCK, openstr, 0);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (error)
goto bad;
}
}
if (ap->a_mode & FWRITE) {
if (ap->a_mode & O_NONBLOCK) {
if (fip->fi_readers == 0) {
error = ENXIO;
goto bad;
}
} else {
while (fip->fi_readers == 0) {
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, 0, p);
error = tsleep((caddr_t)&fip->fi_writers,
PCATCH | PSOCK, openstr, 0);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
if (error)
break;
goto bad;
}
}
}
if (error)
VOP_CLOSE(vp, ap->a_mode, ap->a_cred, ap->a_p);
return (0);
bad:
VOP_CLOSE(vp, ap->a_mode, ap->a_cred, p);
return (error);
}
@ -255,8 +247,9 @@ fifo_read(ap)
struct ucred *a_cred;
} */ *ap;
{
register struct uio *uio = ap->a_uio;
register struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
struct uio *uio = ap->a_uio;
struct socket *rso = ap->a_vp->v_fifoinfo->fi_readsock;
struct proc *p = uio->uio_procp;
int error, startresid;
#ifdef DIAGNOSTIC
@ -268,10 +261,10 @@ fifo_read(ap)
if (ap->a_ioflag & IO_NDELAY)
rso->so_state |= SS_NBIO;
startresid = uio->uio_resid;
VOP_UNLOCK(ap->a_vp);
error = soreceive(rso, (struct mbuf **)0, uio,
(struct mbuf **)0, (struct mbuf **)0, (int*)0);
VOP_LOCK(ap->a_vp);
VOP_UNLOCK(ap->a_vp, 0, p);
error = soreceive(rso, (struct mbuf **)0, uio, (struct mbuf **)0,
(struct mbuf **)0, (int *)0);
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p);
/*
* Clear EOF indication after first such return.
*/
@ -296,6 +289,7 @@ fifo_write(ap)
} */ *ap;
{
struct socket *wso = ap->a_vp->v_fifoinfo->fi_writesock;
struct proc *p = ap->a_uio->uio_procp;
int error;
#ifdef DIAGNOSTIC
@ -304,9 +298,9 @@ fifo_write(ap)
#endif
if (ap->a_ioflag & IO_NDELAY)
wso->so_state |= SS_NBIO;
VOP_UNLOCK(ap->a_vp);
VOP_UNLOCK(ap->a_vp, 0, p);
error = sosend(wso, (struct mbuf *)0, ap->a_uio, 0, (struct mbuf *)0, 0);
VOP_LOCK(ap->a_vp);
vn_lock(ap->a_vp, LK_EXCLUSIVE | LK_RETRY, p);
if (ap->a_ioflag & IO_NDELAY)
wso->so_state &= ~SS_NBIO;
return (error);
@ -328,14 +322,23 @@ fifo_ioctl(ap)
} */ *ap;
{
struct file filetmp;
int error;
if (ap->a_command == FIONBIO)
return (0);
if (ap->a_fflag & FREAD)
if (ap->a_fflag & FREAD) {
filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock;
else
error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p);
if (error)
return (error);
}
if (ap->a_fflag & FWRITE) {
filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock;
return (soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p));
error = soo_ioctl(&filetmp, ap->a_command, ap->a_data, ap->a_p);
if (error)
return (error);
}
return (0);
}
/* ARGSUSED */
@ -350,12 +353,33 @@ fifo_select(ap)
} */ *ap;
{
struct file filetmp;
int ready;
if (ap->a_fflags & FREAD)
if (ap->a_fflags & FREAD) {
filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_readsock;
else
ready = soo_select(&filetmp, ap->a_which, ap->a_p);
if (ready)
return (ready);
}
if (ap->a_fflags & FWRITE) {
filetmp.f_data = (caddr_t)ap->a_vp->v_fifoinfo->fi_writesock;
return (soo_select(&filetmp, ap->a_which, ap->a_p));
ready = soo_select(&filetmp, ap->a_which, ap->a_p);
if (ready)
return (ready);
}
return (0);
}
int
fifo_inactive(ap)
struct vop_inactive_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
return (0);
}
/*
@ -384,31 +408,6 @@ fifo_bmap(ap)
return (0);
}
/*
* At the moment we do not do any locking.
*/
/* ARGSUSED */
static int
fifo_lock(ap)
struct vop_lock_args /* {
struct vnode *a_vp;
} */ *ap;
{
return (0);
}
/* ARGSUSED */
static int
fifo_unlock(ap)
struct vop_unlock_args /* {
struct vnode *a_vp;
} */ *ap;
{
return (0);
}
/*
* Device close routine
*/
@ -426,16 +425,16 @@ fifo_close(ap)
register struct fifoinfo *fip = vp->v_fifoinfo;
int error1, error2;
if (ap->a_fflag & FWRITE) {
fip->fi_writers--;
if (fip->fi_writers == 0)
socantrcvmore(fip->fi_readsock);
}
if (ap->a_fflag & FREAD) {
fip->fi_readers--;
if (fip->fi_readers == 0)
socantsendmore(fip->fi_writesock);
}
if (ap->a_fflag & FWRITE) {
fip->fi_writers--;
if (fip->fi_writers == 0)
socantrcvmore(fip->fi_readsock);
}
if (vp->v_usecount > 1)
return (0);
error1 = soclose(fip->fi_readsock);

View File

@ -124,7 +124,7 @@ msdosfs_hashget(dev, dirclust, diroff)
(void) tsleep((caddr_t)dep, PINOD, "msdhgt", 0);
break;
}
if (!vget(DETOV(dep), 1))
if (!vget(DETOV(dep), LK_EXCLUSIVE | LK_INTERLOCK, curproc))
return dep;
break;
}
@ -259,7 +259,7 @@ deget(pmp, dirclust, diroffset, direntptr, depp)
* can't be accessed until we've read it in and have done what we
* need to it.
*/
VOP_LOCK(nvp);
vn_lock(nvp, LK_EXCLUSIVE | LK_RETRY, curproc);
msdosfs_hashins(ldep);
/*
@ -716,7 +716,7 @@ msdosfs_inactive(ap)
printf("msdosfs_inactive(): dep %p, refcnt %ld, mntflag %x, MNT_RDONLY %x\n",
dep, dep->de_refcnt, vp->v_mount->mnt_flag, MNT_RDONLY);
#endif
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, curproc);
if (dep->de_refcnt <= 0 && (vp->v_mount->mnt_flag & MNT_RDONLY) == 0) {
error = detrunc(dep, (u_long) 0, 0, NOCRED, NULL);
dep->de_flag |= DE_UPDATE;
@ -726,7 +726,7 @@ msdosfs_inactive(ap)
TIMEVAL_TO_TIMESPEC(&time, &ts);
deupdat(dep, &ts, 0);
}
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, 0, curproc);
dep->de_flag = 0;
/*

View File

@ -54,6 +54,7 @@
#include <sys/vnode.h>
#include <sys/mount.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <msdosfs/bpb.h>
#include <msdosfs/direntry.h>
@ -156,14 +157,14 @@ msdosfs_lookup(ap)
VREF(vdp);
error = 0;
} else if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp);
error = vget(vdp, 1);
VOP_UNLOCK(pdp, 0, curproc);
error = vget(vdp, LK_EXCLUSIVE | LK_INTERLOCK, curproc);
if (!error && lockparent && (flags & ISLASTCN))
error = VOP_LOCK(pdp);
error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc);
} else {
error = vget(vdp, 1);
error = vget(vdp, LK_EXCLUSIVE | LK_INTERLOCK, curproc);
if (!lockparent || error || !(flags & ISLASTCN))
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, curproc);
}
if (!error) {
@ -183,9 +184,9 @@ msdosfs_lookup(ap)
}
vput(vdp);
if (lockparent && pdp != vdp && (flags & ISLASTCN))
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, curproc);
}
error = VOP_LOCK(pdp);
error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc);
if (error)
return error;
vdp = pdp;
@ -345,7 +346,7 @@ notfound:;
/* dp->de_flag |= DE_UPDATE; never update dos directories */
cnp->cn_flags |= SAVENAME;
if (!lockparent)/* leave searched dir locked? */
VOP_UNLOCK(vdp);
VOP_UNLOCK(vdp, 0, curproc);
return EJUSTRETURN;
}
/*
@ -398,7 +399,7 @@ foundroot:;
}
*vpp = DETOV(tdp);
if (!lockparent)
VOP_UNLOCK(vdp);
VOP_UNLOCK(vdp, 0, curproc);
if (bp)
brelse(bp);
return 0;
@ -428,7 +429,7 @@ foundroot:;
*vpp = DETOV(tdp);
cnp->cn_flags |= SAVENAME;
if (!lockparent)
VOP_UNLOCK(vdp);
VOP_UNLOCK(vdp, 0, curproc);
if (bp)
brelse(bp);
return 0;
@ -439,16 +440,16 @@ foundroot:;
*/
pdp = vdp;
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, curproc);
error = deget(pmp, cluster, diroff, dep, &tdp);
if (error) {
VOP_LOCK(pdp);
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc);
if (bp)
brelse(bp);
return error;
}
if (lockparent && (flags & ISLASTCN)
&& (error = VOP_LOCK(pdp))) {
&& (error = vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, curproc))) {
vput(DETOV(tdp));
return error;
}
@ -464,7 +465,7 @@ foundroot:;
return error;
}
if (!lockparent || !(flags & ISLASTCN))
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, curproc);
*vpp = DETOV(tdp);
}
if (bp)

View File

@ -130,10 +130,10 @@ msdosfs_mount(mp, path, data, ndp, p)
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
if (vfs_busy(mp))
if (vfs_busy(mp, LK_NOWAIT, 0, p))
return EBUSY;
error = vflush(mp, NULLVP, flags);
vfs_unbusy(mp);
vfs_unbusy(mp, p);
}
if (!error && (mp->mnt_flag & MNT_RELOAD))
/* not yet implemented */
@ -707,7 +707,7 @@ msdosfs_sync(mp, waitfor, cred, p)
if ((dep->de_flag & (DE_MODIFIED | DE_UPDATE)) == 0 &&
vp->v_dirtyblkhd.lh_first == NULL)
continue;
if (vget(vp, 1)) /* not there anymore? */
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p)) /* not there anymore? */
goto loop;
error = VOP_FSYNC(vp, cred, waitfor, p);
if (error)

View File

@ -1172,17 +1172,17 @@ msdosfs_rename(ap)
*/
if (newparent == 0) {
/* tddep and fddep point to the same denode here */
VOP_LOCK(ap->a_fvp); /* ap->a_fdvp is already locked */
vn_lock(ap->a_fvp, LK_EXCLUSIVE | LK_RETRY, curproc); /* ap->a_fdvp is already locked */
error = readep(fddep->de_pmp, fdep->de_dirclust,
fdep->de_diroffset, &bp, &ep);
if (error) {
VOP_UNLOCK(ap->a_fvp);
VOP_UNLOCK(ap->a_fvp, 0, curproc);
goto bad;
}
bcopy(toname, ep->deName, 11);
error = bwrite(bp);
if (error) {
VOP_UNLOCK(ap->a_fvp);
VOP_UNLOCK(ap->a_fvp, 0, curproc);
goto bad;
}
bcopy(toname, fdep->de_Name, 11); /* update denode */
@ -1204,7 +1204,7 @@ msdosfs_rename(ap)
* will also insure that the directory entry on disk has a
* filesize of zero.
*/
VOP_LOCK(ap->a_fvp);
vn_lock(ap->a_fvp, LK_EXCLUSIVE | LK_RETRY, curproc);
bcopy(toname, fdep->de_Name, 11); /* update denode */
if (fdep->de_Attributes & ATTR_DIRECTORY) {
dirsize = fdep->de_FileSize;
@ -1216,22 +1216,22 @@ msdosfs_rename(ap)
}
if (error) {
/* should put back filename */
VOP_UNLOCK(ap->a_fvp);
VOP_UNLOCK(ap->a_fvp, 0, curproc);
goto bad;
}
VOP_LOCK(ap->a_fdvp);
vn_lock(ap->a_fdvp, LK_EXCLUSIVE | LK_RETRY, curproc);
error = readep(fddep->de_pmp, fddep->de_fndclust,
fddep->de_fndoffset, &bp, &ep);
if (error) {
VOP_UNLOCK(ap->a_fvp);
VOP_UNLOCK(ap->a_fdvp);
VOP_UNLOCK(ap->a_fvp, 0, curproc);
VOP_UNLOCK(ap->a_fdvp, 0, curproc);
goto bad;
}
ep->deName[0] = SLOT_DELETED;
error = bwrite(bp);
if (error) {
VOP_UNLOCK(ap->a_fvp);
VOP_UNLOCK(ap->a_fdvp);
VOP_UNLOCK(ap->a_fvp, 0, curproc);
VOP_UNLOCK(ap->a_fdvp, 0, curproc);
goto bad;
}
if (!sourceisadirectory) {
@ -1239,7 +1239,7 @@ msdosfs_rename(ap)
fdep->de_diroffset = tddep->de_fndoffset;
reinsert(fdep);
}
VOP_UNLOCK(ap->a_fdvp);
VOP_UNLOCK(ap->a_fdvp, 0, curproc);
}
/* fdep is still locked here */
@ -1259,19 +1259,19 @@ msdosfs_rename(ap)
NOCRED, &bp);
if (error) {
/* should really panic here, fs is corrupt */
VOP_UNLOCK(ap->a_fvp);
VOP_UNLOCK(ap->a_fvp, 0, curproc);
goto bad;
}
dotdotp = (struct direntry *) bp->b_data + 1;
putushort(dotdotp->deStartCluster, tddep->de_StartCluster);
error = bwrite(bp);
VOP_UNLOCK(ap->a_fvp);
VOP_UNLOCK(ap->a_fvp, 0, curproc);
if (error) {
/* should really panic here, fs is corrupt */
goto bad;
}
} else
VOP_UNLOCK(ap->a_fvp);
VOP_UNLOCK(ap->a_fvp, 0, curproc);
bad: ;
vrele(DETOV(fdep));
vrele(DETOV(fddep));

View File

@ -169,3 +169,15 @@ struct msdosfsmount {
(((size) + (pmp)->pm_bpcluster - 1) >> (pmp)->pm_cnshift)
int msdosfs_init __P((void));
/*
* Arguments to mount MSDOS filesystems.
*/
struct msdosfs_args {
char *fspec; /* blocks special holding the fs to mount */
struct export_args export; /* network export information */
uid_t uid; /* uid that owns msdosfs files */
gid_t gid; /* gid that owns msdosfs files */
mode_t mask; /* mask to be applied for msdosfs perms */
};

View File

@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)null.h 8.2 (Berkeley) 1/21/94
* @(#)null.h 8.3 (Berkeley) 8/20/94
*
* $FreeBSD$
*/
@ -52,8 +52,7 @@ struct null_mount {
* A cache of vnode references
*/
struct null_node {
struct null_node *null_forw; /* Hash chain */
struct null_node *null_back;
LIST_ENTRY(null_node) null_hash; /* Hash list */
struct vnode *null_lowervp; /* VREFed once */
struct vnode *null_vnode; /* Back pointer */
};

View File

@ -33,13 +33,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)null_subr.c 8.4 (Berkeley) 1/21/94
* @(#)null_subr.c 8.7 (Berkeley) 5/14/95
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/vnode.h>
@ -48,11 +49,8 @@
#include <sys/malloc.h>
#include <miscfs/nullfs/null.h>
extern int nullfs_init __P((void));
#define LOG2_SIZEVNODE 7 /* log2(sizeof struct vnode) */
#define NNULLNODECACHE 16
#define NULL_NHASH(vp) ((((u_long)vp)>>LOG2_SIZEVNODE) & (NNULLNODECACHE-1))
/*
* Null layer cache:
@ -62,50 +60,31 @@ extern int nullfs_init __P((void));
* alias is removed the lower vnode is vrele'd.
*/
/*
* Cache head
*/
struct null_node_cache {
struct null_node *ac_forw;
struct null_node *ac_back;
};
static struct null_node_cache null_node_cache[NNULLNODECACHE];
#define NULL_NHASH(vp) \
(&null_node_hashtbl[(((u_long)vp)>>LOG2_SIZEVNODE) & null_node_hash])
LIST_HEAD(null_node_hashhead, null_node) *null_node_hashtbl;
u_long null_node_hash;
static int null_node_alloc __P((struct mount *mp, struct vnode *lowervp,
struct vnode **vpp));
static struct vnode *
null_node_find __P((struct mount *mp, struct vnode *lowervp));
static struct null_node_cache *
null_node_hash __P((struct vnode *lowervp));
/*
* Initialise cache headers
*/
int
nullfs_init()
nullfs_init(vfsp)
struct vfsconf *vfsp;
{
struct null_node_cache *ac;
#ifdef NULLFS_DIAGNOSTIC
printf("nullfs_init\n"); /* printed during system boot */
#endif
for (ac = null_node_cache; ac < null_node_cache + NNULLNODECACHE; ac++)
ac->ac_forw = ac->ac_back = (struct null_node *) ac;
null_node_hashtbl = hashinit(NNULLNODECACHE, M_CACHE, &null_node_hash);
return (0);
}
/*
* Compute hash list for given lower vnode
*/
static struct null_node_cache *
null_node_hash(lowervp)
struct vnode *lowervp;
{
return (&null_node_cache[NULL_NHASH(lowervp)]);
}
/*
* Return a VREF'ed alias for lower vnode if already exists, else 0.
*/
@ -114,7 +93,8 @@ null_node_find(mp, lowervp)
struct mount *mp;
struct vnode *lowervp;
{
struct null_node_cache *hd;
struct proc *p = curproc; /* XXX */
struct null_node_hashhead *hd;
struct null_node *a;
struct vnode *vp;
@ -124,9 +104,9 @@ null_node_find(mp, lowervp)
* the lower vnode. If found, the increment the null_node
* reference count (but NOT the lower vnode's VREF counter).
*/
hd = null_node_hash(lowervp);
hd = NULL_NHASH(lowervp);
loop:
for (a = hd->ac_forw; a != (struct null_node *) hd; a = a->null_forw) {
for (a = hd->lh_first; a != 0; a = a->null_hash.le_next) {
if (a->null_lowervp == lowervp && NULLTOV(a)->v_mount == mp) {
vp = NULLTOV(a);
/*
@ -134,7 +114,7 @@ null_node_find(mp, lowervp)
* stuff, but we don't want to lock
* the lower node.
*/
if (vget(vp, 0)) {
if (vget(vp, 0, p)) {
printf ("null_node_find: vget failed.\n");
goto loop;
};
@ -157,7 +137,7 @@ null_node_alloc(mp, lowervp, vpp)
struct vnode *lowervp;
struct vnode **vpp;
{
struct null_node_cache *hd;
struct null_node_hashhead *hd;
struct null_node *xp;
struct vnode *othervp, *vp;
int error;
@ -194,8 +174,8 @@ null_node_alloc(mp, lowervp, vpp)
return 0;
};
VREF(lowervp); /* Extra VREF will be vrele'd in null_node_create */
hd = null_node_hash(lowervp);
insque(xp, hd);
hd = NULL_NHASH(lowervp);
LIST_INSERT_HEAD(hd, xp, null_hash);
return 0;
}
@ -250,9 +230,8 @@ null_node_create(mp, lowervp, newvpp)
#ifdef DIAGNOSTIC
if (lowervp->v_usecount < 1) {
/* Should never happen... */
vprint ("null_node_create: alias ",aliasvp);
vprint ("null_node_create: lower ",lowervp);
printf ("null_node_create: lower has 0 usecount.\n");
vprint ("null_node_create: alias ", aliasvp);
vprint ("null_node_create: lower ", lowervp);
panic ("null_node_create: lower has 0 usecount.");
};
#endif

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1992, 1993
* Copyright (c) 1992, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
@ -46,7 +46,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/vnode.h>
@ -55,7 +55,7 @@
#include <sys/malloc.h>
#include <miscfs/nullfs/null.h>
extern int nullfs_init __P((void));
extern int nullfs_init __P((struct vfsconf *));
static int nullfs_fhtovp __P((struct mount *mp, struct fid *fidp,
struct mbuf *nam, struct vnode **vpp,
@ -146,7 +146,7 @@ nullfs_mount(mp, path, data, ndp, p)
/*
* Unlock the node (either the lower or the alias)
*/
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, 0, p);
/*
* Make sure the node alias worked
*/
@ -166,7 +166,7 @@ nullfs_mount(mp, path, data, ndp, p)
if (NULLVPTOLOWERVP(nullm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_data = (qaddr_t) xmp;
getnewfsid(mp, MOUNT_LOFS);
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
@ -212,12 +212,8 @@ nullfs_unmount(mp, mntflags, p)
printf("nullfs_unmount(mp = %x)\n", mp);
#endif
if (mntflags & MNT_FORCE) {
/* lofs can never be rootfs so don't check for it */
if (!doforce)
return (EINVAL);
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
}
/*
* Clear out buffer cache. I don't think we
@ -259,6 +255,7 @@ nullfs_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
struct proc *p = curproc; /* XXX */
struct vnode *vp;
#ifdef NULLFS_DIAGNOSTIC
@ -273,7 +270,7 @@ nullfs_root(mp, vpp)
*/
vp = MOUNTTONULLMOUNT(mp)->nullm_rootvp;
VREF(vp);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
*vpp = vp;
return 0;
}

View File

@ -33,7 +33,13 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)null_vnops.c 8.1 (Berkeley) 6/10/93
* @(#)null_vnops.c 8.6 (Berkeley) 5/27/95
*
* Ancestors:
* @(#)lofs_vnops.c 1.2 (Berkeley) 6/18/92
* $Id: null_vnops.c,v 1.11.2000.1 1996/09/17 14:32:31 peter Exp $
* ...and...
* @(#)null_vnodeops.c 1.20 92/07/07 UCLA Ficus project
*
* $FreeBSD$
*/
@ -88,13 +94,21 @@
* in the arguments and, if a vnode is return by the operation,
* stacks a null-node on top of the returned vnode.
*
* Although bypass handles most operations,
* vop_getattr, _inactive, _reclaim, and _print are not bypassed.
* Vop_getattr must change the fsid being returned.
* Although bypass handles most operations, vop_getattr, vop_lock,
* vop_unlock, vop_inactive, vop_reclaim, and vop_print are not
* bypassed. Vop_getattr must change the fsid being returned.
* Vop_lock and vop_unlock must handle any locking for the
* current vnode as well as pass the lock request down.
* Vop_inactive and vop_reclaim are not bypassed so that
* they can handle freeing null-layer specific data.
* Vop_print is not bypassed to avoid excessive debugging
* information.
* they can handle freeing null-layer specific data. Vop_print
* is not bypassed to avoid excessive debugging information.
* Also, certain vnode operations change the locking state within
* the operation (create, mknod, remove, link, rename, mkdir, rmdir,
* and symlink). Ideally these operations should not change the
* lock state, but should be changed to let the caller of the
* function unlock them. Otherwise all intermediate vnode layers
* (such as union, umapfs, etc) must catch these functions to do
* the necessary locking at their layer.
*
*
* INSTANTIATING VNODE STACKS
@ -178,7 +192,7 @@ static int null_bug_bypass = 0; /* for debugging: enables bypass printf'ing */
SYSCTL_INT(_debug, OID_AUTO, nullfs_bug_bypass, CTLFLAG_RW,
&null_bug_bypass, 0, "");
static int null_bypass __P((struct vop_generic_args *ap));
int null_bypass __P((struct vop_generic_args *ap));
static int null_bwrite __P((struct vop_bwrite_args *ap));
static int null_getattr __P((struct vop_getattr_args *ap));
static int null_inactive __P((struct vop_inactive_args *ap));
@ -211,7 +225,7 @@ static int null_strategy __P((struct vop_strategy_args *ap));
* - all mapped vnodes are of our vnode-type (NEEDSWORK:
* problems on rmdir'ing mount points and renaming?)
*/
static int
int
null_bypass(ap)
struct vop_generic_args /* {
struct vnodeop_desc *a_desc;
@ -254,7 +268,8 @@ null_bypass(ap)
* are of our type. Check for and don't map any
* that aren't. (We must always map first vp or vclean fails.)
*/
if (i && (*this_vp_p)->v_op != null_vnodeop_p) {
if (i && (*this_vp_p == NULL ||
(*this_vp_p)->v_op != null_vnodeop_p)) {
old_vps[i] = NULL;
} else {
old_vps[i] = *this_vp_p;
@ -317,6 +332,105 @@ null_bypass(ap)
return (error);
}
/*
* We have to carry on the locking protocol on the null layer vnodes
* as we progress through the tree. We also have to enforce read-only
* if this layer is mounted read-only.
*/
static int
null_lookup(ap)
struct vop_lookup_args /* {
struct vnode * a_dvp;
struct vnode ** a_vpp;
struct componentname * a_cnp;
} */ *ap;
{
struct componentname *cnp = ap->a_cnp;
struct proc *p = cnp->cn_proc;
int flags = cnp->cn_flags;
struct vop_lock_args lockargs;
struct vop_unlock_args unlockargs;
struct vnode *dvp, *vp;
int error;
if ((flags & ISLASTCN) && (ap->a_dvp->v_mount->mnt_flag & MNT_RDONLY) &&
(cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME))
return (EROFS);
error = null_bypass(ap);
if (error == EJUSTRETURN && (flags & ISLASTCN) &&
(ap->a_dvp->v_mount->mnt_flag & MNT_RDONLY) &&
(cnp->cn_nameiop == CREATE || cnp->cn_nameiop == RENAME))
error = EROFS;
/*
* We must do the same locking and unlocking at this layer as
* is done in the layers below us. We could figure this out
* based on the error return and the LASTCN, LOCKPARENT, and
* LOCKLEAF flags. However, it is more expidient to just find
* out the state of the lower level vnodes and set ours to the
* same state.
*/
dvp = ap->a_dvp;
vp = *ap->a_vpp;
if (dvp == vp)
return (error);
if (!VOP_ISLOCKED(dvp)) {
unlockargs.a_vp = dvp;
unlockargs.a_flags = 0;
unlockargs.a_p = p;
vop_nounlock(&unlockargs);
}
if (vp != NULL && VOP_ISLOCKED(vp)) {
lockargs.a_vp = vp;
lockargs.a_flags = LK_SHARED;
lockargs.a_p = p;
vop_nolock(&lockargs);
}
return (error);
}
/*
* Setattr call. Disallow write attempts if the layer is mounted read-only.
*/
int
null_setattr(ap)
struct vop_setattr_args /* {
struct vnodeop_desc *a_desc;
struct vnode *a_vp;
struct vattr *a_vap;
struct ucred *a_cred;
struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
struct vattr *vap = ap->a_vap;
if ((vap->va_flags != VNOVAL || vap->va_uid != (uid_t)VNOVAL ||
vap->va_gid != (gid_t)VNOVAL || vap->va_atime.ts_sec != VNOVAL ||
vap->va_mtime.ts_sec != VNOVAL || vap->va_mode != (mode_t)VNOVAL) &&
(vp->v_mount->mnt_flag & MNT_RDONLY))
return (EROFS);
if (vap->va_size != VNOVAL) {
switch (vp->v_type) {
case VDIR:
return (EISDIR);
case VCHR:
case VBLK:
case VSOCK:
case VFIFO:
return (0);
case VREG:
case VLNK:
default:
/*
* Disallow write attempts if the filesystem is
* mounted read-only.
*/
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
}
}
return (null_bypass(ap));
}
/*
* We handle getattr only to change the fsid.
@ -331,19 +445,90 @@ null_getattr(ap)
} */ *ap;
{
int error;
error = null_bypass(ap);
if (error)
if (error = null_bypass(ap))
return (error);
/* Requires that arguments be restored. */
ap->a_vap->va_fsid = ap->a_vp->v_mount->mnt_stat.f_fsid.val[0];
return (0);
}
static int
null_access(ap)
struct vop_access_args /* {
struct vnode *a_vp;
int a_mode;
struct ucred *a_cred;
struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
mode_t mode = ap->a_mode;
/*
* Disallow write attempts on read-only layers;
* unless the file is a socket, fifo, or a block or
* character device resident on the file system.
*/
if (mode & VWRITE) {
switch (vp->v_type) {
case VDIR:
case VLNK:
case VREG:
if (vp->v_mount->mnt_flag & MNT_RDONLY)
return (EROFS);
break;
}
}
return (null_bypass(ap));
}
/*
* We need to process our own vnode lock and then clear the
* interlock flag as it applies only to our vnode, not the
* vnodes below us on the stack.
*/
int
null_lock(ap)
struct vop_lock_args /* {
struct vnode *a_vp;
int a_flags;
struct proc *a_p;
} */ *ap;
{
vop_nolock(ap);
if ((ap->a_flags & LK_TYPE_MASK) == LK_DRAIN)
return (0);
ap->a_flags &= ~LK_INTERLOCK;
return (null_bypass(ap));
}
/*
* We need to process our own vnode unlock and then clear the
* interlock flag as it applies only to our vnode, not the
* vnodes below us on the stack.
*/
int
null_unlock(ap)
struct vop_unlock_args /* {
struct vnode *a_vp;
int a_flags;
struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
vop_nounlock(ap);
ap->a_flags &= ~LK_INTERLOCK;
return (null_bypass(ap));
}
int
null_inactive(ap)
struct vop_inactive_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
/*
@ -358,6 +543,7 @@ null_inactive(ap)
* like they do in the name lookup cache code.
* That's too much work for now.
*/
VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
return (0);
}
@ -365,6 +551,7 @@ static int
null_reclaim(ap)
struct vop_reclaim_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
@ -377,14 +564,13 @@ null_reclaim(ap)
*/
/* After this assignment, this node will not be re-used. */
xp->null_lowervp = NULL;
remque(xp);
LIST_REMOVE(xp, null_hash);
FREE(vp->v_data, M_TEMP);
vp->v_data = NULL;
vrele (lowervp);
return (0);
}
static int
null_print(ap)
struct vop_print_args /* {
@ -396,7 +582,6 @@ null_print(ap)
return (0);
}
/*
* XXX - vop_strategy must be hand coded because it has no
* vnode in its arguments.
@ -422,7 +607,6 @@ null_strategy(ap)
return (error);
}
/*
* XXX - like vop_strategy, vop_bwrite must be hand coded because it has no
* vnode in its arguments.
@ -455,7 +639,12 @@ vop_t **null_vnodeop_p;
static struct vnodeopv_entry_desc null_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *)null_bypass },
{ &vop_lookup_desc, (vop_t *)null_lookup },
{ &vop_setattr_desc, (vop_t *)null_setattr },
{ &vop_getattr_desc, (vop_t *)null_getattr },
{ &vop_access_desc, (vop_t *)null_access },
{ &vop_lock_desc, (vop_t *)null_lock },
{ &vop_unlock_desc, (vop_t *)null_unlock },
{ &vop_inactive_desc, (vop_t *)null_inactive },
{ &vop_reclaim_desc, (vop_t *)null_reclaim },
{ &vop_print_desc, (vop_t *)null_print },

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1992, 1993
* Copyright (c) 1992, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)portal_vfsops.c 8.6 (Berkeley) 1/21/94
* @(#)portal_vfsops.c 8.11 (Berkeley) 5/14/95
*
* $FreeBSD$
*/
@ -62,28 +62,18 @@
#include <sys/un.h>
#include <miscfs/portal/portal.h>
static int portal_init __P((void));
static int portal_mount __P((struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p));
static int portal_start __P((struct mount *mp, int flags, struct proc *p));
static int portal_unmount __P((struct mount *mp, int mntflags,
struct proc *p));
static int portal_root __P((struct mount *mp, struct vnode **vpp));
static int portal_quotactl __P((struct mount *mp, int cmd, uid_t uid,
caddr_t arg, struct proc *p));
static int portal_statfs __P((struct mount *mp, struct statfs *sbp,
struct proc *p));
static int portal_sync __P((struct mount *mp, int waitfor,
struct ucred *cred, struct proc *p));
static int portal_vget __P((struct mount *mp, ino_t ino,
struct vnode **vpp));
static int portal_fhtovp __P((struct mount *mp, struct fid *fhp,
struct mbuf *nam, struct vnode **vpp,
int *exflagsp, struct ucred **credanonp));
static int portal_vptofh __P((struct vnode *vp, struct fid *fhp));
static int
portal_init()
portal_init(vfsp)
struct vfsconf *vfsp;
{
return (0);
@ -150,7 +140,7 @@ portal_mount(mp, path, data, ndp, p)
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_data = (qaddr_t) fmp;
getnewfsid(mp, MOUNT_PORTAL);
vfs_getnewfsid(mp);
(void)copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
@ -186,12 +176,8 @@ portal_unmount(mp, mntflags, p)
int error, flags = 0;
if (mntflags & MNT_FORCE) {
/* portal can never be rootfs so don't check for it */
if (!doforce)
return (EINVAL);
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
}
/*
* Clear out buffer cache. I don't think we
@ -241,31 +227,19 @@ portal_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
struct proc *p = curproc; /* XXX */
struct vnode *vp;
/*
* Return locked reference to root.
*/
vp = VFSTOPORTAL(mp)->pm_root;
VREF(vp);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
*vpp = vp;
return (0);
}
static int
portal_quotactl(mp, cmd, uid, arg, p)
struct mount *mp;
int cmd;
uid_t uid;
caddr_t arg;
struct proc *p;
{
return (EOPNOTSUPP);
}
static int
portal_statfs(mp, sbp, p)
struct mount *mp;
@ -273,7 +247,6 @@ portal_statfs(mp, sbp, p)
struct proc *p;
{
sbp->f_type = MOUNT_PORTAL;
sbp->f_flags = 0;
sbp->f_bsize = DEV_BSIZE;
sbp->f_iosize = DEV_BSIZE;
@ -283,6 +256,7 @@ portal_statfs(mp, sbp, p)
sbp->f_files = 1; /* Allow for "." */
sbp->f_ffree = 0; /* See comments above */
if (sbp != &mp->mnt_stat) {
sbp->f_type = mp->mnt_vfc->vfc_typenum;
bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
@ -290,48 +264,17 @@ portal_statfs(mp, sbp, p)
return (0);
}
static int
portal_sync(mp, waitfor, cred, p)
struct mount *mp;
int waitfor;
struct ucred *cred;
struct proc *p;
{
return (0);
}
static int
portal_vget(mp, ino, vpp)
struct mount *mp;
ino_t ino;
struct vnode **vpp;
{
return (EOPNOTSUPP);
}
static int
portal_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
struct mount *mp;
struct fid *fhp;
struct mbuf *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
return (EOPNOTSUPP);
}
static int
portal_vptofh(vp, fhp)
struct vnode *vp;
struct fid *fhp;
{
return (EOPNOTSUPP);
}
#define portal_fhtovp ((int (*) __P((struct mount *, struct fid *, \
struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp)
#define portal_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \
struct proc *)))eopnotsupp)
#define portal_sync ((int (*) __P((struct mount *, int, struct ucred *, \
struct proc *)))nullop)
#define portal_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
size_t, struct proc *)))eopnotsupp)
#define portal_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \
eopnotsupp)
#define portal_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp)
static struct vfsops portal_vfsops = {
portal_mount,

View File

@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)portal_vnops.c 8.8 (Berkeley) 1/21/94
* @(#)portal_vnops.c 8.14 (Berkeley) 5/21/95
*
* $FreeBSD$
*/
@ -112,17 +112,25 @@ portal_lookup(ap)
struct componentname * a_cnp;
} */ *ap;
{
char *pname = ap->a_cnp->cn_nameptr;
struct componentname *cnp = ap->a_cnp;
struct vnode **vpp = ap->a_vpp;
struct vnode *dvp = ap->a_dvp;
char *pname = cnp->cn_nameptr;
struct portalnode *pt;
int error;
struct vnode *fvp = 0;
char *path;
int size;
if (ap->a_cnp->cn_namelen == 1 && *pname == '.') {
*ap->a_vpp = ap->a_dvp;
VREF(ap->a_dvp);
/*VOP_LOCK(ap->a_dvp);*/
*vpp = NULLVP;
if (cnp->cn_nameiop == DELETE || cnp->cn_nameiop == RENAME)
return (EROFS);
if (cnp->cn_namelen == 1 && *pname == '.') {
*vpp = dvp;
VREF(dvp);
/*VOP_LOCK(dvp);*/
return (0);
}
@ -134,7 +142,7 @@ portal_lookup(ap)
MALLOC(pt, struct portalnode *, sizeof(struct portalnode),
M_TEMP, M_WAITOK);
error = getnewvnode(VT_PORTAL, ap->a_dvp->v_mount, portal_vnodeop_p, &fvp);
error = getnewvnode(VT_PORTAL, dvp->v_mount, portal_vnodeop_p, &fvp);
if (error) {
FREE(pt, M_TEMP);
goto bad;
@ -148,22 +156,20 @@ portal_lookup(ap)
*/
for (size = 0, path = pname; *path; path++)
size++;
ap->a_cnp->cn_consume = size - ap->a_cnp->cn_namelen;
cnp->cn_consume = size - cnp->cn_namelen;
pt->pt_arg = malloc(size+1, M_TEMP, M_WAITOK);
pt->pt_size = size+1;
bcopy(pname, pt->pt_arg, pt->pt_size);
pt->pt_fileid = portal_fileid++;
*ap->a_vpp = fvp;
*vpp = fvp;
/*VOP_LOCK(fvp);*/
return (0);
bad:;
if (fvp) {
if (fvp)
vrele(fvp);
}
*ap->a_vpp = NULL;
return (error);
}
@ -444,6 +450,7 @@ portal_getattr(ap)
{
struct vnode *vp = ap->a_vp;
struct vattr *vap = ap->a_vap;
struct timeval tv;
bzero(vap, sizeof(*vap));
vattr_null(vap);
@ -452,8 +459,8 @@ portal_getattr(ap)
vap->va_fsid = vp->v_mount->mnt_stat.f_fsid.val[0];
vap->va_size = DEV_BSIZE;
vap->va_blocksize = DEV_BSIZE;
microtime((struct timeval *)&vap->va_atime);
TIMEVAL_TO_TIMESPEC((struct timeval *)&vap->va_atime, (struct timespec *)&vap->va_atime);
microtime(&tv);
TIMEVAL_TO_TIMESPEC(&tv, &vap->va_atime);
vap->va_mtime = vap->va_atime;
vap->va_ctime = vap->va_ctime;
vap->va_gen = 0;
@ -509,9 +516,19 @@ portal_readdir(ap)
struct vnode *a_vp;
struct uio *a_uio;
struct ucred *a_cred;
int *a_eofflag;
u_long *a_cookies;
int a_ncookies;
} */ *ap;
{
/*
* We don't allow exporting portal mounts, and currently local
* requests do not need cookies.
*/
if (ap->a_ncookies)
panic("portal_readdir: not hungry");
return (0);
}
@ -519,9 +536,11 @@ static int
portal_inactive(ap)
struct vop_inactive_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
return (0);
}
@ -639,6 +658,7 @@ portal_badop()
#define portal_ioctl ((int (*) __P((struct vop_ioctl_args *)))portal_enotsupp)
#define portal_select ((int (*) __P((struct vop_select_args *)))portal_enotsupp)
#define portal_mmap ((int (*) __P((struct vop_mmap_args *)))portal_enotsupp)
#define portal_revoke vop_revoke
#define portal_fsync ((int (*) __P((struct vop_fsync_args *)))nullop)
#define portal_seek ((int (*) __P((struct vop_seek_args *)))nullop)
#define portal_remove ((int (*) __P((struct vop_remove_args *)))portal_enotsupp)
@ -651,12 +671,14 @@ portal_badop()
#define portal_readlink \
((int (*) __P((struct vop_readlink_args *)))portal_enotsupp)
#define portal_abortop ((int (*) __P((struct vop_abortop_args *)))nullop)
#define portal_lock ((int (*) __P((struct vop_lock_args *)))nullop)
#define portal_unlock ((int (*) __P((struct vop_unlock_args *)))nullop)
#define portal_lock ((int (*) __P((struct vop_lock_args *)))vop_nolock)
#define portal_unlock ((int (*) __P((struct vop_unlock_args *)))vop_nounlock)
#define portal_bmap ((int (*) __P((struct vop_bmap_args *)))portal_badop)
#define portal_strategy \
((int (*) __P((struct vop_strategy_args *)))portal_badop)
#define portal_islocked ((int (*) __P((struct vop_islocked_args *)))nullop)
#define portal_islocked \
((int (*) __P((struct vop_islocked_args *)))vop_noislocked)
#define fifo_islocked ((int(*) __P((struct vop_islocked_args *)))vop_noislocked)
#define portal_advlock \
((int (*) __P((struct vop_advlock_args *)))portal_enotsupp)
#define portal_blkatoff \
@ -687,6 +709,7 @@ static struct vnodeopv_entry_desc portal_vnodeop_entries[] = {
{ &vop_ioctl_desc, (vop_t *)portal_ioctl }, /* ioctl */
{ &vop_select_desc, (vop_t *)portal_select }, /* select */
{ &vop_mmap_desc, (vop_t *)portal_mmap }, /* mmap */
{ &vop_revoke_desc, (vop_t *)portal_revoke }, /* revoke */
{ &vop_fsync_desc, (vop_t *)portal_fsync }, /* fsync */
{ &vop_seek_desc, (vop_t *)portal_seek }, /* seek */
{ &vop_remove_desc, (vop_t *)portal_remove }, /* remove */

View File

@ -34,8 +34,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)procfs.h 8.6 (Berkeley) 2/3/94
* @(#)procfs.h 8.9 (Berkeley) 5/14/95
*
* From:
* $FreeBSD$
*/
@ -44,6 +45,7 @@
*/
typedef enum {
Proot, /* the filesystem root */
Pcurproc, /* symbolic link for curproc */
Pproc, /* a process-specific sub-directory */
Pfile, /* the executable file */
Pmem, /* the process's memory image */
@ -97,9 +99,9 @@ struct pfsdent {
};
#define UIO_MX sizeof(struct pfsdent)
#define PROCFS_FILENO(pid, type) \
(((type) == Proot) ? \
2 : \
((((pid)+1) << 3) + ((int) (type))))
(((type) < Pproc) ? \
((type) + 2) : \
((((pid)+1) << 4) + ((int) (type))))
/*
* Convert between pfsnode vnode
@ -113,33 +115,33 @@ struct vfs_namemap {
int nm_val;
};
extern int vfs_getuserstr __P((struct uio *, char *, int *));
extern vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int));
int vfs_getuserstr __P((struct uio *, char *, int *));
vfs_namemap_t *vfs_findname __P((vfs_namemap_t *, char *, int));
/* <machine/reg.h> */
struct reg;
struct fpreg;
#define PFIND(pid) ((pid) ? pfind(pid) : &proc0)
extern int procfs_freevp __P((struct vnode *));
extern int procfs_allocvp __P((struct mount *, struct vnode **, long, pfstype));
extern struct vnode *procfs_findtextvp __P((struct proc *));
extern int procfs_sstep __P((struct proc *));
extern void procfs_fix_sstep __P((struct proc *));
extern int procfs_read_regs __P((struct proc *, struct reg *));
extern int procfs_write_regs __P((struct proc *, struct reg *));
extern int procfs_read_fpregs __P((struct proc *, struct fpreg *));
extern int procfs_write_fpregs __P((struct proc *, struct fpreg *));
extern int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_dofpregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
extern int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_freevp __P((struct vnode *));
int procfs_allocvp __P((struct mount *, struct vnode **, long, pfstype));
struct vnode *procfs_findtextvp __P((struct proc *));
int procfs_sstep __P((struct proc *));
void procfs_fix_sstep __P((struct proc *));
int procfs_read_regs __P((struct proc *, struct reg *));
int procfs_write_regs __P((struct proc *, struct reg *));
int procfs_read_fpregs __P((struct proc *, struct fpreg *));
int procfs_write_fpregs __P((struct proc *, struct fpreg *));
int procfs_donote __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_doregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_dofpregs __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_domem __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_doctl __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_dostatus __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_domap __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
int procfs_dotype __P((struct proc *, struct proc *, struct pfsnode *pfsp, struct uio *uio));
/* check to see if the process has the "items" (regs/file) */
/* functions to check whether or not files should be displayed */
int procfs_validfile __P((struct proc *));
int procfs_validfpregs __P((struct proc *));
int procfs_validregs __P((struct proc *));

View File

@ -34,8 +34,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)procfs_ctl.c 8.3 (Berkeley) 1/21/94
* @(#)procfs_ctl.c 8.4 (Berkeley) 6/15/94
*
* From:
* $FreeBSD$
*/
@ -51,13 +52,13 @@
#include <sys/resourcevar.h>
#include <sys/signal.h>
#include <sys/signalvar.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_extern.h>
#include <sys/ptrace.h>
#include <miscfs/procfs/procfs.h>
#ifndef FIX_SSTEP
#define FIX_SSTEP(p)
#endif
/*
* True iff process (p) is in trace wait state
* relative to process (curp)
@ -67,13 +68,6 @@
(p)->p_pptr == (curp) && \
((p)->p_flag & P_TRACED))
#ifdef notdef
#define FIX_SSTEP(p) { \
procfs_fix_sstep(p); \
} \
}
#endif
#define PROCFS_CTL_ATTACH 1
#define PROCFS_CTL_DETACH 2
#define PROCFS_CTL_STEP 3
@ -220,8 +214,10 @@ procfs_control(curp, p, op)
*/
case PROCFS_CTL_STEP:
PHOLD(p);
procfs_sstep(p);
error = procfs_sstep(p);
PRELE(p);
if (error)
return (error);
break;
/*

View File

@ -34,8 +34,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)procfs_fpregs.c 8.1 (Berkeley) 1/27/94
* @(#)procfs_fpregs.c 8.2 (Berkeley) 6/15/94
*
* From:
* $FreeBSD$
*/

View File

@ -59,7 +59,7 @@
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/vm_inherit.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_page.h>

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)procfs_mem.c 8.4 (Berkeley) 1/21/94
* @(#)procfs_mem.c 8.5 (Berkeley) 6/15/94
*
* $FreeBSD$
*/
@ -55,7 +55,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_kern.h>
@ -295,14 +295,11 @@ procfs_domem(curp, p, pfs, uio)
struct pfsnode *pfs;
struct uio *uio;
{
int error;
if (uio->uio_resid == 0)
return (0);
error = procfs_rwmem(p, uio);
return (error);
return (procfs_rwmem(p, uio));
}
/*
@ -320,5 +317,6 @@ struct vnode *
procfs_findtextvp(p)
struct proc *p;
{
return (p->p_textvp);
}

View File

@ -34,8 +34,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)procfs_regs.c 8.3 (Berkeley) 1/27/94
* @(#)procfs_regs.c 8.4 (Berkeley) 6/15/94
*
* From:
* $FreeBSD$
*/

View File

@ -34,8 +34,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)procfs_status.c 8.3 (Berkeley) 2/17/94
* @(#)procfs_status.c 8.4 (Berkeley) 6/15/94
*
* From:
* $FreeBSD$
*/
@ -142,7 +143,7 @@ procfs_dostatus(curp, p, pfs, uio)
xlen = ps - psbuf;
xlen -= uio->uio_offset;
ps = psbuf + uio->uio_offset;
xlen = min(xlen, uio->uio_resid);
xlen = imin(xlen, uio->uio_resid);
if (xlen <= 0)
error = 0;
else

View File

@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)procfs_subr.c 8.4 (Berkeley) 1/27/94
* @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95
*
* $FreeBSD$
*/
@ -84,18 +84,21 @@ procfs_allocvp(mp, vpp, pid, pfs_type)
long pid;
pfstype pfs_type;
{
int error;
struct proc *p = curproc; /* XXX */
struct pfsnode *pfs;
struct vnode *vp;
struct pfsnode **pp;
int error;
loop:
for (pfs = pfshead; pfs != 0; pfs = pfs->pfs_next) {
vp = PFSTOV(pfs);
if (pfs->pfs_pid == pid &&
pfs->pfs_type == pfs_type &&
PFSTOV(pfs)->v_mount == mp) {
if (vget(pfs->pfs_vnode, 0))
vp->v_mount == mp) {
if (vget(vp, 0, p))
goto loop;
*vpp = pfs->pfs_vnode;
*vpp = vp;
return (0);
}
}
@ -118,17 +121,18 @@ procfs_allocvp(mp, vpp, pid, pfs_type)
*/
MALLOC(pfs, struct pfsnode *, sizeof(struct pfsnode), M_TEMP, M_WAITOK);
error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp);
if (error) {
if (error = getnewvnode(VT_PROCFS, mp, procfs_vnodeop_p, vpp)) {
FREE(pfs, M_TEMP);
goto out;
}
vp = *vpp;
vp->v_data = pfs;
(*vpp)->v_data = pfs;
pfs->pfs_next = 0;
pfs->pfs_pid = (pid_t) pid;
pfs->pfs_type = pfs_type;
pfs->pfs_vnode = *vpp;
pfs->pfs_vnode = vp;
pfs->pfs_flags = 0;
pfs->pfs_lockowner = 0;
pfs->pfs_fileno = PROCFS_FILENO(pid, pfs_type);
@ -138,33 +142,41 @@ procfs_allocvp(mp, vpp, pid, pfs_type)
pfs->pfs_mode = (VREAD|VEXEC) |
(VREAD|VEXEC) >> 3 |
(VREAD|VEXEC) >> 6;
vp->v_type = VDIR;
vp->v_flag = VROOT;
break;
case Pcurproc: /* /proc/curproc = lr--r--r-- */
pfs->pfs_mode = (VREAD) |
(VREAD >> 3) |
(VREAD >> 6);
vp->v_type = VLNK;
break;
case Pproc:
pfs->pfs_mode = (VREAD|VEXEC) |
(VREAD|VEXEC) >> 3 |
(VREAD|VEXEC) >> 6;
vp->v_type = VDIR;
break;
case Pfile:
pfs->pfs_mode = (VREAD|VWRITE);
break;
case Pmem:
pfs->pfs_mode = (VREAD|VWRITE) |
(VREAD) >> 3;;
break;
case Pregs:
pfs->pfs_mode = (VREAD|VWRITE);
break;
case Pfpregs:
pfs->pfs_mode = (VREAD|VWRITE);
vp->v_type = VREG;
break;
case Pctl:
case Pnote:
case Pnotepg:
pfs->pfs_mode = (VWRITE);
vp->v_type = VREG;
break;
case Ptype:
@ -173,14 +185,7 @@ procfs_allocvp(mp, vpp, pid, pfs_type)
pfs->pfs_mode = (VREAD) |
(VREAD >> 3) |
(VREAD >> 6);
break;
case Pnote:
pfs->pfs_mode = (VWRITE);
break;
case Pnotepg:
pfs->pfs_mode = (VWRITE);
vp->v_type = VREG;
break;
default:
@ -316,8 +321,7 @@ vfs_getuserstr(uio, buf, buflenp)
return (EMSGSIZE);
xlen = uio->uio_resid;
error = uiomove(buf, xlen, uio);
if (error)
if (error = uiomove(buf, xlen, uio))
return (error);
/* allow multiple writes without seeks */
@ -339,6 +343,7 @@ vfs_findname(nm, buf, buflen)
char *buf;
int buflen;
{
for (; nm->nm_name; nm++)
if (bcmp(buf, nm->nm_name, buflen+1) == 0)
return (nm);

View File

@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)procfs_vfsops.c 8.4 (Berkeley) 1/21/94
* @(#)procfs_vfsops.c 8.7 (Berkeley) 5/10/95
*
* $FreeBSD$
*/
@ -56,24 +56,14 @@
#include <miscfs/procfs/procfs.h>
#include <vm/vm.h> /* for PAGE_SIZE */
static int procfs_fhtovp __P((struct mount *mp, struct fid *fhp,
struct mbuf *nam, struct vnode **vpp,
int *exflagsp, struct ucred **credanonp));
static int procfs_init __P((void));
static int procfs_init __P((struct vfsconf *vfsp));
static int procfs_mount __P((struct mount *mp, char *path, caddr_t data,
struct nameidata *ndp, struct proc *p));
static int procfs_quotactl __P((struct mount *mp, int cmds, uid_t uid,
caddr_t arg, struct proc *p));
static int procfs_start __P((struct mount *mp, int flags, struct proc *p));
static int procfs_statfs __P((struct mount *mp, struct statfs *sbp,
struct proc *p));
static int procfs_sync __P((struct mount *mp, int waitfor,
struct ucred *cred, struct proc *p));
static int procfs_unmount __P((struct mount *mp, int mntflags,
struct proc *p));
static int procfs_vget __P((struct mount *mp, ino_t ino,
struct vnode **vpp));
static int procfs_vptofh __P((struct vnode *vp, struct fid *fhp));
/*
* VFS Operations.
@ -101,7 +91,7 @@ procfs_mount(mp, path, data, ndp, p)
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_data = 0;
getnewfsid(mp, MOUNT_PROCFS);
vfs_getnewfsid(mp);
(void) copyinstr(path, (caddr_t)mp->mnt_stat.f_mntonname, MNAMELEN, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
@ -125,12 +115,8 @@ procfs_unmount(mp, mntflags, p)
int error;
int flags = 0;
if (mntflags & MNT_FORCE) {
/* procfs can never be rootfs so don't check for it */
if (!doforce)
return (EINVAL);
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
}
error = vflush(mp, 0, flags);
if (error)
@ -144,24 +130,10 @@ procfs_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
struct pfsnode *pfs;
struct vnode *vp;
int error;
error = procfs_allocvp(mp, &vp, (pid_t) 0, Proot);
if (error)
return (error);
vp->v_type = VDIR;
vp->v_flag = VROOT;
pfs = VTOPFS(vp);
*vpp = vp;
return (0);
return (procfs_allocvp(mp, vpp, 0, Proot));
}
/*
*/
/* ARGSUSED */
static int
procfs_start(mp, flags, p)
@ -182,7 +154,6 @@ procfs_statfs(mp, sbp, p)
struct statfs *sbp;
struct proc *p;
{
sbp->f_type = MOUNT_PROCFS;
sbp->f_bsize = PAGE_SIZE;
sbp->f_iosize = PAGE_SIZE;
sbp->f_blocks = 1; /* avoid divide by zero in some df's */
@ -192,6 +163,7 @@ procfs_statfs(mp, sbp, p)
sbp->f_ffree = maxproc - nprocs; /* approx */
if (sbp != &mp->mnt_stat) {
sbp->f_type = mp->mnt_vfc->vfc_typenum;
bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
@ -200,68 +172,25 @@ procfs_statfs(mp, sbp, p)
return (0);
}
static int
procfs_quotactl(mp, cmds, uid, arg, p)
struct mount *mp;
int cmds;
uid_t uid;
caddr_t arg;
struct proc *p;
{
return (EOPNOTSUPP);
}
static int
procfs_sync(mp, waitfor, cred, p)
struct mount *mp;
int waitfor;
struct ucred *cred;
struct proc *p;
procfs_init(vfsp)
struct vfsconf *vfsp;
{
return (0);
}
static int
procfs_vget(mp, ino, vpp)
struct mount *mp;
ino_t ino;
struct vnode **vpp;
{
return (EOPNOTSUPP);
}
static int
procfs_fhtovp(mp, fhp, nam, vpp, exflagsp, credanonp)
struct mount *mp;
struct fid *fhp;
struct mbuf *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
return (EINVAL);
}
static int
procfs_vptofh(vp, fhp)
struct vnode *vp;
struct fid *fhp;
{
return EINVAL;
}
static int
procfs_init()
{
return (0);
}
#define procfs_fhtovp ((int (*) __P((struct mount *, struct fid *, \
struct mbuf *, struct vnode **, int *, struct ucred **)))einval)
#define procfs_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \
struct proc *)))eopnotsupp)
#define procfs_sync ((int (*) __P((struct mount *, int, struct ucred *, \
struct proc *)))nullop)
#define procfs_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
size_t, struct proc *)))eopnotsupp)
#define procfs_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \
eopnotsupp)
#define procfs_vptofh ((int (*) __P((struct vnode *, struct fid *)))einval)
static struct vfsops procfs_vfsops = {
procfs_mount,

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1993 Jan-Simon Pendry
* Copyright (c) 1993
* Copyright (c) 1993, 1995 Jan-Simon Pendry
* Copyright (c) 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)procfs_vnops.c 8.6 (Berkeley) 2/7/94
* @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
*
* $FreeBSD$
*/
@ -55,8 +55,9 @@
#include <sys/malloc.h>
#include <sys/dirent.h>
#include <sys/resourcevar.h>
#include <miscfs/procfs/procfs.h>
#include <vm/vm.h> /* for PAGE_SIZE */
#include <machine/reg.h>
#include <miscfs/procfs/procfs.h>
static int procfs_abortop __P((struct vop_abortop_args *));
static int procfs_access __P((struct vop_access_args *));
@ -78,29 +79,30 @@ static int procfs_setattr __P((struct vop_setattr_args *));
* process-specific sub-directories. It is
* used in procfs_lookup and procfs_readdir
*/
static struct pfsnames {
u_short d_namlen;
char d_name[PROCFS_NAMELEN];
pfstype d_pfstype;
int (*d_valid) __P((struct proc *));
} procent[] = {
struct proc_target {
u_char pt_type;
u_char pt_namlen;
char *pt_name;
pfstype pt_pfstype;
int (*pt_valid) __P((struct proc *p));
} proc_targets[] = {
#define N(s) sizeof(s)-1, s
/* namlen, nam, type validp */
{ N("."), Pproc, NULL },
{ N(".."), Proot, NULL },
{ N("file"), Pfile, procfs_validfile },
{ N("mem"), Pmem, NULL },
{ N("regs"), Pregs, procfs_validregs },
{ N("fpregs"), Pfpregs, procfs_validfpregs },
{ N("ctl"), Pctl, NULL },
{ N("status"), Pstatus, NULL },
{ N("note"), Pnote, NULL },
{ N("notepg"), Pnotepg, NULL },
{ N("map"), Pmap, procfs_validmap },
{ N("etype"), Ptype, procfs_validtype },
/* name type validp */
{ DT_DIR, N("."), Pproc, NULL },
{ DT_DIR, N(".."), Proot, NULL },
{ DT_REG, N("file"), Pfile, procfs_validfile },
{ DT_REG, N("mem"), Pmem, NULL },
{ DT_REG, N("regs"), Pregs, procfs_validregs },
{ DT_REG, N("fpregs"), Pfpregs, procfs_validfpregs },
{ DT_REG, N("ctl"), Pctl, NULL },
{ DT_REG, N("status"), Pstatus, NULL },
{ DT_REG, N("note"), Pnote, NULL },
{ DT_REG, N("notepg"), Pnotepg, NULL },
{ DT_REG, N("map"), Pmap, procfs_validmap },
{ DT_REG, N("etype"), Ptype, procfs_validtype },
#undef N
};
#define Nprocent (sizeof(procent)/sizeof(procent[0]))
static const int nproc_targets = sizeof(proc_targets) / sizeof(proc_targets[0]);
static pid_t atopid __P((const char *, u_int));
@ -117,7 +119,12 @@ static pid_t atopid __P((const char *, u_int));
*/
static int
procfs_open(ap)
struct vop_open_args *ap;
struct vop_open_args /* {
struct vnode *a_vp;
int a_mode;
struct ucred *a_cred;
struct proc *a_p;
} */ *ap;
{
struct pfsnode *pfs = VTOPFS(ap->a_vp);
@ -126,11 +133,10 @@ procfs_open(ap)
if (PFIND(pfs->pfs_pid) == 0)
return (ENOENT); /* was ESRCH, jsp */
if (((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL)) ||
((pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE)))
if ((pfs->pfs_flags & FWRITE) && (ap->a_mode & O_EXCL) ||
(pfs->pfs_flags & O_EXCL) && (ap->a_mode & FWRITE))
return (EBUSY);
if (ap->a_mode & FWRITE)
pfs->pfs_flags = ap->a_mode & (FWRITE|O_EXCL);
@ -152,7 +158,12 @@ procfs_open(ap)
*/
static int
procfs_close(ap)
struct vop_close_args *ap;
struct vop_close_args /* {
struct vnode *a_vp;
int a_fflag;
struct ucred *a_cred;
struct proc *a_p;
} */ *ap;
{
struct pfsnode *pfs = VTOPFS(ap->a_vp);
@ -174,14 +185,51 @@ procfs_close(ap)
*/
static int
procfs_ioctl(ap)
struct vop_ioctl_args *ap;
struct vop_ioctl_args /* {
struct vnode *a_vp;
int a_command;
caddr_t a_data;
int a_fflag;
struct ucred *a_cred;
struct proc *a_p;
} */ *ap;
{
return (ENOTTY);
}
/*
* _inactive is called when the pfsnode
* do block mapping for pfsnode (vp).
* since we don't use the buffer cache
* for procfs this function should never
* be called. in any case, it's not clear
* what part of the kernel ever makes use
* of this function. for sanity, this is the
* usual no-op bmap, although returning
* (EIO) would be a reasonable alternative.
*/
int
procfs_bmap(ap)
struct vop_bmap_args /* {
struct vnode *a_vp;
daddr_t a_bn;
struct vnode **a_vpp;
daddr_t *a_bnp;
int *a_runp;
} */ *ap;
{
if (ap->a_vpp != NULL)
*ap->a_vpp = ap->a_vp;
if (ap->a_bnp != NULL)
*ap->a_bnp = ap->a_bn;
if (ap->a_runp != NULL)
*ap->a_runp = 0;
return (0);
}
/*
* procfs_inactive is called when the pfsnode
* is vrele'd and the reference count goes
* to zero. (vp) will be on the vnode free
* list, so to get it back vget() must be
@ -194,16 +242,20 @@ procfs_ioctl(ap)
* chances are that the process will still be
* there and PFIND is not free.
*
* (vp) is not locked on entry or exit.
* (vp) is locked on entry, but must be unlocked on exit.
*/
static int
procfs_inactive(ap)
struct vop_inactive_args *ap;
struct vop_inactive_args /* {
struct vnode *a_vp;
} */ *ap;
{
struct pfsnode *pfs = VTOPFS(ap->a_vp);
struct vnode *vp = ap->a_vp;
struct pfsnode *pfs = VTOPFS(vp);
VOP_UNLOCK(vp, 0, ap->a_p);
if (PFIND(pfs->pfs_pid) == 0)
vgone(ap->a_vp);
vgone(vp);
return (0);
}
@ -217,12 +269,12 @@ procfs_inactive(ap)
*/
static int
procfs_reclaim(ap)
struct vop_reclaim_args *ap;
struct vop_reclaim_args /* {
struct vnode *a_vp;
} */ *ap;
{
int error;
error = procfs_freevp(ap->a_vp);
return (error);
return (procfs_freevp(ap->a_vp));
}
/*
@ -269,13 +321,14 @@ procfs_pathconf(ap)
*/
static int
procfs_print(ap)
struct vop_print_args *ap;
struct vop_print_args /* {
struct vnode *a_vp;
} */ *ap;
{
struct pfsnode *pfs = VTOPFS(ap->a_vp);
printf("tag VT_PROCFS, pid %lu, mode %x, flags %lx\n",
pfs->pfs_pid,
pfs->pfs_mode, pfs->pfs_flags);
printf("tag VT_PROCFS, type %s, pid %d, mode %x, flags %x\n",
pfs->pfs_type, pfs->pfs_pid, pfs->pfs_mode, pfs->pfs_flags);
return (0);
}
@ -287,7 +340,10 @@ procfs_print(ap)
*/
static int
procfs_abortop(ap)
struct vop_abortop_args *ap;
struct vop_abortop_args /* {
struct vnode *a_dvp;
struct componentname *a_cnp;
} */ *ap;
{
if ((ap->a_cnp->cn_flags & (HASBUF | SAVESTART)) == HASBUF)
@ -316,7 +372,12 @@ procfs_badop()
*/
static int
procfs_getattr(ap)
struct vop_getattr_args *ap;
struct vop_getattr_args /* {
struct vnode *a_vp;
struct vattr *a_vap;
struct ucred *a_cred;
struct proc *a_p;
} */ *ap;
{
struct pfsnode *pfs = VTOPFS(ap->a_vp);
struct vattr *vap = ap->a_vap;
@ -329,6 +390,7 @@ procfs_getattr(ap)
*/
switch (pfs->pfs_type) {
case Proot:
case Pcurproc:
procp = 0;
break;
@ -352,6 +414,21 @@ procfs_getattr(ap)
vap->va_blocksize = PAGE_SIZE;
vap->va_bytes = vap->va_size = 0;
/*
* Make all times be current TOD.
* It would be possible to get the process start
* time from the p_stat structure, but there's
* no "file creation" time stamp anyway, and the
* p_stat structure is not addressible if u. gets
* swapped out for that process.
*/
{
struct timeval tv;
microtime(&tv);
TIMEVAL_TO_TIMESPEC(&tv, &vap->va_ctime);
}
vap->va_atime = vap->va_mtime = vap->va_ctime;
/*
* If the process has exercised some setuid or setgid
* privilege, then rip away read/write permission so
@ -375,21 +452,6 @@ procfs_getattr(ap)
break;
}
/*
* Make all times be current TOD.
* It would be possible to get the process start
* time from the p_stat structure, but there's
* no "file creation" time stamp anyway, and the
* p_stat structure is not addressible if u. gets
* swapped out for that process.
*/
{
struct timeval tv;
microtime(&tv);
TIMEVAL_TO_TIMESPEC(&tv, &vap->va_ctime);
}
vap->va_atime = vap->va_mtime = vap->va_ctime;
/*
* now do the object specific fields
*
@ -402,17 +464,30 @@ procfs_getattr(ap)
switch (pfs->pfs_type) {
case Proot:
vap->va_nlink = nprocs + 3;
/*
* Set nlink to 1 to tell fts(3) we don't actually know.
*/
vap->va_nlink = 1;
vap->va_uid = 0;
vap->va_gid = 0;
vap->va_bytes = vap->va_size = DEV_BSIZE;
vap->va_size = vap->va_bytes = DEV_BSIZE;
break;
case Pcurproc: {
char buf[16]; /* should be enough */
vap->va_nlink = 1;
vap->va_uid = 0;
vap->va_gid = 0;
vap->va_size = vap->va_bytes =
sprintf(buf, "%ld", (long)curproc->p_pid);
break;
}
case Pproc:
vap->va_nlink = Nprocent;
vap->va_nlink = nproc_targets;
vap->va_uid = procp->p_ucred->cr_uid;
vap->va_gid = procp->p_ucred->cr_gid;
vap->va_bytes = vap->va_size = DEV_BSIZE;
vap->va_size = vap->va_bytes = DEV_BSIZE;
break;
case Pfile:
@ -436,7 +511,15 @@ procfs_getattr(ap)
case Ptype:
case Pmap:
case Pregs:
vap->va_bytes = vap->va_size = sizeof(struct reg);
vap->va_nlink = 1;
vap->va_uid = procp->p_ucred->cr_uid;
vap->va_gid = procp->p_ucred->cr_gid;
break;
case Pfpregs:
vap->va_bytes = vap->va_size = sizeof(struct fpreg);
case Pctl:
case Pstatus:
case Pnote:
@ -455,7 +538,12 @@ procfs_getattr(ap)
static int
procfs_setattr(ap)
struct vop_setattr_args *ap;
struct vop_setattr_args /* {
struct vnode *a_vp;
struct vattr *a_vap;
struct ucred *a_cred;
struct proc *a_p;
} */ *ap;
{
/*
* just fake out attribute setting
@ -484,7 +572,12 @@ procfs_setattr(ap)
*/
static int
procfs_access(ap)
struct vop_access_args *ap;
struct vop_access_args /* {
struct vnode *a_vp;
int a_mode;
struct ucred *a_cred;
struct proc *a_p;
} */ *ap;
{
struct vattr *vap;
struct vattr vattr;
@ -494,8 +587,9 @@ procfs_access(ap)
* If you're the super-user,
* you always get access.
*/
if (ap->a_cred->cr_uid == (uid_t) 0)
if (ap->a_cred->cr_uid == 0)
return (0);
vap = &vattr;
error = VOP_GETATTR(ap->a_vp, vap, ap->a_cred, ap->a_p);
if (error)
@ -510,7 +604,7 @@ procfs_access(ap)
gid_t *gp;
int i;
(ap->a_mode) >>= 3;
ap->a_mode >>= 3;
gp = ap->a_cred->cr_groups;
for (i = 0; i < ap->a_cred->cr_ngroups; i++, gp++)
if (vap->va_gid == *gp)
@ -537,18 +631,23 @@ procfs_access(ap)
*/
static int
procfs_lookup(ap)
struct vop_lookup_args *ap;
struct vop_lookup_args /* {
struct vnode * a_dvp;
struct vnode ** a_vpp;
struct componentname * a_cnp;
} */ *ap;
{
struct componentname *cnp = ap->a_cnp;
struct vnode **vpp = ap->a_vpp;
struct vnode *dvp = ap->a_dvp;
char *pname = cnp->cn_nameptr;
struct proc *curp = cnp->cn_proc;
int error = 0;
struct proc_target *pt;
struct vnode *fvp;
pid_t pid;
struct vnode *nvp;
struct pfsnode *pfs;
struct proc *procp;
pfstype pfs_type;
struct proc *p;
int i;
*vpp = NULL;
@ -559,7 +658,7 @@ procfs_lookup(ap)
if (cnp->cn_namelen == 1 && *pname == '.') {
*vpp = dvp;
VREF(dvp);
/*VOP_LOCK(dvp);*/
/* vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, curp); */
return (0);
}
@ -570,72 +669,52 @@ procfs_lookup(ap)
return (EIO);
if (CNEQ(cnp, "curproc", 7))
pid = cnp->cn_proc->p_pid;
else
pid = atopid(pname, cnp->cn_namelen);
return (procfs_allocvp(dvp->v_mount, vpp, 0, Pcurproc));
pid = atopid(pname, cnp->cn_namelen);
if (pid == NO_PID)
return (ENOENT);
break;
procp = PFIND(pid);
if (procp == 0)
return (ENOENT);
p = PFIND(pid);
if (p == 0)
break;
error = procfs_allocvp(dvp->v_mount, &nvp, pid, Pproc);
if (error)
return (error);
nvp->v_type = VDIR;
pfs = VTOPFS(nvp);
*vpp = nvp;
return (0);
return (procfs_allocvp(dvp->v_mount, vpp, pid, Pproc));
case Pproc:
if (cnp->cn_flags & ISDOTDOT) {
error = procfs_root(dvp->v_mount, vpp);
return (error);
}
if (cnp->cn_flags & ISDOTDOT)
return (procfs_root(dvp->v_mount, vpp));
procp = PFIND(pfs->pfs_pid);
if (procp == 0)
return (ENOENT);
p = PFIND(pfs->pfs_pid);
if (p == 0)
break;
for (i = 0; i < Nprocent; i++) {
struct pfsnames *dp = &procent[i];
if (cnp->cn_namelen == dp->d_namlen &&
bcmp(pname, dp->d_name, dp->d_namlen) == 0 &&
(dp->d_valid == NULL || (*dp->d_valid)(procp))) {
pfs_type = dp->d_pfstype;
for (pt = proc_targets, i = 0; i < nproc_targets; pt++, i++) {
if (cnp->cn_namelen == pt->pt_namlen &&
bcmp(pt->pt_name, pname, cnp->cn_namelen) == 0 &&
(pt->pt_valid == NULL || (*pt->pt_valid)(p)))
goto found;
}
}
return (ENOENT);
break;
found:
if (pfs_type == Pfile) {
nvp = procfs_findtextvp(procp);
if (nvp) {
VREF(nvp);
VOP_LOCK(nvp);
} else {
error = ENXIO;
}
} else {
error = procfs_allocvp(dvp->v_mount, &nvp,
pfs->pfs_pid, pfs_type);
if (error)
return (error);
nvp->v_type = VREG;
pfs = VTOPFS(nvp);
if (pt->pt_pfstype == Pfile) {
fvp = procfs_findtextvp(p);
/* We already checked that it exists. */
VREF(fvp);
vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, curp);
*vpp = fvp;
return (0);
}
*vpp = nvp;
return (error);
return (procfs_allocvp(dvp->v_mount, vpp, pfs->pfs_pid,
pt->pt_pfstype));
default:
return (ENOTDIR);
}
return (cnp->cn_nameiop == LOOKUP ? ENOENT : EROFS);
}
/*
@ -645,6 +724,7 @@ int
procfs_validfile(p)
struct proc *p;
{
return (procfs_findtextvp(p) != NULLVP);
}
@ -662,7 +742,14 @@ procfs_validfile(p)
*/
static int
procfs_readdir(ap)
struct vop_readdir_args *ap;
struct vop_readdir_args /* {
struct vnode *a_vp;
struct uio *a_uio;
struct ucred *a_cred;
int *a_eofflag;
u_long *a_cookies;
int a_ncookies;
} */ *ap;
{
struct uio *uio = ap->a_uio;
struct pfsdent d;
@ -672,6 +759,13 @@ procfs_readdir(ap)
int count;
int i;
/*
* We don't allow exporting procfs mounts, and currently local
* requests do not need cookies.
*/
if (ap->a_ncookies)
panic("procfs_readdir: not hungry");
pfs = VTOPFS(ap->a_vp);
if (uio->uio_resid < UIO_MX)
@ -693,39 +787,28 @@ procfs_readdir(ap)
*/
case Pproc: {
struct proc *p;
struct proc_target *pt;
p = PFIND(pfs->pfs_pid);
if (p == NULL)
break;
while (uio->uio_resid >= UIO_MX) {
struct pfsnames *dt;
if (i >= Nprocent)
break;
dt = &procent[i];
/* see if we should show this one. */
if (dt->d_valid && (*dt->d_valid)(p) == 0) {
i++;
for (pt = &proc_targets[i];
uio->uio_resid >= UIO_MX && i < nproc_targets; pt++, i++) {
if (pt->pt_valid && (*pt->pt_valid)(p) == 0)
continue;
}
dp->d_reclen = UIO_MX;
dp->d_fileno = PROCFS_FILENO(pfs->pfs_pid, dt->d_pfstype);
dp->d_type = DT_REG;
dp->d_namlen = dt->d_namlen;
bcopy(dt->d_name, dp->d_name, sizeof(dt->d_name)-1);
error = uiomove((caddr_t) dp, UIO_MX, uio);
if (error)
dp->d_fileno = PROCFS_FILENO(pfs->pfs_pid, pt->pt_pfstype);
dp->d_namlen = pt->pt_namlen;
bcopy(pt->pt_name, dp->d_name, pt->pt_namlen + 1);
dp->d_type = pt->pt_type;
if (error = uiomove((caddr_t)dp, UIO_MX, uio))
break;
count += UIO_MX;
i++;
}
break;
}
/*
@ -738,63 +821,61 @@ procfs_readdir(ap)
*/
case Proot: {
int pcnt;
#ifdef PROCFS_ZOMBIE
int doingzomb = 0;
#endif
int pcnt = 0;
volatile struct proc *p = allproc.lh_first;
#define PROCFS_XFILES 3 /* number of other entries, like "curproc" */
pcnt = PROCFS_XFILES;
while (p && uio->uio_resid >= UIO_MX) {
again:
for (; p && uio->uio_resid >= UIO_MX; i++, pcnt++) {
bzero((char *) dp, UIO_MX);
dp->d_type = DT_DIR;
dp->d_reclen = UIO_MX;
switch (i) {
case 0:
case 0: /* `.' */
case 1: /* `..' */
dp->d_fileno = PROCFS_FILENO(0, Proot);
dp->d_namlen = sprintf(dp->d_name, ".");
break;
case 1:
dp->d_fileno = PROCFS_FILENO(0, Proot);
dp->d_namlen = sprintf(dp->d_name, "..");
dp->d_namlen = i + 1;
bcopy("..", dp->d_name, dp->d_namlen);
dp->d_name[i + 1] = '\0';
dp->d_type = DT_DIR;
break;
case 2:
/* ship out entry for "curproc" */
dp->d_fileno = PROCFS_FILENO(PID_MAX+1, Pproc);
dp->d_namlen = sprintf(dp->d_name, "curproc");
dp->d_fileno = PROCFS_FILENO(0, Pcurproc);
dp->d_namlen = 7;
bcopy("curproc", dp->d_name, 8);
dp->d_type = DT_LNK;
break;
default:
if (pcnt >= i) {
dp->d_fileno = PROCFS_FILENO(p->p_pid, Pproc);
dp->d_namlen = sprintf(dp->d_name, "%ld", (long) p->p_pid);
while (pcnt < i) {
pcnt++;
p = p->p_list.le_next;
if (!p)
goto done;
}
dp->d_fileno = PROCFS_FILENO(p->p_pid, Pproc);
dp->d_namlen = sprintf(dp->d_name, "%ld",
(long)p->p_pid);
dp->d_type = DT_REG;
p = p->p_list.le_next;
#ifdef PROCFS_ZOMBIE
if (p == 0 && doingzomb == 0) {
doingzomb = 1;
p = zombproc.lh_first;
}
#endif
if (pcnt++ < i)
continue;
break;
}
error = uiomove((caddr_t) dp, UIO_MX, uio);
if (error)
if (error = uiomove((caddr_t)dp, UIO_MX, uio))
break;
count += UIO_MX;
i++;
}
done:
#ifdef PROCFS_ZOMBIE
if (p == 0 && doingzomb == 0) {
doingzomb = 1;
p = zombproc.lh_first;
goto again;
}
#endif
break;
@ -810,6 +891,25 @@ procfs_readdir(ap)
return (error);
}
/*
* readlink reads the link of `curproc'
*/
int
procfs_readlink(ap)
struct vop_readlink_args *ap;
{
struct uio *uio = ap->a_uio;
char buf[16]; /* should be enough */
int len;
if (VTOPFS(ap->a_vp)->pfs_fileno != PROCFS_FILENO(0, Pcurproc))
return (EINVAL);
len = sprintf(buf, "%ld", (long)curproc->p_pid);
return (uiomove((caddr_t)buf, len, ap->a_uio));
}
/*
* convert decimal ascii to pid_t
*/
@ -838,6 +938,7 @@ atopid(b, len)
#define procfs_write procfs_rw
#define procfs_select ((int (*) __P((struct vop_select_args *))) procfs_badop)
#define procfs_mmap ((int (*) __P((struct vop_mmap_args *))) procfs_badop)
#define procfs_revoke vop_revoke
#define procfs_fsync ((int (*) __P((struct vop_fsync_args *))) procfs_badop)
#define procfs_seek ((int (*) __P((struct vop_seek_args *))) procfs_badop)
#define procfs_remove ((int (*) __P((struct vop_remove_args *))) procfs_badop)
@ -849,7 +950,6 @@ atopid(b, len)
#define procfs_readlink ((int (*) __P((struct vop_readlink_args *))) procfs_badop)
#define procfs_lock ((int (*) __P((struct vop_lock_args *))) nullop)
#define procfs_unlock ((int (*) __P((struct vop_unlock_args *))) nullop)
#define procfs_bmap ((int (*) __P((struct vop_bmap_args *))) procfs_badop)
#define procfs_strategy ((int (*) __P((struct vop_strategy_args *))) procfs_badop)
#define procfs_islocked ((int (*) __P((struct vop_islocked_args *))) nullop)
#define procfs_advlock ((int (*) __P((struct vop_advlock_args *))) procfs_badop)
@ -859,6 +959,9 @@ atopid(b, len)
#define procfs_truncate ((int (*) __P((struct vop_truncate_args *))) procfs_badop)
#define procfs_update ((int (*) __P((struct vop_update_args *))) nullop)
/*
* procfs vnode operations.
*/
vop_t **procfs_vnodeop_p;
static struct vnodeopv_entry_desc procfs_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *)vn_default_error },
@ -875,6 +978,7 @@ static struct vnodeopv_entry_desc procfs_vnodeop_entries[] = {
{ &vop_ioctl_desc, (vop_t *)procfs_ioctl }, /* ioctl */
{ &vop_select_desc, (vop_t *)procfs_select }, /* select */
{ &vop_mmap_desc, (vop_t *)procfs_mmap }, /* mmap */
{ &vop_revoke_desc, (vop_t *)procfs_revoke }, /* revoke */
{ &vop_fsync_desc, (vop_t *)procfs_fsync }, /* fsync */
{ &vop_seek_desc, (vop_t *)procfs_seek }, /* seek */
{ &vop_remove_desc, (vop_t *)procfs_remove }, /* remove */

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1989, 1993
* Copyright (c) 1989, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)spec_vnops.c 8.6 (Berkeley) 4/9/94
* @(#)spec_vnops.c 8.14 (Berkeley) 5/21/95
* $FreeBSD$
*/
@ -79,8 +79,10 @@ static struct vnodeopv_entry_desc spec_vnodeop_entries[] = {
{ &vop_setattr_desc, (vop_t *)spec_setattr }, /* setattr */
{ &vop_read_desc, (vop_t *)spec_read }, /* read */
{ &vop_write_desc, (vop_t *)spec_write }, /* write */
{ &vop_lease_desc, (vop_t *)spec_lease_check }, /* lease */
{ &vop_ioctl_desc, (vop_t *)spec_ioctl }, /* ioctl */
{ &vop_select_desc, (vop_t *)spec_select }, /* select */
{ &vop_revoke_desc, (vop_t *)spec_revoke }, /* revoke */
{ &vop_mmap_desc, (vop_t *)spec_mmap }, /* mmap */
{ &vop_fsync_desc, (vop_t *)spec_fsync }, /* fsync */
{ &vop_seek_desc, (vop_t *)spec_seek }, /* seek */
@ -148,9 +150,10 @@ spec_open(ap)
struct proc *a_p;
} */ *ap;
{
struct proc *p = ap->a_p;
struct vnode *bvp, *vp = ap->a_vp;
dev_t bdev, dev = (dev_t)vp->v_rdev;
register int maj = major(dev);
int maj = major(dev);
int error;
/*
@ -171,7 +174,9 @@ spec_open(ap)
* When running in very secure mode, do not allow
* opens for writing of any disk character devices.
*/
if (securelevel >= 2 && isdisk(dev, VCHR))
if (securelevel >= 2
&& cdevsw[maj]->d_bdev
&& cdevsw[maj]->d_bdev->d_flags == D_DISK)
return (EPERM);
/*
* When running in secure mode, do not allow opens
@ -189,9 +194,20 @@ spec_open(ap)
return (EPERM);
}
}
VOP_UNLOCK(vp);
error = (*cdevsw[maj]->d_open)(dev, ap->a_mode, S_IFCHR, ap->a_p);
VOP_LOCK(vp);
#if 0
/*
* Lite2 stuff. We will almost certainly do this
* differently with devfs. The only use of this flag
* is in dead_read to make ttys return EOF instead of
* EIO when they are dead. Pre-lite2 FreeBSD returns
* EOF for all character devices.
*/
if (cdevsw[maj]->d_type == D_TTY)
vp->v_flag |= VISTTY;
#endif
VOP_UNLOCK(vp, 0, p);
error = (*cdevsw[maj]->d_open)(dev, ap->a_mode, S_IFCHR, p);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
case VBLK:
@ -204,7 +220,7 @@ spec_open(ap)
* opens for writing of any disk block devices.
*/
if (securelevel >= 2 && ap->a_cred != FSCRED &&
(ap->a_mode & FWRITE) && isdisk(dev, VBLK))
(ap->a_mode & FWRITE) && bdevsw[maj]->d_flags == D_DISK)
return (EPERM);
/*
* Do not allow opens of block devices that are
@ -213,9 +229,7 @@ spec_open(ap)
error = vfs_mountedon(vp);
if (error)
return (error);
return ((*bdevsw[maj]->d_open)(dev, ap->a_mode, S_IFBLK, ap->a_p));
default:
break;
return ((*bdevsw[maj]->d_open)(dev, ap->a_mode, S_IFBLK, p));
}
return (0);
}
@ -257,10 +271,10 @@ spec_read(ap)
switch (vp->v_type) {
case VCHR:
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, 0, p);
error = (*cdevsw[major(vp->v_rdev)]->d_read)
(vp->v_rdev, uio, ap->a_ioflag);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
case VBLK:
@ -335,10 +349,10 @@ spec_write(ap)
switch (vp->v_type) {
case VCHR:
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, 0, p);
error = (*cdevsw[major(vp->v_rdev)]->d_write)
(vp->v_rdev, uio, ap->a_ioflag);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
case VBLK:
@ -408,7 +422,7 @@ spec_ioctl(ap)
case VBLK:
if (ap->a_command == 0 && (int)ap->a_data == B_TAPE)
if (bdevsw[major(dev)]->d_flags & B_TAPE)
if (bdevsw[major(dev)]->d_flags == D_TAPE)
return (0);
else
return (1);
@ -498,6 +512,18 @@ spec_fsync(ap)
return (0);
}
int
spec_inactive(ap)
struct vop_inactive_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
return (0);
}
/*
* Just call the device strategy routine
*/
@ -538,31 +564,6 @@ spec_bmap(ap)
return (0);
}
/*
* At the moment we do not do any locking.
*/
/* ARGSUSED */
int
spec_lock(ap)
struct vop_lock_args /* {
struct vnode *a_vp;
} */ *ap;
{
return (0);
}
/* ARGSUSED */
int
spec_unlock(ap)
struct vop_unlock_args /* {
struct vnode *a_vp;
} */ *ap;
{
return (0);
}
/*
* Device close routine
*/
@ -577,6 +578,7 @@ spec_close(ap)
} */ *ap;
{
register struct vnode *vp = ap->a_vp;
struct proc *p = ap->a_p;
dev_t dev = vp->v_rdev;
d_close_t *devclose;
int mode, error;
@ -631,8 +633,11 @@ spec_close(ap)
(vp->v_flag & VXLOCK) == 0)
return (0);
if (vp->v_object)
vnode_pager_uncache(vp);
if (vp->v_object) {
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
vnode_pager_uncache(vp, p);
VOP_UNLOCK(vp, 0, p);
}
devclose = bdevsw[major(dev)]->d_close;
mode = S_IFBLK;

View File

@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)umap.h 8.3 (Berkeley) 1/21/94
* @(#)umap.h 8.4 (Berkeley) 8/20/94
*
* $FreeBSD$
*/
@ -67,8 +67,7 @@ struct umap_mount {
* A cache of vnode references
*/
struct umap_node {
struct umap_node *umap_forw; /* Hash chain */
struct umap_node *umap_back;
LIST_ENTRY(umap_node) umap_hash; /* Hash list */
struct vnode *umap_lowervp; /* Aliased vnode - VREFed once */
struct vnode *umap_vnode; /* Back pointer to vnode/umap_node */
};

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1992, 1993
* Copyright (c) 1992, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
@ -33,13 +33,14 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)umap_subr.c 8.6 (Berkeley) 1/26/94
* @(#)umap_subr.c 8.9 (Berkeley) 5/14/95
*
* $FreeBSD$
*/
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/vnode.h>
@ -48,11 +49,8 @@
#include <sys/malloc.h>
#include <miscfs/umapfs/umap.h>
extern int umapfs_init __P((void));
#define LOG2_SIZEVNODE 7 /* log2(sizeof struct vnode) */
#define NUMAPNODECACHE 16
#define UMAP_NHASH(vp) ((((u_long) vp)>>LOG2_SIZEVNODE) & (NUMAPNODECACHE-1))
/*
* Null layer cache:
@ -62,51 +60,32 @@ extern int umapfs_init __P((void));
* alias is removed the target vnode is vrele'd.
*/
/*
* Cache head
*/
struct umap_node_cache {
struct umap_node *ac_forw;
struct umap_node *ac_back;
};
static struct umap_node_cache umap_node_cache[NUMAPNODECACHE];
#define UMAP_NHASH(vp) \
(&umap_node_hashtbl[(((u_long)vp)>>LOG2_SIZEVNODE) & umap_node_hash])
LIST_HEAD(umap_node_hashhead, umap_node) *umap_node_hashtbl;
u_long umap_node_hash;
static u_long umap_findid __P((u_long id, u_long map[][2], int nentries));
static int umap_node_alloc __P((struct mount *mp, struct vnode *lowervp,
struct vnode **vpp));
static struct vnode *
umap_node_find __P((struct mount *mp, struct vnode *targetvp));
static struct umap_node_cache *
umap_node_hash __P((struct vnode *targetvp));
/*
* Initialise cache headers
*/
int
umapfs_init()
umapfs_init(vfsp)
struct vfsconf *vfsp;
{
struct umap_node_cache *ac;
#ifdef UMAPFS_DIAGNOSTIC
printf("umapfs_init\n"); /* printed during system boot */
#endif
for (ac = umap_node_cache; ac < umap_node_cache + NUMAPNODECACHE; ac++)
ac->ac_forw = ac->ac_back = (struct umap_node *) ac;
umap_node_hashtbl = hashinit(NUMAPNODECACHE, M_CACHE, &umap_node_hash);
return (0);
}
/*
* Compute hash list for given target vnode
*/
static struct umap_node_cache *
umap_node_hash(targetvp)
struct vnode *targetvp;
{
return (&umap_node_cache[UMAP_NHASH(targetvp)]);
}
/*
* umap_findid is called by various routines in umap_vnodeops.c to
* find a user or group id in a map.
@ -163,7 +142,8 @@ umap_node_find(mp, targetvp)
struct mount *mp;
struct vnode *targetvp;
{
struct umap_node_cache *hd;
struct proc *p = curproc; /* XXX */
struct umap_node_hashhead *hd;
struct umap_node *a;
struct vnode *vp;
@ -177,10 +157,9 @@ umap_node_find(mp, targetvp)
* the target vnode. If found, the increment the umap_node
* reference count (but NOT the target vnode's VREF counter).
*/
hd = umap_node_hash(targetvp);
loop:
for (a = hd->ac_forw; a != (struct umap_node *) hd; a = a->umap_forw) {
hd = UMAP_NHASH(targetvp);
loop:
for (a = hd->lh_first; a != 0; a = a->umap_hash.le_next) {
if (a->umap_lowervp == targetvp &&
a->umap_vnode->v_mount == mp) {
vp = UMAPTOV(a);
@ -189,7 +168,7 @@ umap_node_find(mp, targetvp)
* stuff, but we don't want to lock
* the lower node.
*/
if (vget(vp, 0)) {
if (vget(vp, 0, p)) {
#ifdef UMAPFS_DIAGNOSTIC
printf ("umap_node_find: vget failed.\n");
#endif
@ -217,7 +196,7 @@ umap_node_alloc(mp, lowervp, vpp)
struct vnode *lowervp;
struct vnode **vpp;
{
struct umap_node_cache *hd;
struct umap_node_hashhead *hd;
struct umap_node *xp;
struct vnode *othervp, *vp;
int error;
@ -257,8 +236,8 @@ umap_node_alloc(mp, lowervp, vpp)
return (0);
}
VREF(lowervp); /* Extra VREF will be vrele'd in umap_node_create */
hd = umap_node_hash(lowervp);
insque(xp, hd);
hd = UMAP_NHASH(lowervp);
LIST_INSERT_HEAD(hd, xp, umap_hash);
return (0);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1992, 1993
* Copyright (c) 1992, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software donated to Berkeley by
@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)umap_vfsops.c 8.3 (Berkeley) 1/21/94
* @(#)umap_vfsops.c 8.8 (Berkeley) 5/14/95
*
* $FreeBSD$
*/
@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/vnode.h>
@ -54,7 +55,7 @@
#include <sys/malloc.h>
#include <miscfs/umapfs/umap.h>
extern int umapfs_init __P((void));
extern int umapfs_init __P((struct vfsconf *));
static int umapfs_fhtovp __P((struct mount *mp, struct fid *fidp,
struct mbuf *nam, struct vnode **vpp,
@ -187,7 +188,7 @@ umapfs_mount(mp, path, data, ndp, p)
/*
* Unlock the node (either the lower or the alias)
*/
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, 0, p);
/*
* Make sure the node alias worked
*/
@ -207,7 +208,7 @@ umapfs_mount(mp, path, data, ndp, p)
if (UMAPVPTOLOWERVP(umapm_rootvp)->v_mount->mnt_flag & MNT_LOCAL)
mp->mnt_flag |= MNT_LOCAL;
mp->mnt_data = (qaddr_t) amp;
getnewfsid(mp, MOUNT_LOFS);
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
@ -253,12 +254,8 @@ umapfs_unmount(mp, mntflags, p)
printf("umapfs_unmount(mp = %x)\n", mp);
#endif
if (mntflags & MNT_FORCE) {
/* lofs can never be rootfs so don't check for it */
if (!doforce)
return (EINVAL);
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
}
/*
* Clear out buffer cache. I don't think we
@ -300,6 +297,7 @@ umapfs_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
struct proc *p = curproc; /* XXX */
struct vnode *vp;
#ifdef UMAPFS_DIAGNOSTIC
@ -314,7 +312,7 @@ umapfs_root(mp, vpp)
*/
vp = MOUNTTOUMAPMOUNT(mp)->umapm_rootvp;
VREF(vp);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
*vpp = vp;
return (0);
}
@ -429,4 +427,3 @@ static struct vfsops umap_vfsops = {
};
VFS_SET(umap_vfsops, umap, MOUNT_UMAP, VFCF_LOOPBACK);

View File

@ -33,7 +33,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)umap_vnops.c 8.3 (Berkeley) 1/5/94
* @(#)umap_vnops.c 8.6 (Berkeley) 5/22/95
* $FreeBSD$
*/
@ -336,10 +336,52 @@ umap_getattr(ap)
return (0);
}
/*
* We need to process our own vnode lock and then clear the
* interlock flag as it applies only to our vnode, not the
* vnodes below us on the stack.
*/
int
umap_lock(ap)
struct vop_lock_args /* {
struct vnode *a_vp;
int a_flags;
struct proc *a_p;
} */ *ap;
{
vop_nolock(ap);
if ((ap->a_flags & LK_TYPE_MASK) == LK_DRAIN)
return (0);
ap->a_flags &= ~LK_INTERLOCK;
return (null_bypass(ap));
}
/*
* We need to process our own vnode unlock and then clear the
* interlock flag as it applies only to our vnode, not the
* vnodes below us on the stack.
*/
int
umap_unlock(ap)
struct vop_unlock_args /* {
struct vnode *a_vp;
int a_flags;
struct proc *a_p;
} */ *ap;
{
struct vnode *vp = ap->a_vp;
vop_nounlock(ap);
ap->a_flags &= ~LK_INTERLOCK;
return (null_bypass(ap));
}
static int
umap_inactive(ap)
struct vop_inactive_args /* {
struct vnode *a_vp;
struct proc *a_p;
} */ *ap;
{
/*
@ -349,6 +391,7 @@ umap_inactive(ap)
* cache and reusable.
*
*/
VOP_UNLOCK(ap->a_vp, 0, ap->a_p);
return (0);
}
@ -364,7 +407,7 @@ umap_reclaim(ap)
/* After this assignment, this node will not be re-used. */
xp->umap_lowervp = NULL;
remque(xp);
LIST_REMOVE(xp, umap_hash);
FREE(vp->v_data, M_TEMP);
vp->v_data = NULL;
vrele(lowervp);
@ -487,6 +530,8 @@ static struct vnodeopv_entry_desc umap_vnodeop_entries[] = {
{ &vop_default_desc, (vop_t *)umap_bypass },
{ &vop_getattr_desc, (vop_t *)umap_getattr },
{ &vop_lock_desc, (vop_t *)umap_lock },
{ &vop_unlock_desc, (vop_t *)umap_unlock },
{ &vop_inactive_desc, (vop_t *)umap_inactive },
{ &vop_reclaim_desc, (vop_t *)umap_reclaim },
{ &vop_print_desc, (vop_t *)umap_print },

View File

@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)union.h 8.2 (Berkeley) 2/17/94
* @(#)union.h 8.9 (Berkeley) 12/10/94
* $FreeBSD$
*/
@ -75,10 +75,14 @@ struct union_node {
struct vnode *un_uppervp; /* overlaying object */
struct vnode *un_lowervp; /* underlying object */
struct vnode *un_dirvp; /* Parent dir of uppervp */
struct vnode *un_pvp; /* Parent vnode */
char *un_path; /* saved component name */
int un_hash; /* saved un_path hash value */
int un_openl; /* # of opens on lowervp */
int un_flags;
unsigned int un_flags;
struct vnode **un_dircache; /* cached union stack */
off_t un_uppersz; /* size of upper object */
off_t un_lowersz; /* size of lower object */
#ifdef DIAGNOSTIC
pid_t un_pid;
#endif
@ -88,16 +92,23 @@ struct union_node {
#define UN_LOCKED 0x02
#define UN_ULOCK 0x04 /* Upper node is locked */
#define UN_KLOCK 0x08 /* Keep upper node locked on vput */
#define UN_CACHED 0x10 /* In union cache */
extern int union_allocvp __P((struct vnode **, struct mount *,
struct vnode *, struct vnode *,
struct componentname *, struct vnode *,
struct vnode *));
struct vnode *, int));
extern int union_freevp __P((struct vnode *));
extern int union_copyfile __P((struct proc *, struct ucred *,
struct vnode *, struct vnode *));
extern int union_copyfile __P((struct vnode *, struct vnode *,
struct ucred *, struct proc *));
extern int union_copyup __P((struct union_node *, int, struct ucred *,
struct proc *));
extern int union_dowhiteout __P((struct union_node *, struct ucred *,
struct proc *));
extern int union_mkshadow __P((struct union_mount *, struct vnode *,
struct componentname *, struct vnode **));
extern int union_mkwhiteout __P((struct union_mount *, struct vnode *,
struct componentname *, char *));
extern int union_vn_create __P((struct vnode **, struct union_node *,
struct proc *));
extern int union_vn_close __P((struct vnode *, int, struct ucred *,
@ -108,6 +119,7 @@ extern void union_removed_upper __P((struct union_node *un));
extern struct vnode *union_lowervp __P((struct vnode *));
extern void union_newlower __P((struct union_node *, struct vnode *));
extern void union_newupper __P((struct union_node *, struct vnode *));
extern void union_newsize __P((struct vnode *, off_t, off_t));
#define MOUNTTOUNIONMOUNT(mp) ((struct union_mount *)((mp)->mnt_data))
#define VTOUNION(vp) ((struct union_node *)(vp)->v_data)

View File

@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)union_subr.c 8.4 (Berkeley) 2/17/94
* @(#)union_subr.c 8.20 (Berkeley) 5/20/95
* $FreeBSD$
*/
@ -48,6 +48,9 @@
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/queue.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <vm/vm.h> /* for vnode_pager_setsize */
#include <miscfs/union/union.h>
#include <sys/proc.h>
@ -118,31 +121,38 @@ union_updatevp(un, uppervp, lowervp)
{
int ohash = UNION_HASH(un->un_uppervp, un->un_lowervp);
int nhash = UNION_HASH(uppervp, lowervp);
int docache = (lowervp != NULLVP || uppervp != NULLVP);
int lhash, hhash, uhash;
if (ohash != nhash) {
/*
* Ensure locking is ordered from lower to higher
* to avoid deadlocks.
*/
if (nhash < ohash) {
int t = ohash;
ohash = nhash;
nhash = t;
}
while (union_list_lock(ohash))
continue;
while (union_list_lock(nhash))
continue;
LIST_REMOVE(un, un_cache);
union_list_unlock(ohash);
/*
* Ensure locking is ordered from lower to higher
* to avoid deadlocks.
*/
if (nhash < ohash) {
lhash = nhash;
uhash = ohash;
} else {
while (union_list_lock(nhash))
continue;
lhash = ohash;
uhash = nhash;
}
if (lhash != uhash)
while (union_list_lock(lhash))
continue;
while (union_list_lock(uhash))
continue;
if (ohash != nhash || !docache) {
if (un->un_flags & UN_CACHED) {
un->un_flags &= ~UN_CACHED;
LIST_REMOVE(un, un_cache);
}
}
if (ohash != nhash)
union_list_unlock(ohash);
if (un->un_lowervp != lowervp) {
if (un->un_lowervp) {
vrele(un->un_lowervp);
@ -156,6 +166,7 @@ union_updatevp(un, uppervp, lowervp)
}
}
un->un_lowervp = lowervp;
un->un_lowersz = VNOVAL;
}
if (un->un_uppervp != uppervp) {
@ -163,10 +174,13 @@ union_updatevp(un, uppervp, lowervp)
vrele(un->un_uppervp);
un->un_uppervp = uppervp;
un->un_uppersz = VNOVAL;
}
if (ohash != nhash)
if (docache && (ohash != nhash)) {
LIST_INSERT_HEAD(&unhead[nhash], un, un_cache);
un->un_flags |= UN_CACHED;
}
union_list_unlock(nhash);
}
@ -189,6 +203,47 @@ union_newupper(un, uppervp)
union_updatevp(un, uppervp, un->un_lowervp);
}
/*
* Keep track of size changes in the underlying vnodes.
* If the size changes, then callback to the vm layer
* giving priority to the upper layer size.
*/
void
union_newsize(vp, uppersz, lowersz)
struct vnode *vp;
off_t uppersz, lowersz;
{
struct union_node *un;
off_t sz;
/* only interested in regular files */
if (vp->v_type != VREG)
return;
un = VTOUNION(vp);
sz = VNOVAL;
if ((uppersz != VNOVAL) && (un->un_uppersz != uppersz)) {
un->un_uppersz = uppersz;
if (sz == VNOVAL)
sz = un->un_uppersz;
}
if ((lowersz != VNOVAL) && (un->un_lowersz != lowersz)) {
un->un_lowersz = lowersz;
if (sz == VNOVAL)
sz = un->un_lowersz;
}
if (sz != VNOVAL) {
#ifdef UNION_DIAGNOSTIC
printf("union: %s size now %ld\n",
uppersz != VNOVAL ? "upper" : "lower", (long) sz);
#endif
vnode_pager_setsize(vp, sz);
}
}
/*
* allocate a union_node/vnode pair. the vnode is
* referenced and locked. the new vnode is returned
@ -221,19 +276,22 @@ union_newupper(un, uppervp)
* the vnode free list.
*/
int
union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp, docache)
struct vnode **vpp;
struct mount *mp;
struct vnode *undvp;
struct vnode *undvp; /* parent union vnode */
struct vnode *dvp; /* may be null */
struct componentname *cnp; /* may be null */
struct vnode *uppervp; /* may be null */
struct vnode *lowervp; /* may be null */
int docache;
{
int error;
struct union_node *un = 0;
struct vnode *xlowervp = NULLVP;
int hash = 0;
struct union_mount *um = MOUNTTOUNIONMOUNT(mp);
int hash;
int vflag;
int try;
if (uppervp == NULLVP && lowervp == NULLVP)
@ -244,8 +302,22 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
lowervp = NULLVP;
}
/* detect the root vnode (and aliases) */
vflag = 0;
if ((uppervp == um->um_uppervp) &&
((lowervp == NULLVP) || lowervp == um->um_lowervp)) {
if (lowervp == NULLVP) {
lowervp = um->um_lowervp;
if (lowervp != NULLVP)
VREF(lowervp);
}
vflag = VROOT;
}
loop:
for (try = 0; try < 3; try++) {
if (!docache) {
un = 0;
} else for (try = 0; try < 3; try++) {
switch (try) {
case 0:
if (lowervp == NULLVP)
@ -276,7 +348,8 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
(un->un_uppervp == uppervp ||
un->un_uppervp == NULLVP) &&
(UNIONTOV(un)->v_mount == mp)) {
if (vget(UNIONTOV(un), 0)) {
if (vget(UNIONTOV(un), 0,
cnp ? cnp->cn_proc : NULL)) {
union_list_unlock(hash);
goto loop;
}
@ -359,8 +432,7 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
*/
if (lowervp != un->un_lowervp) {
union_newlower(un, lowervp);
if (cnp && (lowervp != NULLVP) &&
(lowervp->v_type == VREG)) {
if (cnp && (lowervp != NULLVP)) {
un->un_hash = cnp->cn_hash;
un->un_path = malloc(cnp->cn_namelen+1,
M_TEMP, M_WAITOK);
@ -377,14 +449,16 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
return (0);
}
/*
* otherwise lock the vp list while we call getnewvnode
* since that can block.
*/
hash = UNION_HASH(uppervp, lowervp);
if (docache) {
/*
* otherwise lock the vp list while we call getnewvnode
* since that can block.
*/
hash = UNION_HASH(uppervp, lowervp);
if (union_list_lock(hash))
goto loop;
if (union_list_lock(hash))
goto loop;
}
error = getnewvnode(VT_UNION, mp, union_vnodeop_p, vpp);
if (error) {
@ -403,6 +477,7 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
MALLOC((*vpp)->v_data, void *, sizeof(struct union_node),
M_TEMP, M_WAITOK);
(*vpp)->v_flag |= vflag;
if (uppervp)
(*vpp)->v_type = uppervp->v_type;
else
@ -410,7 +485,13 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
un = VTOUNION(*vpp);
un->un_vnode = *vpp;
un->un_uppervp = uppervp;
un->un_uppersz = VNOVAL;
un->un_lowervp = lowervp;
un->un_lowersz = VNOVAL;
un->un_pvp = undvp;
if (undvp != NULLVP)
VREF(undvp);
un->un_dircache = 0;
un->un_openl = 0;
un->un_flags = UN_LOCKED;
if (un->un_uppervp)
@ -421,7 +502,7 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
else
un->un_pid = -1;
#endif
if (cnp && (lowervp != NULLVP) && (lowervp->v_type == VREG)) {
if (cnp && (lowervp != NULLVP)) {
un->un_hash = cnp->cn_hash;
un->un_path = malloc(cnp->cn_namelen+1, M_TEMP, M_WAITOK);
bcopy(cnp->cn_nameptr, un->un_path, cnp->cn_namelen);
@ -434,13 +515,17 @@ union_allocvp(vpp, mp, undvp, dvp, cnp, uppervp, lowervp)
un->un_dirvp = 0;
}
LIST_INSERT_HEAD(&unhead[hash], un, un_cache);
if (docache) {
LIST_INSERT_HEAD(&unhead[hash], un, un_cache);
un->un_flags |= UN_CACHED;
}
if (xlowervp)
vrele(xlowervp);
out:
union_list_unlock(hash);
if (docache)
union_list_unlock(hash);
return (error);
}
@ -451,13 +536,18 @@ union_freevp(vp)
{
struct union_node *un = VTOUNION(vp);
LIST_REMOVE(un, un_cache);
if (un->un_flags & UN_CACHED) {
un->un_flags &= ~UN_CACHED;
LIST_REMOVE(un, un_cache);
}
if (un->un_uppervp)
if (un->un_pvp != NULLVP)
vrele(un->un_pvp);
if (un->un_uppervp != NULLVP)
vrele(un->un_uppervp);
if (un->un_lowervp)
if (un->un_lowervp != NULLVP)
vrele(un->un_lowervp);
if (un->un_dirvp)
if (un->un_dirvp != NULLVP)
vrele(un->un_dirvp);
if (un->un_path)
free(un->un_path, M_TEMP);
@ -474,11 +564,11 @@ union_freevp(vp)
* and (tvp) are locked on entry and exit.
*/
int
union_copyfile(p, cred, fvp, tvp)
struct proc *p;
struct ucred *cred;
union_copyfile(fvp, tvp, cred, p)
struct vnode *fvp;
struct vnode *tvp;
struct ucred *cred;
struct proc *p;
{
char *buf;
struct uio uio;
@ -497,12 +587,12 @@ union_copyfile(p, cred, fvp, tvp)
uio.uio_segflg = UIO_SYSSPACE;
uio.uio_offset = 0;
VOP_UNLOCK(fvp); /* XXX */
LEASE_CHECK(fvp, p, cred, LEASE_READ);
VOP_LOCK(fvp); /* XXX */
VOP_UNLOCK(tvp); /* XXX */
LEASE_CHECK(tvp, p, cred, LEASE_WRITE);
VOP_LOCK(tvp); /* XXX */
VOP_UNLOCK(fvp, 0, p); /* XXX */
VOP_LEASE(fvp, p, cred, LEASE_READ);
vn_lock(fvp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */
VOP_UNLOCK(tvp, 0, p); /* XXX */
VOP_LEASE(tvp, p, cred, LEASE_WRITE);
vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY, p); /* XXX */
buf = malloc(MAXBSIZE, M_TEMP, M_WAITOK);
@ -541,6 +631,123 @@ union_copyfile(p, cred, fvp, tvp)
return (error);
}
/*
* (un) is assumed to be locked on entry and remains
* locked on exit.
*/
int
union_copyup(un, docopy, cred, p)
struct union_node *un;
int docopy;
struct ucred *cred;
struct proc *p;
{
int error;
struct vnode *lvp, *uvp;
error = union_vn_create(&uvp, un, p);
if (error)
return (error);
/* at this point, uppervp is locked */
union_newupper(un, uvp);
un->un_flags |= UN_ULOCK;
lvp = un->un_lowervp;
if (docopy) {
/*
* XX - should not ignore errors
* from VOP_CLOSE
*/
vn_lock(lvp, LK_EXCLUSIVE | LK_RETRY, p);
error = VOP_OPEN(lvp, FREAD, cred, p);
if (error == 0) {
error = union_copyfile(lvp, uvp, cred, p);
VOP_UNLOCK(lvp, 0, p);
(void) VOP_CLOSE(lvp, FREAD, cred, p);
}
#ifdef UNION_DIAGNOSTIC
if (error == 0)
uprintf("union: copied up %s\n", un->un_path);
#endif
}
un->un_flags &= ~UN_ULOCK;
VOP_UNLOCK(uvp, 0, p);
union_vn_close(uvp, FWRITE, cred, p);
vn_lock(uvp, LK_EXCLUSIVE | LK_RETRY, p);
un->un_flags |= UN_ULOCK;
/*
* Subsequent IOs will go to the top layer, so
* call close on the lower vnode and open on the
* upper vnode to ensure that the filesystem keeps
* its references counts right. This doesn't do
* the right thing with (cred) and (FREAD) though.
* Ignoring error returns is not right, either.
*/
if (error == 0) {
int i;
for (i = 0; i < un->un_openl; i++) {
(void) VOP_CLOSE(lvp, FREAD, cred, p);
(void) VOP_OPEN(uvp, FREAD, cred, p);
}
un->un_openl = 0;
}
return (error);
}
static int
union_relookup(um, dvp, vpp, cnp, cn, path, pathlen)
struct union_mount *um;
struct vnode *dvp;
struct vnode **vpp;
struct componentname *cnp;
struct componentname *cn;
char *path;
int pathlen;
{
int error;
/*
* A new componentname structure must be faked up because
* there is no way to know where the upper level cnp came
* from or what it is being used for. This must duplicate
* some of the work done by NDINIT, some of the work done
* by namei, some of the work done by lookup and some of
* the work done by VOP_LOOKUP when given a CREATE flag.
* Conclusion: Horrible.
*
* The pathname buffer will be FREEed by VOP_MKDIR.
*/
cn->cn_namelen = pathlen;
cn->cn_pnbuf = malloc(cn->cn_namelen+1, M_NAMEI, M_WAITOK);
bcopy(path, cn->cn_pnbuf, cn->cn_namelen);
cn->cn_pnbuf[cn->cn_namelen] = '\0';
cn->cn_nameiop = CREATE;
cn->cn_flags = (LOCKPARENT|HASBUF|SAVENAME|SAVESTART|ISLASTCN);
cn->cn_proc = cnp->cn_proc;
if (um->um_op == UNMNT_ABOVE)
cn->cn_cred = cnp->cn_cred;
else
cn->cn_cred = um->um_cred;
cn->cn_nameptr = cn->cn_pnbuf;
cn->cn_hash = cnp->cn_hash;
cn->cn_consume = cnp->cn_consume;
VREF(dvp);
error = relookup(dvp, vpp, cn);
if (!error)
vrele(dvp);
return (error);
}
/*
* Create a shadow directory in the upper layer.
* The new vnode is returned locked.
@ -565,6 +772,19 @@ union_mkshadow(um, dvp, cnp, vpp)
struct proc *p = cnp->cn_proc;
struct componentname cn;
error = union_relookup(um, dvp, vpp, cnp, &cn,
cnp->cn_nameptr, cnp->cn_namelen);
if (error)
return (error);
if (*vpp) {
VOP_ABORTOP(dvp, &cn);
VOP_UNLOCK(dvp, 0, p);
vrele(*vpp);
*vpp = NULLVP;
return (EEXIST);
}
/*
* policy: when creating the shadow directory in the
* upper layer, create it owned by the user who did
@ -573,58 +793,65 @@ union_mkshadow(um, dvp, cnp, vpp)
* mkdir syscall). (jsp, kb)
*/
/*
* A new componentname structure must be faked up because
* there is no way to know where the upper level cnp came
* from or what it is being used for. This must duplicate
* some of the work done by NDINIT, some of the work done
* by namei, some of the work done by lookup and some of
* the work done by VOP_LOOKUP when given a CREATE flag.
* Conclusion: Horrible.
*
* The pathname buffer will be FREEed by VOP_MKDIR.
*/
cn.cn_pnbuf = malloc(cnp->cn_namelen+1, M_NAMEI, M_WAITOK);
bcopy(cnp->cn_nameptr, cn.cn_pnbuf, cnp->cn_namelen);
cn.cn_pnbuf[cnp->cn_namelen] = '\0';
cn.cn_nameiop = CREATE;
cn.cn_flags = (LOCKPARENT|HASBUF|SAVENAME|SAVESTART|ISLASTCN);
cn.cn_proc = cnp->cn_proc;
if (um->um_op == UNMNT_ABOVE)
cn.cn_cred = cnp->cn_cred;
else
cn.cn_cred = um->um_cred;
cn.cn_nameptr = cn.cn_pnbuf;
cn.cn_namelen = cnp->cn_namelen;
cn.cn_hash = cnp->cn_hash;
cn.cn_consume = cnp->cn_consume;
VREF(dvp);
error = relookup(dvp, vpp, &cn);
if (error)
return (error);
vrele(dvp);
if (*vpp) {
VOP_ABORTOP(dvp, &cn);
VOP_UNLOCK(dvp);
vrele(*vpp);
*vpp = NULLVP;
return (EEXIST);
}
VATTR_NULL(&va);
va.va_type = VDIR;
va.va_mode = um->um_cmode;
/* LEASE_CHECK: dvp is locked */
LEASE_CHECK(dvp, p, p->p_ucred, LEASE_WRITE);
/* VOP_LEASE: dvp is locked */
VOP_LEASE(dvp, p, cn.cn_cred, LEASE_WRITE);
error = VOP_MKDIR(dvp, vpp, &cn, &va);
return (error);
}
/*
* Create a whiteout entry in the upper layer.
*
* (um) points to the union mount structure for access to the
* the mounting process's credentials.
* (dvp) is the directory in which to create the whiteout.
* it is locked on entry and exit.
* (cnp) is the componentname to be created.
*/
int
union_mkwhiteout(um, dvp, cnp, path)
struct union_mount *um;
struct vnode *dvp;
struct componentname *cnp;
char *path;
{
int error;
struct vattr va;
struct proc *p = cnp->cn_proc;
struct vnode *wvp;
struct componentname cn;
VOP_UNLOCK(dvp, 0, p);
error = union_relookup(um, dvp, &wvp, cnp, &cn, path, strlen(path));
if (error) {
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
}
if (wvp) {
VOP_ABORTOP(dvp, &cn);
vrele(dvp);
vrele(wvp);
return (EEXIST);
}
/* VOP_LEASE: dvp is locked */
VOP_LEASE(dvp, p, p->p_ucred, LEASE_WRITE);
error = VOP_WHITEOUT(dvp, &cn, CREATE);
if (error)
VOP_ABORTOP(dvp, &cn);
vrele(dvp);
return (error);
}
/*
* union_vn_create: creates and opens a new shadow file
* on the upper union layer. this function is similar
@ -699,9 +926,8 @@ union_vn_create(vpp, un, p)
VATTR_NULL(vap);
vap->va_type = VREG;
vap->va_mode = cmode;
LEASE_CHECK(un->un_dirvp, p, cred, LEASE_WRITE);
error = VOP_CREATE(un->un_dirvp, &vp, &cn, vap);
if (error)
VOP_LEASE(un->un_dirvp, p, cred, LEASE_WRITE);
if (error = VOP_CREATE(un->un_dirvp, &vp, &cn, vap))
return (error);
error = VOP_OPEN(vp, fmode, cred, p);
@ -722,6 +948,7 @@ union_vn_close(vp, fmode, cred, p)
struct ucred *cred;
struct proc *p;
{
if (fmode & FWRITE)
--vp->v_writecount;
return (VOP_CLOSE(vp, fmode, cred, p));
@ -731,24 +958,137 @@ void
union_removed_upper(un)
struct union_node *un;
{
if (un->un_flags & UN_ULOCK) {
un->un_flags &= ~UN_ULOCK;
VOP_UNLOCK(un->un_uppervp);
}
struct proc *p = curproc; /* XXX */
union_newupper(un, NULLVP);
if (un->un_flags & UN_CACHED) {
un->un_flags &= ~UN_CACHED;
LIST_REMOVE(un, un_cache);
}
if (un->un_flags & UN_ULOCK) {
un->un_flags &= ~UN_ULOCK;
VOP_UNLOCK(un->un_uppervp, 0, p);
}
}
#if 0
struct vnode *
union_lowervp(vp)
struct vnode *vp;
{
struct union_node *un = VTOUNION(vp);
if (un->un_lowervp && (vp->v_type == un->un_lowervp->v_type)) {
if (vget(un->un_lowervp, 0))
return (NULLVP);
if ((un->un_lowervp != NULLVP) &&
(vp->v_type == un->un_lowervp->v_type)) {
if (vget(un->un_lowervp, 0) == 0)
return (un->un_lowervp);
}
return (un->un_lowervp);
return (NULLVP);
}
#endif
/*
* determine whether a whiteout is needed
* during a remove/rmdir operation.
*/
int
union_dowhiteout(un, cred, p)
struct union_node *un;
struct ucred *cred;
struct proc *p;
{
struct vattr va;
if (un->un_lowervp != NULLVP)
return (1);
if (VOP_GETATTR(un->un_uppervp, &va, cred, p) == 0 &&
(va.va_flags & OPAQUE))
return (1);
return (0);
}
static void
union_dircache_r(vp, vppp, cntp)
struct vnode *vp;
struct vnode ***vppp;
int *cntp;
{
struct union_node *un;
if (vp->v_op != union_vnodeop_p) {
if (vppp) {
VREF(vp);
*(*vppp)++ = vp;
if (--(*cntp) == 0)
panic("union: dircache table too small");
} else {
(*cntp)++;
}
return;
}
un = VTOUNION(vp);
if (un->un_uppervp != NULLVP)
union_dircache_r(un->un_uppervp, vppp, cntp);
if (un->un_lowervp != NULLVP)
union_dircache_r(un->un_lowervp, vppp, cntp);
}
struct vnode *
union_dircache(vp, p)
struct vnode *vp;
struct proc *p;
{
int cnt;
struct vnode *nvp;
struct vnode **vpp;
struct vnode **dircache;
struct union_node *un;
int error;
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
dircache = VTOUNION(vp)->un_dircache;
nvp = NULLVP;
if (dircache == 0) {
cnt = 0;
union_dircache_r(vp, 0, &cnt);
cnt++;
dircache = (struct vnode **)
malloc(cnt * sizeof(struct vnode *),
M_TEMP, M_WAITOK);
vpp = dircache;
union_dircache_r(vp, &vpp, &cnt);
*vpp = NULLVP;
vpp = dircache + 1;
} else {
vpp = dircache;
do {
if (*vpp++ == VTOUNION(vp)->un_uppervp)
break;
} while (*vpp != NULLVP);
}
if (*vpp == NULLVP)
goto out;
vn_lock(*vpp, LK_EXCLUSIVE | LK_RETRY, p);
VREF(*vpp);
error = union_allocvp(&nvp, vp->v_mount, NULLVP, NULLVP, 0, *vpp, NULLVP, 0);
if (error)
goto out;
VTOUNION(vp)->un_dircache = 0;
un = VTOUNION(nvp);
un->un_dircache = dircache;
out:
VOP_UNLOCK(vp, 0, p);
return (nvp);
}

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 1994 The Regents of the University of California.
* Copyright (c) 1994 Jan-Simon Pendry.
* Copyright (c) 1994, 1995 The Regents of the University of California.
* Copyright (c) 1994, 1995 Jan-Simon Pendry.
* All rights reserved.
*
* This code is derived from software donated to Berkeley by
@ -34,7 +34,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)union_vfsops.c 8.7 (Berkeley) 3/5/94
* @(#)union_vfsops.c 8.20 (Berkeley) 5/20/95
* $FreeBSD$
*/
@ -56,7 +56,7 @@
#include <sys/queue.h>
#include <miscfs/union/union.h>
extern int union_init __P((void));
extern int union_init __P((struct vfsconf *));
extern int union_fhtovp __P((struct mount *mp, struct fid *fidp,
struct mbuf *nam, struct vnode **vpp,
@ -92,7 +92,7 @@ union_mount(mp, path, data, ndp, p)
struct union_args args;
struct vnode *lowerrootvp = NULLVP;
struct vnode *upperrootvp = NULLVP;
struct union_mount *um;
struct union_mount *um = 0;
struct ucred *cred = 0;
struct ucred *scred;
struct vattr va;
@ -117,34 +117,6 @@ union_mount(mp, path, data, ndp, p)
goto bad;
}
/*
* Take a copy of the process's credentials. This isn't
* quite right since the euid will always be zero and we
* want to get the "real" users credentials. So fix up
* the uid field after taking the copy.
*/
cred = crdup(p->p_ucred);
cred->cr_uid = p->p_cred->p_ruid;
/*
* Ensure the *real* user has write permission on the
* mounted-on directory. This allows the mount_union
* command to be made setuid root so allowing anyone
* to do union mounts onto any directory on which they
* have write permission and which they also own.
*/
error = VOP_GETATTR(mp->mnt_vnodecovered, &va, cred, p);
if (error)
goto bad;
if ((va.va_uid != cred->cr_uid) &&
(cred->cr_uid != 0)) {
error = EACCES;
goto bad;
}
error = VOP_ACCESS(mp->mnt_vnodecovered, VWRITE, cred, p);
if (error)
goto bad;
/*
* Get argument
*/
@ -156,18 +128,10 @@ union_mount(mp, path, data, ndp, p)
VREF(lowerrootvp);
/*
* Find upper node. Use the real process credentials,
* not the effective ones since this will have come
* through a setuid process (mount_union). All this
* messing around with permissions is entirely bogus
* and should be removed by allowing any user straight
* past the mount system call.
* Find upper node.
*/
scred = p->p_ucred;
p->p_ucred = cred;
NDINIT(ndp, LOOKUP, FOLLOW|WANTPARENT,
UIO_USERSPACE, args.target, p);
p->p_ucred = scred;
error = namei(ndp);
if (error)
@ -218,7 +182,18 @@ union_mount(mp, path, data, ndp, p)
goto bad;
}
um->um_cred = cred;
/*
* Unless the mount is readonly, ensure that the top layer
* supports whiteout operations
*/
if ((mp->mnt_flag & MNT_RDONLY) == 0) {
error = VOP_WHITEOUT(um->um_uppervp, (struct componentname *) 0, LOOKUP);
if (error)
goto bad;
}
um->um_cred = p->p_ucred;
crhold(um->um_cred);
um->um_cmode = UN_DIRMODE &~ p->p_fd->fd_cmask;
/*
@ -246,24 +221,18 @@ union_mount(mp, path, data, ndp, p)
*/
mp->mnt_flag |= (um->um_uppervp->v_mount->mnt_flag & MNT_RDONLY);
/*
* This is a user mount. Privilege check for unmount
* will be done in union_unmount.
*/
mp->mnt_flag |= MNT_USER;
mp->mnt_data = (qaddr_t) um;
getnewfsid(mp, MOUNT_UNION);
vfs_getnewfsid(mp);
(void) copyinstr(path, mp->mnt_stat.f_mntonname, MNAMELEN - 1, &size);
bzero(mp->mnt_stat.f_mntonname + size, MNAMELEN - size);
switch (um->um_op) {
case UNMNT_ABOVE:
cp = "<above>";
cp = "<above>:";
break;
case UNMNT_BELOW:
cp = "<below>";
cp = "<below>:";
break;
case UNMNT_REPLACE:
cp = "";
@ -287,6 +256,8 @@ union_mount(mp, path, data, ndp, p)
return (0);
bad:
if (um)
free(um, M_UFSMNT);
if (cred)
crfree(cred);
if (upperrootvp)
@ -323,40 +294,55 @@ union_unmount(mp, mntflags, p)
struct union_mount *um = MOUNTTOUNIONMOUNT(mp);
struct vnode *um_rootvp;
int error;
int freeing;
int flags = 0;
#ifdef UNION_DIAGNOSTIC
printf("union_unmount(mp = %x)\n", mp);
#endif
/* only the mounter, or superuser can unmount */
if ((p->p_cred->p_ruid != um->um_cred->cr_uid) &&
(error = suser(p->p_ucred, &p->p_acflag)))
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
if (error = union_root(mp, &um_rootvp))
return (error);
if (mntflags & MNT_FORCE) {
/* union can never be rootfs so don't check for it */
if (!doforce)
return (EINVAL);
flags |= FORCECLOSE;
/*
* Keep flushing vnodes from the mount list.
* This is needed because of the un_pvp held
* reference to the parent vnode.
* If more vnodes have been freed on a given pass,
* the try again. The loop will iterate at most
* (d) times, where (d) is the maximum tree depth
* in the filesystem.
*/
for (freeing = 0; vflush(mp, um_rootvp, flags) != 0;) {
struct vnode *vp;
int n;
/* count #vnodes held on mount list */
for (n = 0, vp = mp->mnt_vnodelist.lh_first;
vp != NULLVP;
vp = vp->v_mntvnodes.le_next)
n++;
/* if this is unchanged then stop */
if (n == freeing)
break;
/* otherwise try once more time */
freeing = n;
}
error = union_root(mp, &um_rootvp);
if (error)
return (error);
/* At this point the root vnode should have a single reference */
if (um_rootvp->v_usecount > 1) {
vput(um_rootvp);
return (EBUSY);
}
error = vflush(mp, um_rootvp, flags);
if (error) {
vput(um_rootvp);
return (error);
}
#ifdef UNION_DIAGNOSTIC
vprint("alias root of lower", um_rootvp);
#endif
vprint("union root", um_rootvp);
#endif
/*
* Discard references to upper and lower target vnodes.
*/
@ -385,16 +371,11 @@ union_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
struct proc *p = curproc; /* XXX */
struct union_mount *um = MOUNTTOUNIONMOUNT(mp);
int error;
int loselock;
#ifdef UNION_DIAGNOSTIC
printf("union_root(mp = %x, lvp = %x, uvp = %x)\n", mp,
um->um_lowervp,
um->um_uppervp);
#endif
/*
* Return locked reference to root.
*/
@ -403,7 +384,7 @@ union_root(mp, vpp)
VOP_ISLOCKED(um->um_uppervp)) {
loselock = 1;
} else {
VOP_LOCK(um->um_uppervp);
vn_lock(um->um_uppervp, LK_EXCLUSIVE | LK_RETRY, p);
loselock = 0;
}
if (um->um_lowervp)
@ -413,16 +394,17 @@ union_root(mp, vpp)
(struct vnode *) 0,
(struct componentname *) 0,
um->um_uppervp,
um->um_lowervp);
um->um_lowervp,
1);
if (error) {
if (!loselock)
VOP_UNLOCK(um->um_uppervp);
vrele(um->um_uppervp);
if (loselock)
vrele(um->um_uppervp);
else
vput(um->um_uppervp);
if (um->um_lowervp)
vrele(um->um_lowervp);
} else {
(*vpp)->v_flag |= VROOT;
if (loselock)
VTOUNION(*vpp)->un_flags &= ~UN_ULOCK;
}
@ -430,18 +412,6 @@ union_root(mp, vpp)
return (error);
}
int
union_quotactl(mp, cmd, uid, arg, p)
struct mount *mp;
int cmd;
uid_t uid;
caddr_t arg;
struct proc *p;
{
return (EOPNOTSUPP);
}
int
union_statfs(mp, sbp, p)
struct mount *mp;
@ -485,7 +455,6 @@ union_statfs(mp, sbp, p)
if (error)
return (error);
sbp->f_type = MOUNT_UNION;
sbp->f_flags = mstat.f_flags;
sbp->f_bsize = mstat.f_bsize;
sbp->f_iosize = mstat.f_iosize;
@ -496,18 +465,23 @@ union_statfs(mp, sbp, p)
* kind of sense. none of this makes sense though.
*/
if (mstat.f_bsize != lbsize) {
if (mstat.f_bsize != lbsize)
sbp->f_blocks = sbp->f_blocks * lbsize / mstat.f_bsize;
sbp->f_bfree = sbp->f_bfree * lbsize / mstat.f_bsize;
sbp->f_bavail = sbp->f_bavail * lbsize / mstat.f_bsize;
}
/*
* The "total" fields count total resources in all layers,
* the "free" fields count only those resources which are
* free in the upper layer (since only the upper layer
* is writeable).
*/
sbp->f_blocks += mstat.f_blocks;
sbp->f_bfree += mstat.f_bfree;
sbp->f_bavail += mstat.f_bavail;
sbp->f_bfree = mstat.f_bfree;
sbp->f_bavail = mstat.f_bavail;
sbp->f_files += mstat.f_files;
sbp->f_ffree += mstat.f_ffree;
sbp->f_ffree = mstat.f_ffree;
if (sbp != &mp->mnt_stat) {
sbp->f_type = mp->mnt_vfc->vfc_typenum;
bcopy(&mp->mnt_stat.f_fsid, &sbp->f_fsid, sizeof(sbp->f_fsid));
bcopy(mp->mnt_stat.f_mntonname, sbp->f_mntonname, MNAMELEN);
bcopy(mp->mnt_stat.f_mntfromname, sbp->f_mntfromname, MNAMELEN);
@ -515,51 +489,21 @@ union_statfs(mp, sbp, p)
return (0);
}
int
union_sync(mp, waitfor, cred, p)
struct mount *mp;
int waitfor;
struct ucred *cred;
struct proc *p;
{
/*
* XXX - Assumes no data cached at union layer.
*/
#define union_sync ((int (*) __P((struct mount *, int, struct ucred *, \
struct proc *)))nullop)
/*
* XXX - Assumes no data cached at union layer.
*/
return (0);
}
int
union_vget(mp, ino, vpp)
struct mount *mp;
ino_t ino;
struct vnode **vpp;
{
return (EOPNOTSUPP);
}
int
union_fhtovp(mp, fidp, nam, vpp, exflagsp, credanonp)
struct mount *mp;
struct fid *fidp;
struct mbuf *nam;
struct vnode **vpp;
int *exflagsp;
struct ucred **credanonp;
{
return (EOPNOTSUPP);
}
int
union_vptofh(vp, fhp)
struct vnode *vp;
struct fid *fhp;
{
return (EOPNOTSUPP);
}
#define union_fhtovp ((int (*) __P((struct mount *, struct fid *, \
struct mbuf *, struct vnode **, int *, struct ucred **)))eopnotsupp)
#define union_quotactl ((int (*) __P((struct mount *, int, uid_t, caddr_t, \
struct proc *)))eopnotsupp)
#define union_sysctl ((int (*) __P((int *, u_int, void *, size_t *, void *, \
size_t, struct proc *)))eopnotsupp)
#define union_vget ((int (*) __P((struct mount *, ino_t, struct vnode **))) \
eopnotsupp)
#define union_vptofh ((int (*) __P((struct vnode *, struct fid *)))eopnotsupp)
struct vfsops union_vfsops = {
union_mount,

File diff suppressed because it is too large Load Diff

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufs_bmap.c 8.6 (Berkeley) 1/21/94
* @(#)ufs_bmap.c 8.7 (Berkeley) 3/21/95
* $FreeBSD$
*/
@ -63,9 +63,9 @@ int
ufs_bmap(ap)
struct vop_bmap_args /* {
struct vnode *a_vp;
daddr_t a_bn;
ufs_daddr_t a_bn;
struct vnode **a_vpp;
daddr_t *a_bnp;
ufs_daddr_t *a_bnp;
int *a_runp;
int *a_runb;
} */ *ap;
@ -100,8 +100,8 @@ ufs_bmap(ap)
int
ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb)
struct vnode *vp;
register daddr_t bn;
daddr_t *bnp;
ufs_daddr_t bn;
ufs_daddr_t *bnp;
struct indir *ap;
int *nump;
int *runp;
@ -113,7 +113,7 @@ ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb)
struct mount *mp;
struct vnode *devvp;
struct indir a[NIADDR+1], *xap;
daddr_t daddr;
ufs_daddr_t daddr;
long metalbn;
int error, maxrun = 0, num;
@ -209,12 +209,13 @@ ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb)
}
}
daddr = ((daddr_t *)bp->b_data)[xap->in_off];
daddr = ((ufs_daddr_t *)bp->b_data)[xap->in_off];
if (num == 1 && daddr && runp) {
for (bn = xap->in_off + 1;
bn < MNINDIR(ump) && *runp < maxrun &&
is_sequential(ump, ((daddr_t *)bp->b_data)[bn - 1],
((daddr_t *)bp->b_data)[bn]);
is_sequential(ump,
((ufs_daddr_t *)bp->b_data)[bn - 1],
((ufs_daddr_t *)bp->b_data)[bn]);
++bn, ++*runp);
bn = xap->in_off;
if (runb && bn) {
@ -245,7 +246,7 @@ ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb)
int
ufs_getlbns(vp, bn, ap, nump)
struct vnode *vp;
register daddr_t bn;
ufs_daddr_t bn;
struct indir *ap;
int *nump;
{

View File

@ -56,7 +56,7 @@ int ext2_blkatoff __P((struct vop_blkatoff_args *));
void ext2_blkfree __P((struct inode *, daddr_t, long));
daddr_t ext2_blkpref __P((struct inode *, daddr_t, int, daddr_t *, daddr_t));
int ext2_bmap __P((struct vop_bmap_args *));
int ext2_init __P((void));
int ext2_init __P((struct vfsconf *));
int ext2_reallocblks __P((struct vop_reallocblks_args *));
int ext2_reclaim __P((struct vop_reclaim_args *));
void ext2_setblock __P((struct ext2_sb_info *, u_char *, daddr_t));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1982, 1986, 1989, 1991, 1993
* Copyright (c) 1982, 1986, 1989, 1991, 1993, 1995
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufs_ihash.c 8.4 (Berkeley) 12/30/93
* @(#)ufs_ihash.c 8.7 (Berkeley) 5/17/95
* $FreeBSD$
*/
@ -47,9 +47,10 @@
/*
* Structures associated with inode cacheing.
*/
struct inode **ihashtbl;
LIST_HEAD(ihashhead, inode) *ihashtbl;
u_long ihash; /* size of hash table - 1 */
#define INOHASH(device, inum) (((device) + (inum)) & ihash)
#define INOHASH(device, inum) (&ihashtbl[((device) + (inum)) & ihash])
struct simplelock ufs_ihash_slock;
/*
* Initialize inode hash table.
@ -59,6 +60,7 @@ ufs_ihashinit()
{
ihashtbl = hashinit(desiredvnodes, M_UFSMNT, &ihash);
simple_lock_init(&ufs_ihash_slock);
}
/*
@ -66,19 +68,21 @@ ufs_ihashinit()
* to it. If it is in core, return it, even if it is locked.
*/
struct vnode *
ufs_ihashlookup(device, inum)
dev_t device;
ufs_ihashlookup(dev, inum)
dev_t dev;
ino_t inum;
{
register struct inode *ip;
struct inode *ip;
for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) {
if (ip == NULL)
return (NULL);
if (inum == ip->i_number && device == ip->i_dev)
return (ITOV(ip));
}
/* NOTREACHED */
simple_lock(&ufs_ihash_slock);
for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next)
if (inum == ip->i_number && dev == ip->i_dev)
break;
simple_unlock(&ufs_ihash_slock);
if (ip)
return (ITOV(ip));
return (NULLVP);
}
/*
@ -86,36 +90,28 @@ ufs_ihashlookup(device, inum)
* to it. If it is in core, but locked, wait for it.
*/
struct vnode *
ufs_ihashget(device, inum)
dev_t device;
ufs_ihashget(dev, inum)
dev_t dev;
ino_t inum;
{
register struct inode *ip;
struct proc *p = curproc; /* XXX */
struct inode *ip;
struct vnode *vp;
for (;;)
for (ip = ihashtbl[INOHASH(device, inum)];; ip = ip->i_next) {
if (ip == NULL)
return (NULL);
if (inum == ip->i_number && device == ip->i_dev) {
if (ip->i_flag & IN_LOCKED) {
if( curproc->p_pid != ip->i_lockholder) {
ip->i_flag |= IN_WANTED;
(void) tsleep(ip, PINOD, "uihget", 0);
break;
} else if (ip->i_flag & IN_RECURSE) {
ip->i_lockcount++;
} else {
panic("ufs_ihashget: recursive lock not expected -- pid %d\n", ip->i_lockholder);
}
}
vp = ITOV(ip);
if (!vget(vp, 1))
return (vp);
break;
}
loop:
simple_lock(&ufs_ihash_slock);
for (ip = INOHASH(dev, inum)->lh_first; ip; ip = ip->i_hash.le_next) {
if (inum == ip->i_number && dev == ip->i_dev) {
vp = ITOV(ip);
simple_lock(&vp->v_interlock);
simple_unlock(&ufs_ihash_slock);
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK, p))
goto loop;
return (vp);
}
/* NOTREACHED */
}
simple_unlock(&ufs_ihash_slock);
return (NULL);
}
/*
@ -125,26 +121,16 @@ void
ufs_ihashins(ip)
struct inode *ip;
{
struct inode **ipp, *iq;
struct proc *p = curproc; /* XXX */
struct ihashhead *ipp;
ipp = &ihashtbl[INOHASH(ip->i_dev, ip->i_number)];
iq = *ipp;
if (iq)
iq->i_prev = &ip->i_next;
ip->i_next = iq;
ip->i_prev = ipp;
*ipp = ip;
if ((ip->i_flag & IN_LOCKED) &&
((ip->i_flag & IN_RECURSE) == 0 ||
(!curproc || (curproc && (ip->i_lockholder != curproc->p_pid)))))
panic("ufs_ihashins: already locked");
if (curproc) {
ip->i_lockcount += 1;
ip->i_lockholder = curproc->p_pid;
} else {
ip->i_lockholder = -1;
}
ip->i_flag |= IN_LOCKED;
/* lock the inode, then put it on the appropriate hash list */
lockmgr(&ip->i_lock, LK_EXCLUSIVE, (struct simplelock *)0, p);
simple_lock(&ufs_ihash_slock);
ipp = INOHASH(ip->i_dev, ip->i_number);
LIST_INSERT_HEAD(ipp, ip, i_hash);
simple_unlock(&ufs_ihash_slock);
}
/*
@ -152,16 +138,13 @@ ufs_ihashins(ip)
*/
void
ufs_ihashrem(ip)
register struct inode *ip;
struct inode *ip;
{
register struct inode *iq;
iq = ip->i_next;
if (iq)
iq->i_prev = ip->i_prev;
*ip->i_prev = iq;
simple_lock(&ufs_ihash_slock);
LIST_REMOVE(ip, i_hash);
#ifdef DIAGNOSTIC
ip->i_next = NULL;
ip->i_prev = NULL;
ip->i_hash.le_next = NULL;
ip->i_hash.le_prev = NULL;
#endif
simple_unlock(&ufs_ihash_slock);
}

View File

@ -77,9 +77,9 @@ static int ext2_indirtrunc __P((struct inode *, daddr_t, daddr_t, daddr_t, int,
long *));
int
ext2_init()
ext2_init(struct vfsconf *vfsp)
{
return (ufs_init());
return (ufs_init(vfsp));
}
/*
@ -118,16 +118,16 @@ ext2_update(ap)
(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)
return (0);
if (ip->i_flag & IN_ACCESS)
ip->i_atime.tv_sec = ap->a_access->tv_sec;
ip->i_atime = ap->a_access->tv_sec;
if (ip->i_flag & IN_UPDATE) {
ip->i_mtime.tv_sec = ap->a_modify->tv_sec;
ip->i_mtime = ap->a_modify->tv_sec;
ip->i_modrev++;
}
if (ip->i_flag & IN_CHANGE) {
#if !defined(__FreeBSD__)
get_time(&time);
#endif
ip->i_ctime.tv_sec = time.tv_sec;
ip->i_ctime = time.tv_sec;
}
ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
fs = ip->i_e2fs;

View File

@ -66,17 +66,17 @@ ext2_print_dinode( di )
di->di_uid, di->di_gid, di->di_size);
printf( "Links: %3d Blockcount: %d\n",
di->di_nlink, di->di_blocks);
printf( "ctime: 0x%x", di->di_ctime.tv_sec);
printf( "ctime: 0x%x", di->di_ctime);
#if !defined(__FreeBSD__)
print_time(" -- %s\n", di->di_ctime.tv_sec);
print_time(" -- %s\n", di->di_ctime);
#endif
printf( "atime: 0x%x", di->di_atime.tv_sec);
printf( "atime: 0x%x", di->di_atime);
#if !defined(__FreeBSD__)
print_time(" -- %s\n", di->di_atime.tv_sec);
print_time(" -- %s\n", di->di_atime);
#endif
printf( "mtime: 0x%x", di->di_mtime.tv_sec);
printf( "mtime: 0x%x", di->di_mtime);
#if !defined(__FreeBSD__)
print_time(" -- %s\n", di->di_mtime.tv_sec);
print_time(" -- %s\n", di->di_mtime);
#endif
printf( "BLOCKS: ");
for(i=0; i < (di->di_blocks <= 24 ? ((di->di_blocks+1)/2): 12); i++)
@ -110,9 +110,9 @@ ext2_ei2di(ei, di)
*/
di->di_mode = ei->i_links_count ? ei->i_mode : 0;
di->di_size = ei->i_size;
di->di_atime.tv_sec = ei->i_atime;
di->di_mtime.tv_sec = ei->i_mtime;
di->di_ctime.tv_sec = ei->i_ctime;
di->di_atime = ei->i_atime;
di->di_mtime = ei->i_mtime;
di->di_ctime = ei->i_ctime;
di->di_flags = 0;
di->di_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0;
di->di_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0;
@ -143,11 +143,11 @@ ext2_di2ei(di, ei)
Godmar thinks: if dtime is nonzero, ext2 says this inode
has been deleted, this would correspond to a zero link count
*/
ei->i_dtime = ei->i_links_count ? 0 : di->di_mtime.tv_sec;
ei->i_dtime = ei->i_links_count ? 0 : di->di_mtime;
ei->i_size = di->di_size;
ei->i_atime = di->di_atime.tv_sec;
ei->i_mtime = di->di_mtime.tv_sec;
ei->i_ctime = di->di_ctime.tv_sec;
ei->i_atime = di->di_atime;
ei->i_mtime = di->di_mtime;
ei->i_ctime = di->di_ctime;
ei->i_flags = di->di_flags;
ei->i_flags = 0;
ei->i_flags |= (di->di_flags & APPEND) ? EXT2_APPEND_FL: 0;

View File

@ -274,6 +274,7 @@ ext2_lookup(ap)
struct ucred *cred = cnp->cn_cred;
int flags = cnp->cn_flags;
int nameiop = cnp->cn_nameiop;
struct proc *p = cnp->cn_proc;
int DIRBLKSIZ = VTOI(ap->a_dvp)->i_e2fs->s_blocksize;
@ -318,14 +319,14 @@ ext2_lookup(ap)
VREF(vdp);
error = 0;
} else if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp);
error = vget(vdp, 1);
VOP_UNLOCK(pdp, 0, p);
error = vget(vdp, LK_EXCLUSIVE, p);
if (!error && lockparent && (flags & ISLASTCN))
error = VOP_LOCK(pdp);
error = vn_lock(pdp, LK_EXCLUSIVE, p);
} else {
error = vget(vdp, 1);
error = vget(vdp, LK_EXCLUSIVE, p);
if (!lockparent || error || !(flags & ISLASTCN))
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, p);
}
/*
* Check that the capability number did not change
@ -336,9 +337,9 @@ ext2_lookup(ap)
return (0);
vput(vdp);
if (lockparent && pdp != vdp && (flags & ISLASTCN))
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, p);
}
if (error = VOP_LOCK(pdp))
if (error = vn_lock(pdp, LK_EXCLUSIVE, p))
return (error);
vdp = pdp;
dp = VTOI(pdp);
@ -548,7 +549,7 @@ ext2_lookup(ap)
*/
cnp->cn_flags |= SAVENAME;
if (!lockparent)
VOP_UNLOCK(vdp);
VOP_UNLOCK(vdp, 0, p);
return (EJUSTRETURN);
}
/*
@ -625,7 +626,7 @@ ext2_lookup(ap)
}
*vpp = tdp;
if (!lockparent)
VOP_UNLOCK(vdp);
VOP_UNLOCK(vdp, 0, p);
return (0);
}
@ -650,7 +651,7 @@ ext2_lookup(ap)
*vpp = tdp;
cnp->cn_flags |= SAVENAME;
if (!lockparent)
VOP_UNLOCK(vdp);
VOP_UNLOCK(vdp, 0, p);
return (0);
}
@ -675,13 +676,13 @@ ext2_lookup(ap)
*/
pdp = vdp;
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp); /* race to get the inode */
VOP_UNLOCK(pdp, 0, p); /* race to get the inode */
if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) {
VOP_LOCK(pdp);
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
}
if (lockparent && (flags & ISLASTCN) &&
(error = VOP_LOCK(pdp))) {
(error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
vput(tdp);
return (error);
}
@ -693,7 +694,7 @@ ext2_lookup(ap)
if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp))
return (error);
if (!lockparent || !(flags & ISLASTCN))
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, p);
*vpp = tdp;
}

View File

@ -30,13 +30,34 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufsmount.h 8.2 (Berkeley) 1/12/94
* @(#)ufsmount.h 8.6 (Berkeley) 3/30/95
* $FreeBSD$
*/
#ifndef _UFS_UFS_UFSMOUNT_H_
#define _UFS_UFS_UFSMOUNT_H_
/*
* Arguments to mount UFS-based filesystems
*/
struct ufs_args {
char *fspec; /* block special device to mount */
struct export_args export; /* network export information */
};
#ifdef MFS
/*
* Arguments to mount MFS
*/
struct mfs_args {
char *fspec; /* name to export for statfs */
struct export_args export; /* if exported MFSes are supported */
caddr_t base; /* base of file system in memory */
u_long size; /* size of file system */
};
#endif /* MFS */
#ifdef KERNEL
struct buf;
struct inode;
struct nameidata;
@ -51,6 +72,7 @@ struct ufsmount {
struct mount *um_mountp; /* filesystem vfs structure */
dev_t um_dev; /* device mounted */
struct vnode *um_devvp; /* block device mounted vnode */
union { /* pointer to superblock */
struct lfs *lfs; /* LFS */
struct fs *fs; /* FFS */
@ -60,6 +82,7 @@ struct ufsmount {
#define um_lfs ufsmount_u.lfs
#define um_e2fs ufsmount_u.e2fs
#define um_e2fsb ufsmount_u.e2fs->s_es
struct vnode *um_quotas[MAXQUOTAS]; /* pointer to quota files */
struct ucred *um_cred[MAXQUOTAS]; /* quota file access cred */
u_long um_nindir; /* indirect ptrs per block */
@ -69,7 +92,9 @@ struct ufsmount {
time_t um_itime[MAXQUOTAS]; /* inode quota time limit */
char um_qflags[MAXQUOTAS]; /* quota specific flags */
struct netexport um_export; /* export information */
int64_t um_savedmaxfilesize; /* XXX - limit maxfilesize */
};
/*
* Flags describing the state of quotas.
*/
@ -83,8 +108,9 @@ struct ufsmount {
* Macros to access file system parameters in the ufsmount structure.
* Used by ufs_bmap.
*/
#define blkptrtodb(ump, b) ((b) << (ump)->um_bptrtodb)
#define is_sequential(ump, a, b) ((b) == (a) + ump->um_seqinc)
#define MNINDIR(ump) ((ump)->um_nindir)
#define MNINDIR(ump) ((ump)->um_nindir)
#define blkptrtodb(ump, b) ((b) << (ump)->um_bptrtodb)
#define is_sequential(ump, a, b) ((b) == (a) + ump->um_seqinc)
#endif /* KERNEL */
#endif

View File

@ -221,10 +221,10 @@ ext2_mount(mp, path, data, ndp, p)
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
if (vfs_busy(mp))
if (vfs_busy(mp, LK_NOWAIT, 0, p))
return (EBUSY);
error = ext2_flushfiles(mp, flags, p);
vfs_unbusy(mp);
vfs_unbusy(mp, p);
}
if (!error && (mp->mnt_flag & MNT_RELOAD))
error = ext2_reload(mp, ndp->ni_cnd.cn_cred, p);
@ -515,7 +515,7 @@ ext2_reload(mountp, cred, p)
/*
* Step 5: invalidate all cached file data.
*/
if (vget(vp, 1))
if (vget(vp, LK_EXCLUSIVE, p))
goto loop;
if (vinvalbuf(vp, 0, cred, p, 0, 0))
panic("ext2_reload: dirty2");
@ -727,17 +727,12 @@ ext2_flushfiles(mp, flags, p)
int flags;
struct proc *p;
{
#if !defined(__FreeBSD__)
extern int doforce;
#endif
register struct ufsmount *ump;
int error;
#if QUOTA
int i;
#endif
if (!doforce)
flags &= ~FORCECLOSE;
ump = VFSTOUFS(mp);
#if QUOTA
if (mp->mnt_flag & MNT_QUOTA) {
@ -872,7 +867,7 @@ ext2_sync(mp, waitfor, cred, p)
(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
vp->v_dirtyblkhd.lh_first == NULL)
continue;
if (vget(vp, 1))
if (vget(vp, LK_EXCLUSIVE, p))
goto loop;
if (error = VOP_FSYNC(vp, cred, waitfor, p))
allerror = error;

View File

@ -152,6 +152,6 @@ extern u_char *fragtbl[];
* I think I'll try a VOP_LOCK/VOP_UNLOCK on the device vnode
*/
#define DEVVP(inode) (VFSTOUFS(ITOV(inode)->v_mount)->um_devvp)
#define lock_super(devvp) VOP_LOCK(devvp)
#define unlock_super(devvp) VOP_UNLOCK(devvp)
#define lock_super(devvp) vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, curproc)
#define unlock_super(devvp) VOP_UNLOCK(devvp, 0, curproc)

View File

@ -35,42 +35,33 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)inode.h 8.4 (Berkeley) 1/21/94
* @(#)inode.h 8.9 (Berkeley) 5/14/95
* $FreeBSD$
*/
#ifndef _UFS_UFS_INODE_H_
#define _UFS_UFS_INODE_H_
#include <ufs/ufs/dir.h>
#include <ufs/ufs/dinode.h>
/*
* Theoretically, directories can 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
/*
* The inode is used to describe each active (or recently active)
* file in the UFS filesystem. It is composed of two types of
* information. The first part is the information that is needed
* only while the file is active (such as the identity of the file
* and linkage to speed its lookup). The second part is the
* permanent meta-data associated with the file which is read
* in from the permanent dinode from long term storage when the
* file becomes active, and is put back when the file is no longer
* being used.
* The inode is used to describe each active (or recently active) file in the
* UFS filesystem. It is composed of two types of information. The first part
* is the information that is needed only while the file is active (such as
* the identity of the file and linkage to speed its lookup). The second part
* is the permanent meta-data associated with the file which is read in
* from the permanent dinode from long term storage when the file becomes
* active, and is put back when the file is no longer being used.
*/
struct inode {
struct inode *i_next; /* Hash chain forward. */
struct inode **i_prev; /* Hash chain back. */
struct vnode *i_vnode; /* Vnode associated with this inode. */
struct vnode *i_devvp; /* Vnode for block I/O. */
u_long i_flag; /* I* flags. */
dev_t i_dev; /* Device associated with the inode. */
ino_t i_number; /* The identity of the inode. */
LIST_ENTRY(inode) i_hash;/* Hash chain. */
struct vnode *i_vnode;/* Vnode associated with this inode. */
struct vnode *i_devvp;/* Vnode for block I/O. */
u_int32_t i_flag; /* flags, see below */
dev_t i_dev; /* Device associated with the inode. */
ino_t i_number; /* The identity of the inode. */
union { /* Associated filesystem. */
struct fs *fs; /* FFS */
struct lfs *lfs; /* LFS */
@ -79,22 +70,21 @@ struct inode {
#define i_fs inode_u.fs
#define i_lfs inode_u.lfs
#define i_e2fs inode_u.e2fs
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for lease. */
struct lockf *i_lockf; /* Head of byte-level lock list. */
pid_t i_lockholder; /* DEBUG: holder of inode lock. */
pid_t i_lockwaiter; /* DEBUG: latest blocked for inode lock. */
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for NFS lease. */
struct lockf *i_lockf;/* Head of byte-level lock list. */
struct lock i_lock; /* Inode lock. */
/*
* Side effects; used during directory lookup.
*/
long i_count; /* Size of free slot in directory. */
doff_t i_endoff; /* End of useful stuff in directory. */
doff_t i_diroff; /* Offset in dir, where we found last entry. */
doff_t i_offset; /* Offset of free space in directory. */
ino_t i_ino; /* Inode number of found directory. */
u_long i_reclen; /* Size of found directory entry. */
int i_lockcount; /* Process lock count (recursion) */
long i_spare[10]; /* Spares to round up to 128 bytes. */
int32_t i_count; /* Size of free slot in directory. */
doff_t i_endoff; /* End of useful stuff in directory. */
doff_t i_diroff; /* Offset in dir, where we found last entry. */
doff_t i_offset; /* Offset of free space in directory. */
ino_t i_ino; /* Inode number of found directory. */
u_int32_t i_reclen; /* Size of found directory entry. */
int i_lockcount; /* Process lock count (recursion) */
int i_spare[10]; /* XXX spare storage (for ext2fs) */
/*
* The on-disk dinode itself.
*/
@ -102,8 +92,10 @@ struct inode {
};
#define i_atime i_din.di_atime
#define i_atimensec i_din.di_atimensec
#define i_blocks i_din.di_blocks
#define i_ctime i_din.di_ctime
#define i_ctimensec i_din.di_ctimensec
#define i_db i_din.di_db
#define i_flags i_din.di_flags
#define i_gen i_din.di_gen
@ -111,6 +103,7 @@ struct inode {
#define i_ib i_din.di_ib
#define i_mode i_din.di_mode
#define i_mtime i_din.di_mtime
#define i_mtimensec i_din.di_mtimensec
#define i_nlink i_din.di_nlink
#define i_rdev i_din.di_rdev
#define i_shortlink i_din.di_shortlink
@ -120,15 +113,12 @@ struct inode {
/* These flags are kept in i_flag. */
#define IN_ACCESS 0x0001 /* Access time update request. */
#define IN_CHANGE 0x0002 /* Inode change time update request. */
#define IN_EXLOCK 0x0004 /* File has exclusive lock. */
#define IN_LOCKED 0x0008 /* Inode lock. */
#define IN_LWAIT 0x0010 /* Process waiting on file lock. */
#define IN_MODIFIED 0x0020 /* Inode has been modified. */
#define IN_RENAME 0x0040 /* Inode is being renamed. */
#define IN_SHLOCK 0x0080 /* File has shared lock. */
#define IN_UPDATE 0x0100 /* Modification time update request. */
#define IN_WANTED 0x0200 /* Inode is wanted by a process. */
#define IN_RECURSE 0x0400 /* Recursion expected */
#define IN_UPDATE 0x0004 /* Modification time update request. */
#define IN_MODIFIED 0x0008 /* Inode has been modified. */
#define IN_RENAME 0x0010 /* Inode is being renamed. */
#define IN_SHLOCK 0x0020 /* File has shared lock. */
#define IN_EXLOCK 0x0040 /* File has exclusive lock. */
#define IN_RECURSE 0x0080 /* Recursion expected */
#ifdef KERNEL
/*
@ -136,7 +126,7 @@ struct inode {
* ufs_getlbns and used by truncate and bmap code.
*/
struct indir {
daddr_t in_lbn; /* Logical block number. */
ufs_daddr_t in_lbn; /* Logical block number. */
int in_off; /* Offset in buffer. */
int in_exists; /* Flag if the block exists. */
};
@ -155,25 +145,25 @@ struct indir {
if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
(ip)->i_flag |= IN_MODIFIED; \
if ((ip)->i_flag & IN_ACCESS) \
(ip)->i_atime.tv_sec \
(ip)->i_atime \
= ((t1) == &time ? tv_sec : (t1)->tv_sec); \
if ((ip)->i_flag & IN_UPDATE) { \
(ip)->i_mtime.tv_sec \
(ip)->i_mtime \
= ((t2) == &time ? tv_sec : (t2)->tv_sec); \
(ip)->i_modrev++; \
} \
if ((ip)->i_flag & IN_CHANGE) \
(ip)->i_ctime.tv_sec = tv_sec; \
(ip)->i_ctime = tv_sec; \
(ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
} \
}
/* This overlays the fid structure (see mount.h). */
struct ufid {
u_short ufid_len; /* Length of structure. */
u_short ufid_pad; /* Force long alignment. */
ino_t ufid_ino; /* File number (ino). */
long ufid_gen; /* Generation number. */
u_int16_t ufid_len; /* Length of structure. */
u_int16_t ufid_pad; /* Force 32-bit alignment. */
ino_t ufid_ino; /* File number (ino). */
int32_t ufid_gen; /* Generation number. */
};
#endif /* KERNEL */

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufs_bmap.c 8.6 (Berkeley) 1/21/94
* @(#)ufs_bmap.c 8.7 (Berkeley) 3/21/95
* $FreeBSD$
*/
@ -63,9 +63,9 @@ int
ufs_bmap(ap)
struct vop_bmap_args /* {
struct vnode *a_vp;
daddr_t a_bn;
ufs_daddr_t a_bn;
struct vnode **a_vpp;
daddr_t *a_bnp;
ufs_daddr_t *a_bnp;
int *a_runp;
int *a_runb;
} */ *ap;
@ -100,8 +100,8 @@ ufs_bmap(ap)
int
ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb)
struct vnode *vp;
register daddr_t bn;
daddr_t *bnp;
ufs_daddr_t bn;
ufs_daddr_t *bnp;
struct indir *ap;
int *nump;
int *runp;
@ -113,7 +113,7 @@ ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb)
struct mount *mp;
struct vnode *devvp;
struct indir a[NIADDR+1], *xap;
daddr_t daddr;
ufs_daddr_t daddr;
long metalbn;
int error, maxrun = 0, num;
@ -209,12 +209,13 @@ ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb)
}
}
daddr = ((daddr_t *)bp->b_data)[xap->in_off];
daddr = ((ufs_daddr_t *)bp->b_data)[xap->in_off];
if (num == 1 && daddr && runp) {
for (bn = xap->in_off + 1;
bn < MNINDIR(ump) && *runp < maxrun &&
is_sequential(ump, ((daddr_t *)bp->b_data)[bn - 1],
((daddr_t *)bp->b_data)[bn]);
is_sequential(ump,
((ufs_daddr_t *)bp->b_data)[bn - 1],
((ufs_daddr_t *)bp->b_data)[bn]);
++bn, ++*runp);
bn = xap->in_off;
if (runb && bn) {
@ -245,7 +246,7 @@ ufs_bmaparray(vp, bn, bnp, ap, nump, runp, runb)
int
ufs_getlbns(vp, bn, ap, nump)
struct vnode *vp;
register daddr_t bn;
ufs_daddr_t bn;
struct indir *ap;
int *nump;
{

View File

@ -56,7 +56,7 @@ int ext2_blkatoff __P((struct vop_blkatoff_args *));
void ext2_blkfree __P((struct inode *, daddr_t, long));
daddr_t ext2_blkpref __P((struct inode *, daddr_t, int, daddr_t *, daddr_t));
int ext2_bmap __P((struct vop_bmap_args *));
int ext2_init __P((void));
int ext2_init __P((struct vfsconf *));
int ext2_reallocblks __P((struct vop_reallocblks_args *));
int ext2_reclaim __P((struct vop_reclaim_args *));
void ext2_setblock __P((struct ext2_sb_info *, u_char *, daddr_t));

View File

@ -77,9 +77,9 @@ static int ext2_indirtrunc __P((struct inode *, daddr_t, daddr_t, daddr_t, int,
long *));
int
ext2_init()
ext2_init(struct vfsconf *vfsp)
{
return (ufs_init());
return (ufs_init(vfsp));
}
/*
@ -118,16 +118,16 @@ ext2_update(ap)
(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0)
return (0);
if (ip->i_flag & IN_ACCESS)
ip->i_atime.tv_sec = ap->a_access->tv_sec;
ip->i_atime = ap->a_access->tv_sec;
if (ip->i_flag & IN_UPDATE) {
ip->i_mtime.tv_sec = ap->a_modify->tv_sec;
ip->i_mtime = ap->a_modify->tv_sec;
ip->i_modrev++;
}
if (ip->i_flag & IN_CHANGE) {
#if !defined(__FreeBSD__)
get_time(&time);
#endif
ip->i_ctime.tv_sec = time.tv_sec;
ip->i_ctime = time.tv_sec;
}
ip->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE);
fs = ip->i_e2fs;

View File

@ -66,17 +66,17 @@ ext2_print_dinode( di )
di->di_uid, di->di_gid, di->di_size);
printf( "Links: %3d Blockcount: %d\n",
di->di_nlink, di->di_blocks);
printf( "ctime: 0x%x", di->di_ctime.tv_sec);
printf( "ctime: 0x%x", di->di_ctime);
#if !defined(__FreeBSD__)
print_time(" -- %s\n", di->di_ctime.tv_sec);
print_time(" -- %s\n", di->di_ctime);
#endif
printf( "atime: 0x%x", di->di_atime.tv_sec);
printf( "atime: 0x%x", di->di_atime);
#if !defined(__FreeBSD__)
print_time(" -- %s\n", di->di_atime.tv_sec);
print_time(" -- %s\n", di->di_atime);
#endif
printf( "mtime: 0x%x", di->di_mtime.tv_sec);
printf( "mtime: 0x%x", di->di_mtime);
#if !defined(__FreeBSD__)
print_time(" -- %s\n", di->di_mtime.tv_sec);
print_time(" -- %s\n", di->di_mtime);
#endif
printf( "BLOCKS: ");
for(i=0; i < (di->di_blocks <= 24 ? ((di->di_blocks+1)/2): 12); i++)
@ -110,9 +110,9 @@ ext2_ei2di(ei, di)
*/
di->di_mode = ei->i_links_count ? ei->i_mode : 0;
di->di_size = ei->i_size;
di->di_atime.tv_sec = ei->i_atime;
di->di_mtime.tv_sec = ei->i_mtime;
di->di_ctime.tv_sec = ei->i_ctime;
di->di_atime = ei->i_atime;
di->di_mtime = ei->i_mtime;
di->di_ctime = ei->i_ctime;
di->di_flags = 0;
di->di_flags |= (ei->i_flags & EXT2_APPEND_FL) ? APPEND : 0;
di->di_flags |= (ei->i_flags & EXT2_IMMUTABLE_FL) ? IMMUTABLE : 0;
@ -143,11 +143,11 @@ ext2_di2ei(di, ei)
Godmar thinks: if dtime is nonzero, ext2 says this inode
has been deleted, this would correspond to a zero link count
*/
ei->i_dtime = ei->i_links_count ? 0 : di->di_mtime.tv_sec;
ei->i_dtime = ei->i_links_count ? 0 : di->di_mtime;
ei->i_size = di->di_size;
ei->i_atime = di->di_atime.tv_sec;
ei->i_mtime = di->di_mtime.tv_sec;
ei->i_ctime = di->di_ctime.tv_sec;
ei->i_atime = di->di_atime;
ei->i_mtime = di->di_mtime;
ei->i_ctime = di->di_ctime;
ei->i_flags = di->di_flags;
ei->i_flags = 0;
ei->i_flags |= (di->di_flags & APPEND) ? EXT2_APPEND_FL: 0;

View File

@ -274,6 +274,7 @@ ext2_lookup(ap)
struct ucred *cred = cnp->cn_cred;
int flags = cnp->cn_flags;
int nameiop = cnp->cn_nameiop;
struct proc *p = cnp->cn_proc;
int DIRBLKSIZ = VTOI(ap->a_dvp)->i_e2fs->s_blocksize;
@ -318,14 +319,14 @@ ext2_lookup(ap)
VREF(vdp);
error = 0;
} else if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp);
error = vget(vdp, 1);
VOP_UNLOCK(pdp, 0, p);
error = vget(vdp, LK_EXCLUSIVE, p);
if (!error && lockparent && (flags & ISLASTCN))
error = VOP_LOCK(pdp);
error = vn_lock(pdp, LK_EXCLUSIVE, p);
} else {
error = vget(vdp, 1);
error = vget(vdp, LK_EXCLUSIVE, p);
if (!lockparent || error || !(flags & ISLASTCN))
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, p);
}
/*
* Check that the capability number did not change
@ -336,9 +337,9 @@ ext2_lookup(ap)
return (0);
vput(vdp);
if (lockparent && pdp != vdp && (flags & ISLASTCN))
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, p);
}
if (error = VOP_LOCK(pdp))
if (error = vn_lock(pdp, LK_EXCLUSIVE, p))
return (error);
vdp = pdp;
dp = VTOI(pdp);
@ -548,7 +549,7 @@ ext2_lookup(ap)
*/
cnp->cn_flags |= SAVENAME;
if (!lockparent)
VOP_UNLOCK(vdp);
VOP_UNLOCK(vdp, 0, p);
return (EJUSTRETURN);
}
/*
@ -625,7 +626,7 @@ ext2_lookup(ap)
}
*vpp = tdp;
if (!lockparent)
VOP_UNLOCK(vdp);
VOP_UNLOCK(vdp, 0, p);
return (0);
}
@ -650,7 +651,7 @@ ext2_lookup(ap)
*vpp = tdp;
cnp->cn_flags |= SAVENAME;
if (!lockparent)
VOP_UNLOCK(vdp);
VOP_UNLOCK(vdp, 0, p);
return (0);
}
@ -675,13 +676,13 @@ ext2_lookup(ap)
*/
pdp = vdp;
if (flags & ISDOTDOT) {
VOP_UNLOCK(pdp); /* race to get the inode */
VOP_UNLOCK(pdp, 0, p); /* race to get the inode */
if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) {
VOP_LOCK(pdp);
vn_lock(pdp, LK_EXCLUSIVE | LK_RETRY, p);
return (error);
}
if (lockparent && (flags & ISLASTCN) &&
(error = VOP_LOCK(pdp))) {
(error = vn_lock(pdp, LK_EXCLUSIVE, p))) {
vput(tdp);
return (error);
}
@ -693,7 +694,7 @@ ext2_lookup(ap)
if (error = VFS_VGET(vdp->v_mount, dp->i_ino, &tdp))
return (error);
if (!lockparent || !(flags & ISLASTCN))
VOP_UNLOCK(pdp);
VOP_UNLOCK(pdp, 0, p);
*vpp = tdp;
}

View File

@ -30,13 +30,34 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufsmount.h 8.2 (Berkeley) 1/12/94
* @(#)ufsmount.h 8.6 (Berkeley) 3/30/95
* $FreeBSD$
*/
#ifndef _UFS_UFS_UFSMOUNT_H_
#define _UFS_UFS_UFSMOUNT_H_
/*
* Arguments to mount UFS-based filesystems
*/
struct ufs_args {
char *fspec; /* block special device to mount */
struct export_args export; /* network export information */
};
#ifdef MFS
/*
* Arguments to mount MFS
*/
struct mfs_args {
char *fspec; /* name to export for statfs */
struct export_args export; /* if exported MFSes are supported */
caddr_t base; /* base of file system in memory */
u_long size; /* size of file system */
};
#endif /* MFS */
#ifdef KERNEL
struct buf;
struct inode;
struct nameidata;
@ -51,6 +72,7 @@ struct ufsmount {
struct mount *um_mountp; /* filesystem vfs structure */
dev_t um_dev; /* device mounted */
struct vnode *um_devvp; /* block device mounted vnode */
union { /* pointer to superblock */
struct lfs *lfs; /* LFS */
struct fs *fs; /* FFS */
@ -60,6 +82,7 @@ struct ufsmount {
#define um_lfs ufsmount_u.lfs
#define um_e2fs ufsmount_u.e2fs
#define um_e2fsb ufsmount_u.e2fs->s_es
struct vnode *um_quotas[MAXQUOTAS]; /* pointer to quota files */
struct ucred *um_cred[MAXQUOTAS]; /* quota file access cred */
u_long um_nindir; /* indirect ptrs per block */
@ -69,7 +92,9 @@ struct ufsmount {
time_t um_itime[MAXQUOTAS]; /* inode quota time limit */
char um_qflags[MAXQUOTAS]; /* quota specific flags */
struct netexport um_export; /* export information */
int64_t um_savedmaxfilesize; /* XXX - limit maxfilesize */
};
/*
* Flags describing the state of quotas.
*/
@ -83,8 +108,9 @@ struct ufsmount {
* Macros to access file system parameters in the ufsmount structure.
* Used by ufs_bmap.
*/
#define blkptrtodb(ump, b) ((b) << (ump)->um_bptrtodb)
#define is_sequential(ump, a, b) ((b) == (a) + ump->um_seqinc)
#define MNINDIR(ump) ((ump)->um_nindir)
#define MNINDIR(ump) ((ump)->um_nindir)
#define blkptrtodb(ump, b) ((b) << (ump)->um_bptrtodb)
#define is_sequential(ump, a, b) ((b) == (a) + ump->um_seqinc)
#endif /* KERNEL */
#endif

View File

@ -221,10 +221,10 @@ ext2_mount(mp, path, data, ndp, p)
flags = WRITECLOSE;
if (mp->mnt_flag & MNT_FORCE)
flags |= FORCECLOSE;
if (vfs_busy(mp))
if (vfs_busy(mp, LK_NOWAIT, 0, p))
return (EBUSY);
error = ext2_flushfiles(mp, flags, p);
vfs_unbusy(mp);
vfs_unbusy(mp, p);
}
if (!error && (mp->mnt_flag & MNT_RELOAD))
error = ext2_reload(mp, ndp->ni_cnd.cn_cred, p);
@ -515,7 +515,7 @@ ext2_reload(mountp, cred, p)
/*
* Step 5: invalidate all cached file data.
*/
if (vget(vp, 1))
if (vget(vp, LK_EXCLUSIVE, p))
goto loop;
if (vinvalbuf(vp, 0, cred, p, 0, 0))
panic("ext2_reload: dirty2");
@ -727,17 +727,12 @@ ext2_flushfiles(mp, flags, p)
int flags;
struct proc *p;
{
#if !defined(__FreeBSD__)
extern int doforce;
#endif
register struct ufsmount *ump;
int error;
#if QUOTA
int i;
#endif
if (!doforce)
flags &= ~FORCECLOSE;
ump = VFSTOUFS(mp);
#if QUOTA
if (mp->mnt_flag & MNT_QUOTA) {
@ -872,7 +867,7 @@ ext2_sync(mp, waitfor, cred, p)
(IN_ACCESS | IN_CHANGE | IN_MODIFIED | IN_UPDATE)) == 0 &&
vp->v_dirtyblkhd.lh_first == NULL)
continue;
if (vget(vp, 1))
if (vget(vp, LK_EXCLUSIVE, p))
goto loop;
if (error = VOP_FSYNC(vp, cred, waitfor, p))
allerror = error;

View File

@ -152,6 +152,6 @@ extern u_char *fragtbl[];
* I think I'll try a VOP_LOCK/VOP_UNLOCK on the device vnode
*/
#define DEVVP(inode) (VFSTOUFS(ITOV(inode)->v_mount)->um_devvp)
#define lock_super(devvp) VOP_LOCK(devvp)
#define unlock_super(devvp) VOP_UNLOCK(devvp)
#define lock_super(devvp) vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY, curproc)
#define unlock_super(devvp) VOP_UNLOCK(devvp, 0, curproc)

View File

@ -35,42 +35,33 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)inode.h 8.4 (Berkeley) 1/21/94
* @(#)inode.h 8.9 (Berkeley) 5/14/95
* $FreeBSD$
*/
#ifndef _UFS_UFS_INODE_H_
#define _UFS_UFS_INODE_H_
#include <ufs/ufs/dir.h>
#include <ufs/ufs/dinode.h>
/*
* Theoretically, directories can 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
/*
* The inode is used to describe each active (or recently active)
* file in the UFS filesystem. It is composed of two types of
* information. The first part is the information that is needed
* only while the file is active (such as the identity of the file
* and linkage to speed its lookup). The second part is the
* permanent meta-data associated with the file which is read
* in from the permanent dinode from long term storage when the
* file becomes active, and is put back when the file is no longer
* being used.
* The inode is used to describe each active (or recently active) file in the
* UFS filesystem. It is composed of two types of information. The first part
* is the information that is needed only while the file is active (such as
* the identity of the file and linkage to speed its lookup). The second part
* is the permanent meta-data associated with the file which is read in
* from the permanent dinode from long term storage when the file becomes
* active, and is put back when the file is no longer being used.
*/
struct inode {
struct inode *i_next; /* Hash chain forward. */
struct inode **i_prev; /* Hash chain back. */
struct vnode *i_vnode; /* Vnode associated with this inode. */
struct vnode *i_devvp; /* Vnode for block I/O. */
u_long i_flag; /* I* flags. */
dev_t i_dev; /* Device associated with the inode. */
ino_t i_number; /* The identity of the inode. */
LIST_ENTRY(inode) i_hash;/* Hash chain. */
struct vnode *i_vnode;/* Vnode associated with this inode. */
struct vnode *i_devvp;/* Vnode for block I/O. */
u_int32_t i_flag; /* flags, see below */
dev_t i_dev; /* Device associated with the inode. */
ino_t i_number; /* The identity of the inode. */
union { /* Associated filesystem. */
struct fs *fs; /* FFS */
struct lfs *lfs; /* LFS */
@ -79,22 +70,21 @@ struct inode {
#define i_fs inode_u.fs
#define i_lfs inode_u.lfs
#define i_e2fs inode_u.e2fs
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for lease. */
struct lockf *i_lockf; /* Head of byte-level lock list. */
pid_t i_lockholder; /* DEBUG: holder of inode lock. */
pid_t i_lockwaiter; /* DEBUG: latest blocked for inode lock. */
struct dquot *i_dquot[MAXQUOTAS]; /* Dquot structures. */
u_quad_t i_modrev; /* Revision level for NFS lease. */
struct lockf *i_lockf;/* Head of byte-level lock list. */
struct lock i_lock; /* Inode lock. */
/*
* Side effects; used during directory lookup.
*/
long i_count; /* Size of free slot in directory. */
doff_t i_endoff; /* End of useful stuff in directory. */
doff_t i_diroff; /* Offset in dir, where we found last entry. */
doff_t i_offset; /* Offset of free space in directory. */
ino_t i_ino; /* Inode number of found directory. */
u_long i_reclen; /* Size of found directory entry. */
int i_lockcount; /* Process lock count (recursion) */
long i_spare[10]; /* Spares to round up to 128 bytes. */
int32_t i_count; /* Size of free slot in directory. */
doff_t i_endoff; /* End of useful stuff in directory. */
doff_t i_diroff; /* Offset in dir, where we found last entry. */
doff_t i_offset; /* Offset of free space in directory. */
ino_t i_ino; /* Inode number of found directory. */
u_int32_t i_reclen; /* Size of found directory entry. */
int i_lockcount; /* Process lock count (recursion) */
int i_spare[10]; /* XXX spare storage (for ext2fs) */
/*
* The on-disk dinode itself.
*/
@ -102,8 +92,10 @@ struct inode {
};
#define i_atime i_din.di_atime
#define i_atimensec i_din.di_atimensec
#define i_blocks i_din.di_blocks
#define i_ctime i_din.di_ctime
#define i_ctimensec i_din.di_ctimensec
#define i_db i_din.di_db
#define i_flags i_din.di_flags
#define i_gen i_din.di_gen
@ -111,6 +103,7 @@ struct inode {
#define i_ib i_din.di_ib
#define i_mode i_din.di_mode
#define i_mtime i_din.di_mtime
#define i_mtimensec i_din.di_mtimensec
#define i_nlink i_din.di_nlink
#define i_rdev i_din.di_rdev
#define i_shortlink i_din.di_shortlink
@ -120,15 +113,12 @@ struct inode {
/* These flags are kept in i_flag. */
#define IN_ACCESS 0x0001 /* Access time update request. */
#define IN_CHANGE 0x0002 /* Inode change time update request. */
#define IN_EXLOCK 0x0004 /* File has exclusive lock. */
#define IN_LOCKED 0x0008 /* Inode lock. */
#define IN_LWAIT 0x0010 /* Process waiting on file lock. */
#define IN_MODIFIED 0x0020 /* Inode has been modified. */
#define IN_RENAME 0x0040 /* Inode is being renamed. */
#define IN_SHLOCK 0x0080 /* File has shared lock. */
#define IN_UPDATE 0x0100 /* Modification time update request. */
#define IN_WANTED 0x0200 /* Inode is wanted by a process. */
#define IN_RECURSE 0x0400 /* Recursion expected */
#define IN_UPDATE 0x0004 /* Modification time update request. */
#define IN_MODIFIED 0x0008 /* Inode has been modified. */
#define IN_RENAME 0x0010 /* Inode is being renamed. */
#define IN_SHLOCK 0x0020 /* File has shared lock. */
#define IN_EXLOCK 0x0040 /* File has exclusive lock. */
#define IN_RECURSE 0x0080 /* Recursion expected */
#ifdef KERNEL
/*
@ -136,7 +126,7 @@ struct inode {
* ufs_getlbns and used by truncate and bmap code.
*/
struct indir {
daddr_t in_lbn; /* Logical block number. */
ufs_daddr_t in_lbn; /* Logical block number. */
int in_off; /* Offset in buffer. */
int in_exists; /* Flag if the block exists. */
};
@ -155,25 +145,25 @@ struct indir {
if ((ip)->i_flag & (IN_ACCESS | IN_CHANGE | IN_UPDATE)) { \
(ip)->i_flag |= IN_MODIFIED; \
if ((ip)->i_flag & IN_ACCESS) \
(ip)->i_atime.tv_sec \
(ip)->i_atime \
= ((t1) == &time ? tv_sec : (t1)->tv_sec); \
if ((ip)->i_flag & IN_UPDATE) { \
(ip)->i_mtime.tv_sec \
(ip)->i_mtime \
= ((t2) == &time ? tv_sec : (t2)->tv_sec); \
(ip)->i_modrev++; \
} \
if ((ip)->i_flag & IN_CHANGE) \
(ip)->i_ctime.tv_sec = tv_sec; \
(ip)->i_ctime = tv_sec; \
(ip)->i_flag &= ~(IN_ACCESS | IN_CHANGE | IN_UPDATE); \
} \
}
/* This overlays the fid structure (see mount.h). */
struct ufid {
u_short ufid_len; /* Length of structure. */
u_short ufid_pad; /* Force long alignment. */
ino_t ufid_ino; /* File number (ino). */
long ufid_gen; /* Generation number. */
u_int16_t ufid_len; /* Length of structure. */
u_int16_t ufid_pad; /* Force 32-bit alignment. */
ino_t ufid_ino; /* File number (ino). */
int32_t ufid_gen; /* Generation number. */
};
#endif /* KERNEL */

View File

@ -53,6 +53,7 @@
#include <sys/reboot.h>
#include <sys/kernel.h>
#include <sys/mount.h>
#include <sys/vnode.h>
#include <sys/sysctl.h>
#include <machine/bootinfo.h>
@ -88,31 +89,15 @@
static void configure __P((void *));
SYSINIT(configure, SI_SUB_CONFIGURE, SI_ORDER_FIRST, configure, NULL)
#ifdef MFS_ROOT
extern struct vfsops mfs_vfsops;
#endif
#ifdef FFS
extern struct vfsops ufs_vfsops;
#endif
#ifdef LFS
extern struct vfsops lfs_vfsops;
#endif
#ifdef NFS
extern int nfs_mountroot __P((void *));
#endif
#ifdef CD9660
extern int cd9660_mountroot __P((void *));
#endif
#ifdef MSDOSFS
extern int msdosfs_mountroot __P((void *));
#endif
static void configure_finish __P((void));
static void configure_start __P((void));
static int setdumpdev __P((dev_t dev));
static void setroot __P((void));
#ifdef CD9660
#include <isofs/cd9660/iso.h>
/* We need to try out all our potential CDROM drives, so we need a table. */
static struct {
char *name;
@ -138,7 +123,7 @@ find_cdrom_root(dummy)
rootdev = makedev(try_cdrom[k].major,j*8);
printf("trying rootdev=0x%lx (%s%d)\n",
rootdev, try_cdrom[k].name,j);
i = (*cd9660_mountroot)((void *)NULL);
i = (*cd9660_mountroot)();
if (!i) return i;
}
return EINVAL;
@ -176,6 +161,11 @@ configure(dummy)
enable_intr();
INTREN(IRQ_SLAVE);
#if NCRD > 0
/* Before isa_configure to avoid ISA drivers finding our cards */
pccard_configure();
#endif
#if NEISA > 0
eisa_configure();
#endif
@ -188,11 +178,6 @@ configure(dummy)
isa_configure();
#endif
#if NCRD > 0
/* After everyone else has a chance at grabbing resources */
pccard_configure();
#endif
if (setdumpdev(dumpdev) != 0)
dumpdev = NODEV;
@ -235,19 +220,26 @@ configure(dummy)
}
#ifdef CD9660
if ((boothowto & RB_CDROM) && !mountroot) {
if ((boothowto & RB_CDROM)) {
if (bootverbose)
printf("Considering CD-ROM root f/s.\n");
mountroot = find_cdrom_root;
mountrootfsname = "cd9660";
}
#endif
#ifdef NFS
if (!mountrootfsname && nfs_diskless_valid) {
if (bootverbose)
printf("Considering NFS root f/s.\n");
mountrootfsname = "nfs";
}
#endif /* NFS */
#ifdef MFS_ROOT
if (!mountroot) {
if (!mountrootfsname) {
if (bootverbose)
printf("Considering MFS root f/s.\n");
mountroot = vfs_mountroot; /* XXX goes away*/
mountrootvfsops = &mfs_vfsops;
mountrootfsname = "mfs";
/*
* Ignore the -a flag if this kernel isn't compiled
* with a generic root/swap configuration: if we skip
@ -260,21 +252,11 @@ configure(dummy)
setroot();
}
#endif
#ifdef NFS
if (!mountroot && nfs_diskless_valid) {
if (bootverbose)
printf("Considering NFS root f/s.\n");
mountroot = nfs_mountroot;
}
#endif /* NFS */
#ifdef FFS
if (!mountroot) {
if (!mountrootfsname) {
mountrootfsname = "ufs";
if (bootverbose)
printf("Considering FFS root f/s.\n");
mountroot = vfs_mountroot; /* XXX goes away*/
mountrootvfsops = &ufs_vfsops;
/*
* Ignore the -a flag if this kernel isn't compiled
* with a generic root/swap configuration: if we skip
@ -288,11 +270,10 @@ configure(dummy)
}
#endif
#ifdef LFS
if (!mountroot) {
if (!mountrootfsname) {
if (bootverbose)
printf("Considering LFS root f/s.\n");
mountroot = vfs_mountroot; /* XXX goes away*/
mountrootvfsops = &lfs_vfsops;
mountrootfsname = "lfs";
/*
* Ignore the -a flag if this kernel isn't compiled
* with a generic root/swap configuration: if we skip
@ -305,8 +286,7 @@ configure(dummy)
setroot();
}
#endif
if (!mountroot) {
if (!mountrootfsname) {
panic("Nobody wants to mount my root for me");
}
@ -417,4 +397,4 @@ sysctl_kern_dumpdev SYSCTL_HANDLER_ARGS
}
SYSCTL_PROC(_kern, KERN_DUMPDEV, dumpdev, CTLTYPE_OPAQUE|CTLFLAG_RW,
0, sizeof dumpdev, sysctl_kern_dumpdev, "T,dev_t", "");
0, sizeof dumpdev, sysctl_kern_dumpdev, "I", "");

View File

@ -34,7 +34,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_prot.h>
#include <vm/pmap.h>
#include <ddb/ddb.h>

View File

@ -61,13 +61,15 @@
#include <sys/vmmeter.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <sys/user.h>
#include <net/if.h>
#include <netinet/in.h>
#include <nfs/nfsv2.h>
#include <nfs/rpcv2.h>
#include <nfs/nfs.h>
#include <nfs/nfsdiskless.h>
extern int main __P((void));

View File

@ -82,7 +82,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_kern.h>
#include <vm/vm_object.h>
#include <vm/vm_page.h>

View File

@ -56,7 +56,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <sys/user.h>

View File

@ -68,7 +68,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_prot.h>
#include <vm/pmap.h>
#include <vm/vm_extern.h>

View File

@ -85,7 +85,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>

View File

@ -80,7 +80,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>

View File

@ -44,7 +44,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_map.h>
#include <vm/vm_extern.h>

View File

@ -61,7 +61,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/pmap.h>
#include <vm/vm_kern.h>
#include <vm/vm_map.h>

View File

@ -58,7 +58,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_prot.h>
#include <vm/lock.h>
#include <sys/lock.h>
#include <vm/vm_kern.h>
#include <vm/vm_page.h>
#include <vm/vm_map.h>

View File

@ -354,7 +354,7 @@ ibcs2_getdents(p, uap, retval)
buflen = max(DIRBLKSIZ, SCARG(uap, nbytes) + blockoff);
buflen = min(buflen, MAXBSIZE);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
again:
aiov.iov_base = buf;
aiov.iov_len = buflen;
@ -420,7 +420,7 @@ ibcs2_getdents(p, uap, retval)
eof:
*retval = SCARG(uap, nbytes) - resid;
out:
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, p);
free(buf, M_TEMP);
return (error);
}
@ -465,7 +465,7 @@ ibcs2_read(p, uap, retval)
buflen = max(DIRBLKSIZ, SCARG(uap, nbytes) + blockoff);
buflen = min(buflen, MAXBSIZE);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
again:
aiov.iov_base = buf;
aiov.iov_len = buflen;
@ -535,7 +535,7 @@ ibcs2_read(p, uap, retval)
eof:
*retval = SCARG(uap, nbytes) - resid;
out:
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, p);
free(buf, M_TEMP);
return (error);
}

View File

@ -214,7 +214,7 @@ coff_load_file(struct proc *p, char *name)
* Lose the lock on the vnode. It's no longer needed, and must not
* exist for the pagefault paging to work below.
*/
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, p);
if (error = vm_mmap(kernel_map,
(vm_offset_t *) &ptr,

View File

@ -45,6 +45,7 @@
*/
#define MACHINE "i386"
#define NCPUS 1
#define MID_MACHINE MID_I386
/*
@ -125,4 +126,63 @@
#define i386_btop(x) ((unsigned)(x) >> PAGE_SHIFT)
#define i386_ptob(x) ((unsigned)(x) << PAGE_SHIFT)
#ifndef _SIMPLELOCK_H_
#define _SIMPLELOCK_H_
/*
* A simple spin lock.
*
* This structure only sets one bit of data, but is sized based on the
* minimum word size that can be operated on by the hardware test-and-set
* instruction. It is only needed for multiprocessors, as uniprocessors
* will always run to completion or a sleep. It is an error to hold one
* of these locks while a process is sleeping.
*/
struct simplelock {
int lock_data;
};
#if !defined(SIMPLELOCK_DEBUG) && NCPUS > 1
/*
* The simple-lock routines are the primitives out of which the lock
* package is built. The machine-dependent code must implement an
* atomic test_and_set operation that indivisibly sets the simple lock
* to non-zero and returns its old value. It also assumes that the
* setting of the lock to zero below is indivisible. Simple locks may
* only be used for exclusive locks.
*/
static __inline void
simple_lock_init(lkp)
struct simplelock *lkp;
{
lkp->lock_data = 0;
}
static __inline void
simple_lock(lkp)
__volatile struct simplelock *lkp;
{
while (test_and_set(&lkp->lock_data))
continue;
}
static __inline int
simple_lock_try(lkp)
__volatile struct simplelock *lkp;
{
return (!test_and_set(&lkp->lock_data))
}
static __inline void
simple_unlock(lkp)
__volatile struct simplelock *lkp;
{
lkp->lock_data = 0;
}
#endif /* NCPUS > 1 */
#endif /* !_SIMPLELOCK_H_ */
#endif /* !_MACHINE_PARAM_H_ */

View File

@ -67,4 +67,6 @@ typedef unsigned long long u_int64_t;
typedef int32_t register_t;
typedef int32_t ufs_daddr_t;
#endif /* !_MACHINE_TYPES_H_ */

View File

@ -277,7 +277,7 @@ static d_strategy_t fdstrategy;
static struct cdevsw fd_cdevsw;
static struct bdevsw fd_bdevsw =
{ Fdopen, fdclose, fdstrategy, fdioctl, /*2*/
nodump, nopsize, 0, "fd", &fd_cdevsw, -1 };
nodump, nopsize, D_DISK, "fd", &fd_cdevsw, -1 };
static struct isa_device *fdcdevs[NFDC];

View File

@ -236,7 +236,7 @@ static d_psize_t wdsize;
static struct cdevsw wd_cdevsw;
static struct bdevsw wd_bdevsw =
{ wdopen, wdclose, wdstrategy, wdioctl, /*0*/
wddump, wdsize, 0, "wd", &wd_cdevsw, -1 };
wddump, wdsize, D_DISK, "wd", &wd_cdevsw, -1 };
/*
* Probe for controller.

View File

@ -450,7 +450,7 @@ linux_getdents(struct proc *p, struct linux_getdents_args *args, int *retval)
buflen = max(DIRBLKSIZ, nbytes + blockoff);
buflen = min(buflen, MAXBSIZE);
buf = malloc(buflen, M_TEMP, M_WAITOK);
VOP_LOCK(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p);
again:
aiov.iov_base = buf;
aiov.iov_len = buflen;
@ -530,7 +530,7 @@ linux_getdents(struct proc *p, struct linux_getdents_args *args, int *retval)
eof:
*retval = nbytes - resid;
out:
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, p);
free(buf, M_TEMP);
return error;
}

View File

@ -237,7 +237,7 @@ linux_uselib(struct proc *p, struct linux_uselib_args *args, int *retval)
/*
* Lock no longer needed
*/
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, p);
locked = 0;
/*
@ -392,7 +392,7 @@ printf("mem=%08x = %08x %08x\n", vmaddr, ((int*)vmaddr)[0], ((int*)vmaddr)[1]);
* Unlock vnode if needed
*/
if (locked)
VOP_UNLOCK(vp);
VOP_UNLOCK(vp, p);
/*
* Release the kernel mapping.

Some files were not shown because too many files have changed in this diff Show More