Sync with CSRG.

This commit is contained in:
mycroft 1994-12-14 13:03:35 +00:00
parent d67f9f7960
commit a63cb01c7d
22 changed files with 499 additions and 312 deletions

View File

@ -1,7 +1,7 @@
/* $NetBSD: dkbad.h,v 1.8 1994/10/29 08:20:15 cgd Exp $ */
/* $NetBSD: dkbad.h,v 1.9 1994/12/14 13:09:04 mycroft Exp $ */
/*-
* Copyright (c) 1982, 1986, 1993
* Copyright (c) 1982, 1986, 1993, 1994
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -32,12 +32,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)dkbad.h 8.1 (Berkeley) 6/2/93
* @(#)dkbad.h 8.2 (Berkeley) 7/10/94
*/
#ifndef _SYS_DKBAD_H_
#define _SYS_DKBAD_H_
/*
* Definitions needed to perform bad sector revectoring ala DEC STD 144.
*
@ -58,7 +55,7 @@
* replacement sectors.
*/
struct dkbad {
int32_t bt_csn; /* cartridge serial number */
int32_t bt_csn; /* cartridge serial number */
u_int16_t bt_mbz; /* unused; should be 0 */
u_int16_t bt_flag; /* -1 => alignment cartridge */
struct bt_bad {
@ -71,5 +68,3 @@ struct dkbad {
#define SSE 1
#define BSE 2
#define CONT 3
#endif /* !_SYS_DKBAD_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_alloc.c,v 1.4 1994/10/20 04:20:55 cgd Exp $ */
/* $NetBSD: ffs_alloc.c,v 1.5 1994/12/14 13:03:35 mycroft Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ffs_alloc.c 8.8 (Berkeley) 2/21/94
* @(#)ffs_alloc.c 8.11 (Berkeley) 10/27/94
*/
#include <sys/param.h>
@ -308,6 +308,8 @@ nospace:
#include <sys/sysctl.h>
int doasyncfree = 1;
struct ctldebug debug14 = { "doasyncfree", &doasyncfree };
int prtrealloc = 0;
struct ctldebug debug15 = { "prtrealloc", &prtrealloc };
#else
#define doasyncfree 1
#endif
@ -401,13 +403,22 @@ ffs_reallocblks(ap)
* block pointers in the inode and indirect blocks associated
* with the file.
*/
#ifdef DEBUG
if (prtrealloc)
printf("realloc: ino %d, lbns %d-%d\n\told:", ip->i_number,
start_lbn, end_lbn);
#endif
blkno = newblk;
for (bap = &sbap[soff], i = 0; i < len; i++, blkno += fs->fs_frag) {
if (i == ssize)
bap = ebap;
#ifdef DIAGNOSTIC
if (buflist->bs_children[i]->b_blkno != fsbtodb(fs, *bap))
if (dbtofsb(fs, buflist->bs_children[i]->b_blkno) != *bap)
panic("ffs_reallocblks: alloc mismatch");
#endif
#ifdef DEBUG
if (prtrealloc)
printf(" %d,", *bap);
#endif
*bap++ = blkno;
}
@ -443,11 +454,25 @@ ffs_reallocblks(ap)
/*
* Last, free the old blocks and assign the new blocks to the buffers.
*/
#ifdef DEBUG
if (prtrealloc)
printf("\n\tnew:");
#endif
for (blkno = newblk, i = 0; i < len; i++, blkno += fs->fs_frag) {
ffs_blkfree(ip, dbtofsb(fs, buflist->bs_children[i]->b_blkno),
fs->fs_bsize);
buflist->bs_children[i]->b_blkno = fsbtodb(fs, blkno);
#ifdef DEBUG
if (prtrealloc)
printf(" %d,", blkno);
#endif
}
#ifdef DEBUG
if (prtrealloc) {
prtrealloc--;
printf("\n");
}
#endif
return (0);
fail:
@ -998,9 +1023,10 @@ ffs_clusteralloc(ip, cg, bpref, len)
struct buf *bp;
int i, run, bno, bit, map;
u_char *mapp;
int32_t *lp;
fs = ip->i_fs;
if (fs->fs_cs(fs, cg).cs_nbfree < len)
if (fs->fs_maxcluster[cg] < len)
return (NULL);
if (bread(ip->i_devvp, fsbtodb(fs, cgtod(fs, cg)), (int)fs->fs_cgsize,
NOCRED, &bp))
@ -1012,11 +1038,25 @@ ffs_clusteralloc(ip, cg, bpref, len)
* Check to see if a cluster of the needed size (or bigger) is
* available in this cylinder group.
*/
lp = &cg_clustersum(cgp)[len];
for (i = len; i <= fs->fs_contigsumsize; i++)
if (cg_clustersum(cgp)[i] > 0)
if (*lp++ > 0)
break;
if (i > fs->fs_contigsumsize)
if (i > fs->fs_contigsumsize) {
/*
* This is the first time looking for a cluster in this
* cylinder group. Update the cluster summary information
* to reflect the true maximum sized cluster so that
* future cluster allocation requests can avoid reading
* the cylinder group map only to find no clusters.
*/
lp = &cg_clustersum(cgp)[len - 1];
for (i = len - 1; i > 0; i--)
if (*lp-- > 0)
break;
fs->fs_maxcluster[cg] = i;
goto fail;
}
/*
* Search the cluster map to find a big enough cluster.
* We take the first one that we find, even if it is larger
@ -1394,6 +1434,7 @@ ffs_clusteracct(fs, cgp, blkno, cnt)
int cnt;
{
int32_t *sump;
int32_t *lp;
u_char *freemapp, *mapp;
int i, start, end, forw, back, map, bit;
@ -1462,6 +1503,14 @@ ffs_clusteracct(fs, cgp, blkno, cnt)
sump[back] -= cnt;
if (forw > 0)
sump[forw] -= cnt;
/*
* Update cluster summary information.
*/
lp = &sump[fs->fs_contigsumsize];
for (i = fs->fs_contigsumsize; i > 0; i--)
if (*lp-- > 0)
break;
fs->fs_maxcluster[cgp->cg_cgx] = i;
}
/*

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_inode.c,v 1.6 1994/10/28 19:31:07 mycroft Exp $ */
/* $NetBSD: ffs_inode.c,v 1.7 1994/12/14 13:03:37 mycroft Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ffs_inode.c 8.5 (Berkeley) 12/30/93
* @(#)ffs_inode.c 8.8 (Berkeley) 10/19/94
*/
#include <sys/param.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vfsops.c,v 1.8 1994/10/28 20:20:18 mycroft Exp $ */
/* $NetBSD: ffs_vfsops.c,v 1.9 1994/12/14 13:03:38 mycroft Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1994
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ffs_vfsops.c 8.8 (Berkeley) 4/18/94
* @(#)ffs_vfsops.c 8.14 (Berkeley) 11/28/94
*/
#include <sys/param.h>
@ -153,6 +153,7 @@ ffs_mount(mp, path, data, ndp, p)
register struct fs *fs;
u_int size;
int error, flags;
mode_t accessmode;
if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
return (error);
@ -177,8 +178,23 @@ ffs_mount(mp, path, data, ndp, p)
error = ffs_reload(mp, ndp->ni_cnd.cn_cred, p);
if (error)
return (error);
if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR))
if (fs->fs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
/*
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
*/
if (p->p_ucred->cr_uid != 0) {
devvp = ump->um_devvp;
VOP_LOCK(devvp);
if (error = VOP_ACCESS(devvp, VREAD | VWRITE,
p->p_ucred, p)) {
VOP_UNLOCK(devvp);
return (error);
}
VOP_UNLOCK(devvp);
}
fs->fs_ronly = 0;
}
if (args.fspec == 0) {
/*
* Process export requests.
@ -203,6 +219,21 @@ ffs_mount(mp, path, data, ndp, p)
vrele(devvp);
return (ENXIO);
}
/*
* If mount by non-root, then verify that user has necessary
* permissions on the device.
*/
if (p->p_ucred->cr_uid != 0) {
accessmode = VREAD;
if ((mp->mnt_flag & MNT_RDONLY) == 0)
accessmode |= VWRITE;
VOP_LOCK(devvp);
if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) {
vput(devvp);
return (error);
}
VOP_UNLOCK(devvp);
}
if ((mp->mnt_flag & MNT_UPDATE) == 0)
error = ffs_mountfs(devvp, mp, p);
else {
@ -350,14 +381,18 @@ ffs_mountfs(devvp, mp, p)
register struct ufsmount *ump;
struct buf *bp;
register struct fs *fs;
dev_t dev = devvp->v_rdev;
dev_t dev;
struct partinfo dpart;
caddr_t base, space;
int blks;
int error, i, size;
int ronly;
int error, i, size, ronly;
int32_t *lp;
struct ucred *cred;
extern struct vnode *rootvp;
u_int64_t maxfilesize; /* XXX */
dev = devvp->v_rdev;
cred = p ? p->p_ucred : NOCRED;
/*
* Disallow multiple mounts of the same device.
* Disallow mounting of a device that is currently in use
@ -368,20 +403,20 @@ ffs_mountfs(devvp, mp, p)
return (error);
if (vcount(devvp) > 1 && devvp != rootvp)
return (EBUSY);
if (error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0))
if (error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0))
return (error);
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p))
return (error);
if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0)
if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
size = DEV_BSIZE;
else
size = dpart.disklab->d_secsize;
bp = NULL;
ump = NULL;
if (error = bread(devvp, (daddr_t)(SBOFF / size), SBSIZE, NOCRED, &bp))
if (error = bread(devvp, (daddr_t)(SBOFF / size), SBSIZE, cred, &bp))
goto out;
fs = (struct fs *)bp->b_data;
if (fs->fs_magic != FS_MAGIC || fs->fs_bsize > MAXBSIZE ||
@ -407,16 +442,17 @@ ffs_mountfs(devvp, mp, p)
fs->fs_ronly = ronly;
if (ronly == 0)
fs->fs_fmod = 1;
blks = howmany(fs->fs_cssize, fs->fs_fsize);
base = space = malloc((u_long)fs->fs_cssize, M_UFSMNT,
M_WAITOK);
size = fs->fs_cssize;
blks = howmany(size, fs->fs_fsize);
if (fs->fs_contigsumsize > 0)
size += fs->fs_ncg * sizeof(int32_t);
base = space = malloc((u_long)size, M_UFSMNT, M_WAITOK);
for (i = 0; i < blks; i += fs->fs_frag) {
size = fs->fs_bsize;
if (i + fs->fs_frag > blks)
size = (blks - i) * fs->fs_fsize;
error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
NOCRED, &bp);
if (error) {
if (error = bread(devvp, fsbtodb(fs, fs->fs_csaddr + i), size,
cred, &bp)) {
free(base, M_UFSMNT);
goto out;
}
@ -426,6 +462,11 @@ ffs_mountfs(devvp, mp, p)
brelse(bp);
bp = NULL;
}
if (fs->fs_contigsumsize > 0) {
fs->fs_maxcluster = lp = (int32_t *)space;
for (i = 0; i < fs->fs_ncg; i++)
*lp++ = fs->fs_contigsumsize;
}
mp->mnt_data = (qaddr_t)ump;
mp->mnt_stat.f_fsid.val[0] = (long)dev;
mp->mnt_stat.f_fsid.val[1] = makefstype(MOUNT_UFS);
@ -441,11 +482,15 @@ ffs_mountfs(devvp, mp, p)
ump->um_quotas[i] = NULLVP;
devvp->v_specflags |= SI_MOUNTEDON;
ffs_oldfscompat(fs);
ump->um_savedmaxfilesize = fs->fs_maxfilesize; /* XXX */
maxfilesize = (u_int64_t)0x80000000 * fs->fs_bsize - 1; /* XXX */
if (fs->fs_maxfilesize > maxfilesize) /* XXX */
fs->fs_maxfilesize = maxfilesize; /* XXX */
return (0);
out:
if (bp)
brelse(bp);
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
if (ump) {
free(ump->um_fs, M_UFSMNT);
free(ump, M_UFSMNT);
@ -479,15 +524,6 @@ ffs_oldfscompat(fs)
fs->fs_qbmask = ~fs->fs_bmask; /* XXX */
fs->fs_qfmask = ~fs->fs_fmask; /* XXX */
} /* XXX */
#ifndef KLUGE_BEGONE
{
u_int64_t maxfilesize;
maxfilesize = (u_int64_t)0x80000000 * fs->fs_bsize - 1;
if (fs->fs_maxfilesize > maxfilesize)
fs->fs_maxfilesize = maxfilesize;
}
#endif
return (0);
}
@ -502,7 +538,7 @@ ffs_unmount(mp, mntflags, p)
{
register struct ufsmount *ump;
register struct fs *fs;
int error, flags, ronly;
int error, flags;
flags = 0;
if (mntflags & MNT_FORCE) {
@ -514,9 +550,8 @@ ffs_unmount(mp, mntflags, p)
return (error);
ump = VFSTOUFS(mp);
fs = ump->um_fs;
ronly = !fs->fs_ronly;
ump->um_devvp->v_specflags &= ~SI_MOUNTEDON;
error = VOP_CLOSE(ump->um_devvp, ronly ? FREAD : FREAD|FWRITE,
error = VOP_CLOSE(ump->um_devvp, fs->fs_ronly ? FREAD : FREAD|FWRITE,
NOCRED, p);
vrele(ump->um_devvp);
free(fs->fs_csp[0], M_UFSMNT);
@ -836,40 +871,29 @@ ffs_sbupdate(mp, waitfor)
struct ufsmount *mp;
int waitfor;
{
register struct fs *fs = mp->um_fs;
register struct fs *dfs, *fs = mp->um_fs;
register struct buf *bp;
int blks;
caddr_t space;
int i, size, error = 0;
struct fs *cfs;
bp = getblk(mp->um_devvp, SBOFF >> (fs->fs_fshift - fs->fs_fsbtodb),
(int)fs->fs_sbsize, 0, 0);
bcopy((caddr_t)fs, bp->b_data, (u_int)fs->fs_sbsize);
cfs = (struct fs *)bp->b_data;
/* Restore compatibility to old file systems. XXX */
dfs = (struct fs *)bp->b_data; /* XXX */
if (fs->fs_postblformat == FS_42POSTBLFMT) /* XXX */
cfs->fs_nrpos = -1; /* XXX */
dfs->fs_nrpos = -1; /* XXX */
if (fs->fs_inodefmt < FS_44INODEFMT) { /* XXX */
int32_t *lp, tmp; /* XXX */
/* XXX */
lp = (int32_t *)&cfs->fs_qbmask; /* XXX */
lp = (int32_t *)&dfs->fs_qbmask; /* XXX */
tmp = lp[4]; /* XXX */
for (i = 4; i > 0; i--) /* XXX */
lp[i] = lp[i-1]; /* XXX */
lp[0] = tmp; /* XXX */
} /* XXX */
#ifndef KLUGE_BEGONE
{
u_int64_t sizepb = fs->fs_bsize; /* XXX */
/* XXX */
cfs->fs_maxfilesize = fs->fs_bsize * NDADDR - 1; /* XXX */
for (i = 0; i < NIADDR; i++) { /* XXX */
sizepb *= NINDIR(fs); /* XXX */
cfs->fs_maxfilesize += sizepb; /* XXX */
} /* XXX */
}
#endif
dfs->fs_maxfilesize = mp->um_savedmaxfilesize; /* XXX */
if (waitfor == MNT_WAIT)
error = bwrite(bp);
else

View File

@ -1,4 +1,4 @@
/* $NetBSD: ffs_vnops.c,v 1.4 1994/12/13 20:16:16 mycroft Exp $ */
/* $NetBSD: ffs_vnops.c,v 1.5 1994/12/14 13:03:41 mycroft Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ffs_vnops.c 8.7 (Berkeley) 2/3/94
* @(#)ffs_vnops.c 8.10 (Berkeley) 8/10/94
*/
#include <sys/param.h>
@ -68,6 +68,7 @@ struct vnodeopv_entry_desc ffs_vnodeop_entries[] = {
{ &vop_default_desc, vn_default_error },
{ &vop_lookup_desc, ufs_lookup }, /* lookup */
{ &vop_create_desc, ufs_create }, /* create */
{ &vop_whiteout_desc, ufs_whiteout }, /* whiteout */
{ &vop_mknod_desc, ufs_mknod }, /* mknod */
{ &vop_open_desc, ufs_open }, /* open */
{ &vop_close_desc, ufs_close }, /* close */

View File

@ -1,4 +1,4 @@
/* $NetBSD: fs.h,v 1.4 1994/12/13 19:10:43 mycroft Exp $ */
/* $NetBSD: fs.h,v 1.5 1994/12/14 13:03:42 mycroft Exp $ */
/*
* Copyright (c) 1982, 1986, 1993
@ -111,7 +111,7 @@
* is taken away to point to an array of cluster sizes that is
* computed as cylinder groups are inspected.
*/
#define MAXCSBUFS (128 / sizeof(void *))
#define MAXCSBUFS ((128 / sizeof(void *)) - 1)
/*
* A summary of contiguous blocks of various sizes is maintained
@ -215,7 +215,7 @@ struct fs {
int32_t fs_ipg; /* inodes per group */
int32_t fs_fpg; /* blocks per group * fs_frag */
/* this data must be re-computed after crashes */
struct csum fs_cstotal; /* cylinder summary information */
struct csum fs_cstotal; /* cylinder summary information */
/* these fields are cleared at mount time */
int8_t fs_fmod; /* super block modified flag */
int8_t fs_clean; /* file system is clean flag */
@ -224,7 +224,8 @@ struct fs {
u_char fs_fsmnt[MAXMNTLEN]; /* name mounted on */
/* these fields retain the current block allocation info */
int32_t fs_cgrotor; /* last cg searched */
struct csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */
struct csum *fs_csp[MAXCSBUFS];/* list of fs_cs info buffers */
int32_t *fs_maxcluster; /* max cluster in each cyl group */
int32_t fs_cpc; /* cyl per cycle in postbl */
int16_t fs_opostbl[16][8]; /* old rotation block list head */
int32_t fs_sparecon[50]; /* reserved for future constants */
@ -311,7 +312,7 @@ struct cg {
int16_t cg_ncyl; /* number of cyl's this cg */
int16_t cg_niblk; /* number of inode blocks this cg */
int32_t cg_ndblk; /* number of data blocks this cg */
struct csum cg_cs; /* cylinder summary information */
struct csum cg_cs; /* cylinder summary information */
int32_t cg_rotor; /* position of last used block */
int32_t cg_frotor; /* position of last used frag */
int32_t cg_irotor; /* position of last used inode */
@ -368,7 +369,7 @@ struct ocg {
int16_t cg_ncyl; /* number of cyl's this cg */
int16_t cg_niblk; /* number of inode blocks this cg */
int32_t cg_ndblk; /* number of data blocks this cg */
struct csum cg_cs; /* cylinder summary information */
struct csum cg_cs; /* cylinder summary information */
int32_t cg_rotor; /* position of last used block */
int32_t cg_frotor; /* position of last used frag */
int32_t cg_irotor; /* position of last used inode */

View File

@ -1,5 +1,3 @@
/* $NetBSD: lfs.h,v 1.4 1994/11/17 16:58:41 mycroft Exp $ */
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
@ -32,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)lfs.h 8.3 (Berkeley) 9/23/93
* @(#)lfs.h 8.5 (Berkeley) 7/8/94
*/
#define LFS_LABELPAD 8192 /* LFS label size */
@ -61,9 +59,10 @@ struct segusage {
u_int32_t su_lastmod; /* SEGUSE last modified timestamp */
u_int16_t su_nsums; /* number of summaries in segment */
u_int16_t su_ninos; /* number of inode blocks in seg */
#define SEGUSE_ACTIVE 0x1 /* segment is currently being written */
#define SEGUSE_DIRTY 0x2 /* segment has data in it */
#define SEGUSE_SUPERBLOCK 0x4 /* segment contains a superblock */
#define SEGUSE_ACTIVE 0x01 /* segment is currently being written */
#define SEGUSE_DIRTY 0x02 /* segment has data in it */
#define SEGUSE_SUPERBLOCK 0x04 /* segment contains a superblock */
u_int32_t su_flags;
};
@ -77,7 +76,7 @@ struct finfo {
u_int32_t fi_nblocks; /* number of blocks */
u_int32_t fi_version; /* version number */
u_int32_t fi_ino; /* inode number */
int32_t fi_blocks[1]; /* array of logical block numbers */
daddr_t fi_blocks[1]; /* array of logical block numbers */
};
/* On-disk and in-memory super block. */
@ -141,24 +140,26 @@ struct lfs {
#define LFS_MAXNUMSB 10 /* superblock disk offsets */
daddr_t lfs_sboffs[LFS_MAXNUMSB];
/* Checksum -- last valid disk field. */
u_int32_t lfs_cksum; /* checksum for superblock checking */
/* These fields are set at mount time and are meaningless on disk. */
struct segment *lfs_sp; /* current segment being written */
struct vnode *lfs_ivnode; /* vnode for the ifile */
u_long lfs_seglock; /* single-thread the segment writer */
pid_t lfs_lockpid; /* pid of lock holder */
u_long lfs_iocount; /* number of ios pending */
u_long lfs_writer; /* don't allow any dirops to start */
u_long lfs_dirops; /* count of active directory ops */
u_long lfs_doifile; /* Write ifile blocks on next write */
u_long lfs_nactive; /* Number of segments since last ckp */
u_int8_t lfs_fmod; /* super block modified flag */
u_int8_t lfs_clean; /* file system is clean flag */
u_int8_t lfs_ronly; /* mounted read-only flag */
u_char lfs_fsmnt[MNAMELEN]; /* name mounted on */
struct segment *lfs_sp; /* current segment being written */
struct vnode *lfs_ivnode; /* vnode for the ifile */
u_long lfs_seglock; /* single-thread the segment writer */
pid_t lfs_lockpid; /* pid of lock holder */
u_long lfs_iocount; /* number of ios pending */
u_long lfs_writer; /* don't allow any dirops to start */
u_long lfs_dirops; /* count of active directory ops */
u_long lfs_doifile; /* Write ifile blocks on next write */
u_long lfs_nactive; /* Number of segments since last ckp */
int8_t lfs_fmod; /* super block modified flag */
int8_t lfs_clean; /* file system is clean flag */
int8_t lfs_ronly; /* mounted read-only flag */
int8_t lfs_flags; /* currently unused flag */
u_char lfs_fsmnt[MNAMELEN]; /* name mounted on */
int32_t pad[40]; /* round to 512 bytes */
int32_t lfs_pad[40]; /* round to 512 bytes */
};
/*
@ -218,6 +219,7 @@ struct segsum {
u_int32_t ss_create; /* creation time stamp */
u_int16_t ss_nfinfo; /* number of file info structures */
u_int16_t ss_ninos; /* number of inodes in summary */
#define SS_DIROP 0x01 /* segment begins a dirop */
#define SS_CONT 0x02 /* more partials to finish this write*/
u_int16_t ss_flags; /* used for directory operations */
@ -284,9 +286,8 @@ struct segsum {
* the segment usage table, plus an ifile page.
*/
#define LFS_FITS(fs, db) \
((int32_t)((db + ((fs)->lfs_uinodes + INOPB((fs))) / \
INOPB((fs)) + fsbtodb(fs, 1) + \
LFS_SUMMARY_SIZE / DEV_BSIZE + \
((int32_t)((db + ((fs)->lfs_uinodes + INOPB((fs))) / \
INOPB((fs)) + fsbtodb(fs, 1) + LFS_SUMMARY_SIZE / DEV_BSIZE + \
(fs)->lfs_segtabsz)) < (fs)->lfs_avail)
/* Determine if a buffer belongs to the ifile */
@ -307,23 +308,24 @@ typedef struct block_info {
/* In-memory description of a segment about to be written. */
struct segment {
struct lfs *fs; /* file system pointer */
struct lfs *fs; /* file system pointer */
struct buf **bpp; /* pointer to buffer array */
struct buf **cbpp; /* pointer to next available bp */
struct buf **start_bpp; /* pointer to first bp in this set */
struct buf *ibp; /* buffer pointer to inode page */
struct finfo *fip; /* current fileinfo pointer */
struct vnode *vp; /* vnode being gathered */
struct buf *ibp; /* buffer pointer to inode page */
struct finfo *fip; /* current fileinfo pointer */
struct vnode *vp; /* vnode being gathered */
void *segsum; /* segment summary info */
u_int32_t ninodes; /* number of inodes in this segment */
u_int32_t seg_bytes_left; /* bytes left in segment */
u_int32_t sum_bytes_left; /* bytes left in summary block */
u_int32_t seg_number; /* number of this segment */
daddr_t *start_lbp; /* beginning lbn for this set */
#define SEGM_CKP 0x01 /* doing a checkpoint */
#define SEGM_CLEAN 0x02 /* cleaner call; don't sort */
#define SEGM_SYNC 0x04 /* wait for segment */
u_int8_t seg_flags; /* run-time flags for this segment */
u_int16_t seg_flags; /* run-time flags for this segment */
};
#define ISSPACE(F, BB, C) \
@ -340,18 +342,18 @@ struct segment {
#ifdef DOSTATS
/* Statistics Counters */
struct lfs_stats {
int blocktot;
int cleanblocks;
int flush_invoked;
int ncheckpoints;
int nsync_writes;
int nwrites;
int pcleanwrites;
int psegwrites;
int psyncwrites;
int segsused;
int wait_exceeded;
int write_exceeded;
u_int segsused;
u_int psegwrites;
u_int psyncwrites;
u_int pcleanwrites;
u_int blocktot;
u_int cleanblocks;
u_int ncheckpoints;
u_int nwrites;
u_int nsync_writes;
u_int wait_exceeded;
u_int write_exceeded;
u_int flush_invoked;
};
extern struct lfs_stats lfs_stats;
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_cksum.c,v 1.3 1994/09/20 06:45:17 cgd Exp $ */
/* $NetBSD: lfs_cksum.c,v 1.4 1994/12/14 13:03:46 mycroft Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)lfs_cksum.c 8.1 (Berkeley) 6/11/93
* @(#)lfs_cksum.c 8.2 (Berkeley) 10/9/94
*/
#include <sys/types.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_extern.h,v 1.2 1994/06/29 06:46:55 cgd Exp $ */
/* $NetBSD: lfs_extern.h,v 1.3 1994/12/14 13:03:47 mycroft Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)lfs_extern.h 8.2 (Berkeley) 4/16/94
* @(#)lfs_extern.h 8.3 (Berkeley) 6/16/94
*/
struct fid;

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_syscalls.c,v 1.6 1994/12/11 17:57:15 mycroft Exp $ */
/* $NetBSD: lfs_syscalls.c,v 1.7 1994/12/14 13:03:48 mycroft Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)lfs_syscalls.c 8.5 (Berkeley) 4/20/94
* @(#)lfs_syscalls.c 8.6 (Berkeley) 6/16/94
*/
#include <sys/param.h>

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_vfsops.c,v 1.2 1994/06/29 06:47:06 cgd Exp $ */
/* $NetBSD: lfs_vfsops.c,v 1.3 1994/12/14 13:03:49 mycroft Exp $ */
/*
* Copyright (c) 1989, 1991, 1993, 1994
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)lfs_vfsops.c 8.7 (Berkeley) 4/16/94
* @(#)lfs_vfsops.c 8.10 (Berkeley) 11/21/94
*/
#include <sys/param.h>
@ -102,6 +102,7 @@ lfs_mount(mp, path, data, ndp, p)
register struct lfs *fs; /* LFS */
u_int size;
int error;
mode_t accessmode;
if (error = copyin(data, (caddr_t)&args, sizeof (struct ufs_args)))
return (error);
@ -116,15 +117,22 @@ lfs_mount(mp, path, data, ndp, p)
*/
if (mp->mnt_flag & MNT_UPDATE) {
ump = VFSTOUFS(mp);
#ifdef NOTLFS /* LFS */
fs = ump->um_fs;
if (fs->fs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0)
fs->fs_ronly = 0;
#else
fs = ump->um_lfs;
if (fs->lfs_ronly && (mp->mnt_flag & MNT_RDONLY) == 0)
if (fs->lfs_ronly && (mp->mnt_flag & MNT_WANTRDWR)) {
/*
* If upgrade to read-write by non-root, then verify
* that user has necessary permissions on the device.
*/
if (p->p_ucred->cr_uid != 0) {
VOP_LOCK(ump->um_devvp);
if (error = VOP_ACCESS(ump->um_devvp,
VREAD | VWRITE, p->p_ucred, p)) {
VOP_UNLOCK(ump->um_devvp);
return (error);
}
VOP_UNLOCK(ump->um_devvp);
}
fs->lfs_ronly = 0;
#endif
}
if (args.fspec == 0) {
/*
* Process export requests.
@ -148,6 +156,21 @@ lfs_mount(mp, path, data, ndp, p)
vrele(devvp);
return (ENXIO);
}
/*
* If mount by non-root, then verify that user has necessary
* permissions on the device.
*/
if (p->p_ucred->cr_uid != 0) {
accessmode = VREAD;
if ((mp->mnt_flag & MNT_RDONLY) == 0)
accessmode |= VWRITE;
VOP_LOCK(devvp);
if (error = VOP_ACCESS(devvp, accessmode, p->p_ucred, p)) {
vput(devvp);
return (error);
}
VOP_UNLOCK(devvp);
}
if ((mp->mnt_flag & MNT_UPDATE) == 0)
error = lfs_mountfs(devvp, mp, p); /* LFS */
else {
@ -202,7 +225,9 @@ lfs_mountfs(devvp, mp, p)
struct partinfo dpart;
dev_t dev;
int error, i, ronly, size;
struct ucred *cred;
cred = p ? p->p_ucred : NOCRED;
/*
* Disallow multiple mounts of the same device.
* Disallow mounting of a device that is currently in use
@ -213,14 +238,14 @@ lfs_mountfs(devvp, mp, p)
return (error);
if (vcount(devvp) > 1 && devvp != rootvp)
return (EBUSY);
if (error = vinvalbuf(devvp, V_SAVE, p->p_ucred, p, 0, 0))
if (error = vinvalbuf(devvp, V_SAVE, cred, p, 0, 0))
return (error);
ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
if (error = VOP_OPEN(devvp, ronly ? FREAD : FREAD|FWRITE, FSCRED, p))
return (error);
if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, NOCRED, p) != 0)
if (VOP_IOCTL(devvp, DIOCGPART, (caddr_t)&dpart, FREAD, cred, p) != 0)
size = DEV_BSIZE;
else {
size = dpart.disklab->d_secsize;
@ -237,7 +262,7 @@ lfs_mountfs(devvp, mp, p)
ump = NULL;
/* Read in the superblock. */
if (error = bread(devvp, LFS_LABELPAD / size, LFS_SBPAD, NOCRED, &bp))
if (error = bread(devvp, LFS_LABELPAD / size, LFS_SBPAD, cred, &bp))
goto out;
fs = (struct lfs *)bp->b_data;
@ -304,7 +329,7 @@ lfs_mountfs(devvp, mp, p)
out:
if (bp)
brelse(bp);
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, NOCRED, p);
(void)VOP_CLOSE(devvp, ronly ? FREAD : FREAD|FWRITE, cred, p);
if (ump) {
free(ump->um_lfs, M_UFSMNT);
free(ump, M_UFSMNT);

View File

@ -1,4 +1,4 @@
/* $NetBSD: lfs_vnops.c,v 1.5 1994/12/13 20:51:56 mycroft Exp $ */
/* $NetBSD: lfs_vnops.c,v 1.6 1994/12/14 13:03:50 mycroft Exp $ */
/*
* Copyright (c) 1986, 1989, 1991, 1993
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)lfs_vnops.c 8.5 (Berkeley) 12/30/93
* @(#)lfs_vnops.c 8.8 (Berkeley) 8/10/94
*/
#include <sys/param.h>
@ -69,6 +69,7 @@ struct vnodeopv_entry_desc lfs_vnodeop_entries[] = {
{ &vop_default_desc, vn_default_error },
{ &vop_lookup_desc, ufs_lookup }, /* lookup */
{ &vop_create_desc, ufs_create }, /* create */
{ &vop_whiteout_desc, ufs_whiteout }, /* whiteout */
{ &vop_mknod_desc, ufs_mknod }, /* mknod */
{ &vop_open_desc, ufs_open }, /* open */
{ &vop_close_desc, lfs_close }, /* close */
@ -427,12 +428,9 @@ lfs_getattr(ap)
vap->va_gid = ip->i_gid;
vap->va_rdev = (dev_t)ip->i_rdev;
vap->va_size = ip->i_din.di_size;
vap->va_atime.ts_sec = ip->i_atime.ts_sec;
vap->va_atime.ts_nsec = ip->i_atime.ts_nsec;
vap->va_mtime.ts_sec = ip->i_mtime.ts_sec;
vap->va_mtime.ts_nsec = ip->i_mtime.ts_nsec;
vap->va_ctime.ts_sec = ip->i_ctime.ts_sec;
vap->va_ctime.ts_nsec = ip->i_ctime.ts_nsec;
vap->va_atime = ip->i_atime;
vap->va_mtime = ip->i_mtime;
vap->va_ctime = ip->i_ctime;
vap->va_flags = ip->i_flags;
vap->va_gen = ip->i_gen;
/* this doesn't belong here */

View File

@ -1,4 +1,4 @@
/* $NetBSD: mfs_extern.h,v 1.2 1994/06/29 06:47:10 cgd Exp $ */
/* $NetBSD: mfs_extern.h,v 1.3 1994/12/14 13:03:51 mycroft Exp $ */
/*-
* Copyright (c) 1991, 1993
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mfs_extern.h 8.1 (Berkeley) 6/11/93
* @(#)mfs_extern.h 8.2 (Berkeley) 6/16/94
*/
struct buf;

View File

@ -1,4 +1,4 @@
/* $NetBSD: mfs_vnops.c,v 1.4 1994/10/30 21:50:13 cgd Exp $ */
/* $NetBSD: mfs_vnops.c,v 1.5 1994/12/14 13:03:52 mycroft Exp $ */
/*
* Copyright (c) 1989, 1993
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)mfs_vnops.c 8.3 (Berkeley) 9/21/93
* @(#)mfs_vnops.c 8.5 (Berkeley) 7/28/94
*/
#include <sys/param.h>
@ -304,13 +304,7 @@ mfs_reclaim(ap)
} */ *ap;
{
register struct vnode *vp = ap->a_vp;
#if 0 /* XXX */
int error;
error = ufs_reclaim(vp);
if (error)
return (error);
#endif
FREE(vp->v_data, M_MFSNODE);
vp->v_data = NULL;
return (0);

View File

@ -1,5 +1,3 @@
/* $NetBSD: dinode.h,v 1.4 1994/10/20 04:21:16 cgd Exp $ */
/*
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
@ -37,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)dinode.h 8.3 (Berkeley) 1/21/94
* @(#)dinode.h 8.6 (Berkeley) 9/13/94
*/
/*
@ -48,6 +46,14 @@
*/
#define ROOTINO ((ino_t)2)
/*
* The Whiteout inode# is a dummy non-zero inode number which will
* never be allocated to a real file. It is used as a place holder
* in the directory entry which has been tagged as a DT_W entry.
* See the comments about ROOTINO above.
*/
#define WINO ((ino_t)1)
/*
* A dinode contains all the meta-data associated with a UFS file.
* This structure defines the on-disk format of a dinode.
@ -56,22 +62,17 @@
#define NDADDR 12 /* Direct addresses in inode. */
#define NIADDR 3 /* Indirect addresses in inode. */
struct ufs_timespec {
int32_t ts_sec; /* seconds */
int32_t ts_nsec; /* and nanoseconds */
};
struct dinode {
u_int16_t di_mode; /* 0: IFMT and permissions. */
u_int16_t di_mode; /* 0: IFMT, permissions; see below. */
int16_t di_nlink; /* 2: File link count. */
union {
u_int16_t oldids[2]; /* 4: Ffs: old user and group ids. */
ino_t inumber; /* 4: Lfs: inode number. */
ino_t inumber; /* 4: Lfs: inode number. */
} di_u;
u_int64_t di_size; /* 8: File byte count. */
struct ufs_timespec di_atime; /* 16: Last access time. */
struct ufs_timespec di_mtime; /* 24: Last modified time. */
struct ufs_timespec di_ctime; /* 32: Last inode change time. */
struct timespec di_atime; /* 16: Last access time. */
struct timespec di_mtime; /* 24: Last modified time. */
struct timespec di_ctime; /* 32: Last inode change time. */
daddr_t di_db[NDADDR]; /* 40: Direct disk blocks. */
daddr_t di_ib[NIADDR]; /* 88: Indirect disk blocks. */
u_int32_t di_flags; /* 100: Status flags (chflags). */
@ -96,7 +97,7 @@ struct dinode {
#define di_shortlink di_db
#define MAXSYMLINKLEN ((NDADDR + NIADDR) * sizeof(daddr_t))
/* File modes. */
/* File permissions. */
#define IEXEC 0000100 /* Executable. */
#define IWRITE 0000200 /* Writeable. */
#define IREAD 0000400 /* Readable. */
@ -113,3 +114,4 @@ struct dinode {
#define IFREG 0100000 /* Regular file. */
#define IFLNK 0120000 /* Symbolic link. */
#define IFSOCK 0140000 /* UNIX domain socket. */
#define IFWHT 0160000 /* Whiteout. */

View File

@ -1,5 +1,3 @@
/* $NetBSD: dir.h,v 1.3 1994/10/20 04:21:18 cgd Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
* The Regents of the University of California. All rights reserved.
@ -37,45 +35,46 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)dir.h 8.2 (Berkeley) 1/21/94
* @(#)dir.h 8.4 (Berkeley) 8/10/94
*/
#ifndef _DIR_H_
#define _DIR_H_
/*
* A directory consists of some number of blocks of DIRBLKSIZ bytes, where
* DIRBLKSIZ is chosen such that it can be transferred to disk in a single
* atomic operation (e.g. 512 bytes on most machines).
* A directory consists of some number of blocks of DIRBLKSIZ
* bytes, where DIRBLKSIZ is chosen such that it can be transferred
* to disk in a single atomic operation (e.g. 512 bytes on most machines).
*
* Each DIRBLKSIZ byte block contains some number of directory entry
* structures, which are of variable length. Each directory entry has a
* struct direct at the front of it, containing its inode number, the
* length of the entry, and the length of the name contained in the
* entry. These are followed by the name padded to a 4 byte boundary with
* null bytes. All names are guaranteed null terminated. The maximum
* length of a name in a directory is MAXNAMLEN.
* structures, which are of variable length. Each directory entry has
* a struct direct at the front of it, containing its inode number,
* the length of the entry, and the length of the name contained in
* the entry. These are followed by the name padded to a 4 byte boundary
* with null bytes. All names are guaranteed null terminated.
* The maximum length of a name in a directory is MAXNAMLEN.
*
* The macro DIRSIZ(fmt, dp) gives the amount of space required to represent
* a directory entry. Free space in a directory is represented by entries
* which have dp->d_reclen > DIRSIZ(fmt, dp). All DIRBLKSIZ bytes in a
* directory block are claimed by the directory entries. This usually
* results in the last entry in a directory having a large dp->d_reclen.
* When entries are deleted from a directory, the space is returned to the
* previous entry in the same directory block by increasing its
* dp->d_reclen. If the first entry of a directory block is free, then
* its dp->d_ino is set to 0. Entries other than the first in a directory
* do not normally have dp->d_ino set to 0.
* a directory entry. Free space in a directory is represented by
* entries which have dp->d_reclen > DIRSIZ(fmt, dp). All DIRBLKSIZ bytes
* in a directory block are claimed by the directory entries. This
* usually results in the last entry in a directory having a large
* dp->d_reclen. When entries are deleted from a directory, the
* space is returned to the previous entry in the same directory
* block by increasing its dp->d_reclen. If the first entry of
* a directory block is free, then its dp->d_ino is set to 0.
* Entries other than the first in a directory do not normally have
* dp->d_ino set to 0.
*/
#define DIRBLKSIZ DEV_BSIZE
#define MAXNAMLEN 255
struct direct {
u_int32_t d_ino; /* inode number of entry */
u_int16_t d_reclen; /* length of this record */
u_int8_t d_type; /* file type, see below */
u_int8_t d_namlen; /* length of string in d_name */
char d_name[MAXNAMLEN + 1]; /* name with length <= MAXNAMLEN */
u_int32_t d_ino; /* inode number of entry */
u_int16_t d_reclen; /* length of this record */
u_int8_t d_type; /* file type, see below */
u_int8_t d_namlen; /* length of string in d_name */
char d_name[MAXNAMLEN + 1];/* name with length <= MAXNAMLEN */
};
/*
@ -89,6 +88,7 @@ struct direct {
#define DT_REG 8
#define DT_LNK 10
#define DT_SOCK 12
#define DT_WHT 14
/*
* Convert between stat structure types and directory types.
@ -105,11 +105,11 @@ struct direct {
#if (BYTE_ORDER == LITTLE_ENDIAN)
#define DIRSIZ(oldfmt, dp) \
((oldfmt) ? \
((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_type+1 + 3) &~ 3)) : \
((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)))
((sizeof(struct direct) - (MAXNAMLEN+1)) + (((dp)->d_type+1 + 3) &~ 3)) : \
((sizeof(struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3)))
#else
#define DIRSIZ(oldfmt, dp) \
((sizeof (struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
((sizeof(struct direct) - (MAXNAMLEN+1)) + (((dp)->d_namlen+1 + 3) &~ 3))
#endif
#define OLDDIRFMT 1
#define NEWDIRFMT 0
@ -123,12 +123,12 @@ struct dirtemplate {
int16_t dot_reclen;
u_int8_t dot_type;
u_int8_t dot_namlen;
u_int8_t dot_name[4]; /* must be multiple of 4 */
char dot_name[4]; /* must be multiple of 4 */
u_int32_t dotdot_ino;
int16_t dotdot_reclen;
u_int8_t dotdot_type;
u_int8_t dotdot_namlen;
u_int8_t dotdot_name[4]; /* ditto */
char dotdot_name[4]; /* ditto */
};
/*
@ -138,10 +138,10 @@ struct odirtemplate {
u_int32_t dot_ino;
int16_t dot_reclen;
u_int16_t dot_namlen;
u_int8_t dot_name[4]; /* must be multiple of 4 */
char dot_name[4]; /* must be multiple of 4 */
u_int32_t dotdot_ino;
int16_t dotdot_reclen;
u_int16_t dotdot_namlen;
u_int8_t dotdot_name[4]; /* ditto */
char dotdot_name[4]; /* ditto */
};
#endif /* !_DIR_H_ */

View File

@ -1,5 +1,3 @@
/* $NetBSD: inode.h,v 1.4 1994/10/20 04:21:19 cgd Exp $ */
/*
* Copyright (c) 1982, 1989, 1993
* The Regents of the University of California. All rights reserved.
@ -37,78 +35,61 @@
* 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.5 (Berkeley) 7/8/94
*/
#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.
* practice this seems unlikely. So, we define the type doff_t as a 32-bit
* quantity to keep down the cost of doing lookup on a 32-bit machine.
*/
#define doff_t long
#define doff_t int32_t
/*
* 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 permannent 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. */
#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. */
u_long i_flag; /* I* flags. */
dev_t i_dev; /* Device associated with the inode. */
ino_t i_number; /* The identity of the 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_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 */
struct fs *fs; /* FFS */
struct lfs *lfs; /* LFS */
} inode_u;
#define i_fs inode_u.fs
#define i_lfs inode_u.lfs
/* Dquot structures. */
struct dquot *i_dquot[MAXQUOTAS];
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. */
pid_t i_lockholder; /* DEBUG: holder of inode lock. */
pid_t i_lockwaiter; /* DEBUG: latest blocked for 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. */
/* Spares to round up to 128 bytes on a 32-bit machine. */
int32_t i_spare[11];
struct dinode i_din; /* 128 bytes of on-disk dinode. */
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. */
/*
* Side effects; used during directory lookup.
*/
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. */
/*
* The on-disk dinode itself.
*/
struct dinode i_din; /* 128 bytes of the on-disk dinode. */
};
#define i_atime i_din.di_atime
@ -127,6 +108,18 @@ struct inode {
#define i_size i_din.di_size
#define i_uid i_din.di_uid
/* 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. */
#ifdef KERNEL
/*
* Structure used to pass around logical block paths generated by
@ -159,9 +152,9 @@ struct indir {
/* 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). */
int32_t 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

@ -1,4 +1,4 @@
/* $NetBSD: ufs_extern.h,v 1.3 1994/12/13 20:16:30 mycroft Exp $ */
/* $NetBSD: ufs_extern.h,v 1.4 1994/12/14 13:03:58 mycroft Exp $ */
/*-
* Copyright (c) 1991, 1993, 1994
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufs_extern.h 8.3 (Berkeley) 4/16/94
* @(#)ufs_extern.h 8.6 (Berkeley) 8/10/94
*/
struct buf;
@ -111,6 +111,7 @@ int ufs_start __P((struct mount *, int, struct proc *));
int ufs_strategy __P((struct vop_strategy_args *));
int ufs_symlink __P((struct vop_symlink_args *));
int ufs_unlock __P((struct vop_unlock_args *));
int ufs_whiteout __P((struct vop_whiteout_args *));
int ufs_vinit __P((struct mount *,
int (**)(), int (**)(), struct vnode **));
int ufsspec_close __P((struct vop_close_args *));

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_inode.c,v 1.4 1994/10/20 04:21:21 cgd Exp $ */
/* $NetBSD: ufs_inode.c,v 1.5 1994/12/14 13:03:59 mycroft Exp $ */
/*
* Copyright (c) 1991, 1993
@ -37,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufs_inode.c 8.4 (Berkeley) 1/21/94
* @(#)ufs_inode.c 8.7 (Berkeley) 7/22/94
*/
#include <sys/param.h>
@ -58,12 +58,11 @@ u_long nextgennumber; /* Next generation number to assign. */
int
ufs_init()
{
static int first = 1;
static int done;
if (!first)
if (done)
return (0);
first = 0;
done = 1;
ufs_ihashinit();
#ifdef QUOTA
dqinit();

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_lookup.c,v 1.2 1994/06/29 06:47:29 cgd Exp $ */
/* $NetBSD: ufs_lookup.c,v 1.3 1994/12/14 13:04:00 mycroft Exp $ */
/*
* Copyright (c) 1989, 1993
@ -37,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufs_lookup.c 8.6 (Berkeley) 4/1/94
* @(#)ufs_lookup.c 8.9 (Berkeley) 8/11/94
*/
#include <sys/param.h>
@ -331,19 +331,19 @@ searchloop:
* reclen in ndp->ni_ufs area, and release
* directory buffer.
*/
if (ep->d_type == DT_WHT) {
slotstatus = FOUND;
slotoffset = dp->i_offset;
slotsize = ep->d_reclen;
dp->i_reclen = slotsize;
enduseful = slotoffset + slotsize;
ap->a_cnp->cn_flags |= ISWHITEOUT;
numdirpasses--;
goto notfound;
}
dp->i_ino = ep->d_ino;
dp->i_reclen = ep->d_reclen;
#if 0 /* XXXX Upgrade on the fly! */
if (vdp->v_mount->mnt_maxsymlinklen > 0 &&
ep->d_type == DT_UNKNOWN &&
!(vdp->v_mount->mnt_flag & MNT_RDONLY) &&
!VFS_VGET(vdp->v_mount, dp->i_ino, &tdp)) {
ep->d_type = tdp->v_type;
vput(tdp);
bdwrite(bp);
} else
#endif
brelse(bp);
brelse(bp);
goto found;
}
}
@ -353,7 +353,7 @@ searchloop:
if (ep->d_ino)
enduseful = dp->i_offset;
}
/* notfound: */
notfound:
/*
* If we started in the middle of the directory and failed
* to find our target, we must check the beginning as well.
@ -371,7 +371,10 @@ searchloop:
* directory has not been removed, then can consider
* allowing file to be created.
*/
if ((nameiop == CREATE || nameiop == RENAME) &&
if ((nameiop == CREATE || nameiop == RENAME ||
(nameiop == DELETE &&
(ap->a_cnp->cn_flags & DOWHITEOUT) &&
(ap->a_cnp->cn_flags & ISWHITEOUT))) &&
(flags & ISLASTCN) && dp->i_nlink != 0) {
/*
* Access for write is interpreted as allowing
@ -392,6 +395,12 @@ searchloop:
dp->i_offset = roundup(dp->i_size, DIRBLKSIZ);
dp->i_count = 0;
enduseful = dp->i_offset;
} else if (nameiop == DELETE) {
dp->i_offset = slotoffset;
if ((dp->i_offset & (DIRBLKSIZ - 1)) == 0)
dp->i_count = 0;
else
dp->i_count = dp->i_offset - prevoff;
} else {
dp->i_offset = slotoffset;
dp->i_count = slotsize;
@ -647,15 +656,8 @@ ufs_direnter(ip, dvp, cnp)
struct vnode *dvp;
register struct componentname *cnp;
{
register struct direct *ep, *nep;
register struct inode *dp;
struct buf *bp;
struct direct newdir;
struct iovec aiov;
struct uio auio;
u_int dsize;
int error, loc, newentrysize, spacefree;
char *dirbuf;
#ifdef DIAGNOSTIC
if ((cnp->cn_flags & SAVENAME) == 0)
@ -675,7 +677,32 @@ ufs_direnter(ip, dvp, cnp)
newdir.d_type = tmp; }
# endif
}
newentrysize = DIRSIZ(FSFMT(dvp), &newdir);
return (ufs_direnter2(dvp, &newdir, cnp->cn_cred, cnp->cn_proc));
}
/*
* Common entry point for directory entry removal used by ufs_direnter
* and ufs_whiteout
*/
ufs_direnter2(dvp, dirp, cr, p)
struct vnode *dvp;
struct direct *dirp;
struct ucred *cr;
struct proc *p;
{
int newentrysize;
struct inode *dp;
struct buf *bp;
struct iovec aiov;
struct uio auio;
u_int dsize;
struct direct *ep, *nep;
int error, loc, spacefree;
char *dirbuf;
dp = VTOI(dvp);
newentrysize = DIRSIZ(FSFMT(dvp), dirp);
if (dp->i_count == 0) {
/*
* If dp->i_count is 0, then namei could find no
@ -684,22 +711,22 @@ ufs_direnter(ip, dvp, cnp)
* new entry into a fresh block.
*/
if (dp->i_offset & (DIRBLKSIZ - 1))
panic("ufs_direnter: newblk");
panic("ufs_direnter2: newblk");
auio.uio_offset = dp->i_offset;
newdir.d_reclen = DIRBLKSIZ;
dirp->d_reclen = DIRBLKSIZ;
auio.uio_resid = newentrysize;
aiov.iov_len = newentrysize;
aiov.iov_base = (caddr_t)&newdir;
aiov.iov_base = (caddr_t)dirp;
auio.uio_iov = &aiov;
auio.uio_iovcnt = 1;
auio.uio_rw = UIO_WRITE;
auio.uio_segflg = UIO_SYSSPACE;
auio.uio_procp = (struct proc *)0;
error = VOP_WRITE(dvp, &auio, IO_SYNC, cnp->cn_cred);
error = VOP_WRITE(dvp, &auio, IO_SYNC, cr);
if (DIRBLKSIZ >
VFSTOUFS(dvp->v_mount)->um_mountp->mnt_stat.f_bsize)
/* XXX should grow with balloc() */
panic("ufs_direnter: frag size");
panic("ufs_direnter2: frag size");
else if (!error) {
dp->i_size = roundup(dp->i_size, DIRBLKSIZ);
dp->i_flag |= IN_CHANGE;
@ -759,23 +786,24 @@ ufs_direnter(ip, dvp, cnp)
* Update the pointer fields in the previous entry (if any),
* copy in the new entry, and write out the block.
*/
if (ep->d_ino == 0) {
if (ep->d_ino == 0 ||
(ep->d_ino == WINO &&
bcmp(ep->d_name, dirp->d_name, dirp->d_namlen) == 0)) {
if (spacefree + dsize < newentrysize)
panic("ufs_direnter: compact1");
newdir.d_reclen = spacefree + dsize;
panic("ufs_direnter2: compact1");
dirp->d_reclen = spacefree + dsize;
} else {
if (spacefree < newentrysize)
panic("ufs_direnter: compact2");
newdir.d_reclen = spacefree;
panic("ufs_direnter2: compact2");
dirp->d_reclen = spacefree;
ep->d_reclen = dsize;
ep = (struct direct *)((char *)ep + dsize);
}
bcopy((caddr_t)&newdir, (caddr_t)ep, (u_int)newentrysize);
bcopy((caddr_t)dirp, (caddr_t)ep, (u_int)newentrysize);
error = VOP_BWRITE(bp);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
if (!error && dp->i_endoff && dp->i_endoff < dp->i_size)
error = VOP_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC,
cnp->cn_cred, cnp->cn_proc);
error = VOP_TRUNCATE(dvp, (off_t)dp->i_endoff, IO_SYNC, cr, p);
return (error);
}
@ -802,6 +830,21 @@ ufs_dirremove(dvp, cnp)
int error;
dp = VTOI(dvp);
if (cnp->cn_flags & DOWHITEOUT) {
/*
* Whiteout entry: set d_ino to WINO.
*/
if (error =
VOP_BLKATOFF(dvp, (off_t)dp->i_offset, (char **)&ep, &bp))
return (error);
ep->d_ino = WINO;
ep->d_type = DT_WHT;
error = VOP_BWRITE(bp);
dp->i_flag |= IN_CHANGE | IN_UPDATE;
return (error);
}
if (dp->i_count == 0) {
/*
* First entry in block: set d_ino to zero.
@ -885,7 +928,7 @@ ufs_dirempty(ip, parentino, cred)
if (dp->d_reclen == 0)
return (0);
/* skip empty entries */
if (dp->d_ino == 0)
if (dp->d_ino == 0 || dp->d_ino == WINO)
continue;
/* accept only "." and ".." */
# if (BYTE_ORDER == LITTLE_ENDIAN)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_readwrite.c,v 1.4 1994/10/20 04:21:23 cgd Exp $ */
/* $NetBSD: ufs_readwrite.c,v 1.5 1994/12/14 13:04:02 mycroft Exp $ */
/*-
* Copyright (c) 1993
@ -32,7 +32,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufs_readwrite.c 8.7 (Berkeley) 1/21/94
* @(#)ufs_readwrite.c 8.8 (Berkeley) 8/4/94
*/
#ifdef LFS_READWRITE
@ -116,7 +116,7 @@ READ(ap)
(void)lfs_check(vp, lbn);
error = cluster_read(vp, ip->i_size, lbn, size, NOCRED, &bp);
#else
if (lblktosize(fs, nextlbn) > ip->i_size)
if (lblktosize(fs, nextlbn) >= ip->i_size)
error = bread(vp, lbn, size, NOCRED, &bp);
else if (doclusterread)
error = cluster_read(vp,

View File

@ -1,4 +1,4 @@
/* $NetBSD: ufs_vnops.c,v 1.5 1994/10/30 21:50:17 cgd Exp $ */
/* $NetBSD: ufs_vnops.c,v 1.6 1994/12/14 13:04:03 mycroft Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@ -37,7 +37,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)ufs_vnops.c 8.10 (Berkeley) 4/1/94
* @(#)ufs_vnops.c 8.14 (Berkeley) 10/26/94
*/
#include <sys/param.h>
@ -302,12 +302,9 @@ ufs_getattr(ap)
vap->va_gid = ip->i_gid;
vap->va_rdev = (dev_t)ip->i_rdev;
vap->va_size = ip->i_din.di_size;
vap->va_atime.ts_sec = ip->i_atime.ts_sec;
vap->va_atime.ts_nsec = ip->i_atime.ts_nsec;
vap->va_mtime.ts_sec = ip->i_mtime.ts_sec;
vap->va_mtime.ts_nsec = ip->i_mtime.ts_nsec;
vap->va_ctime.ts_sec = ip->i_ctime.ts_sec;
vap->va_ctime.ts_nsec = ip->i_ctime.ts_nsec;
vap->va_atime = ip->i_atime;
vap->va_mtime = ip->i_mtime;
vap->va_ctime = ip->i_ctime;
vap->va_flags = ip->i_flags;
vap->va_gen = ip->i_gen;
/* this doesn't belong here */
@ -471,7 +468,7 @@ ufs_chown(vp, uid, gid, cred, p)
* the caller must be superuser or the call fails.
*/
if ((cred->cr_uid != ip->i_uid || uid != ip->i_uid ||
!groupmember((gid_t)gid, cred)) &&
(gid != ip->i_gid && !groupmember((gid_t)gid, cred))) &&
(error = suser(cred, &p->p_acflag)))
return (error);
ogid = ip->i_gid;
@ -712,6 +709,64 @@ out2:
return (error);
}
/*
* whiteout vnode call
*/
int
ufs_whiteout(ap)
struct vop_whiteout_args /* {
struct vnode *a_dvp;
struct componentname *a_cnp;
int a_flags;
} */ *ap;
{
struct vnode *dvp = ap->a_dvp;
struct componentname *cnp = ap->a_cnp;
struct direct newdir;
int error;
switch (ap->a_flags) {
case LOOKUP:
/* 4.4 format directories support whiteout operations */
if (dvp->v_mount->mnt_maxsymlinklen > 0)
return (0);
return (EOPNOTSUPP);
case CREATE:
/* create a new directory whiteout */
#ifdef DIAGNOSTIC
if ((cnp->cn_flags & SAVENAME) == 0)
panic("ufs_whiteout: missing name");
if (dvp->v_mount->mnt_maxsymlinklen <= 0)
panic("ufs_whiteout: old format filesystem");
#endif
newdir.d_ino = WINO;
newdir.d_namlen = cnp->cn_namelen;
bcopy(cnp->cn_nameptr, newdir.d_name, (unsigned)cnp->cn_namelen + 1);
newdir.d_type = DT_WHT;
error = ufs_direnter2(dvp, &newdir, cnp->cn_cred, cnp->cn_proc);
break;
case DELETE:
/* remove an existing directory whiteout */
#ifdef DIAGNOSTIC
if (dvp->v_mount->mnt_maxsymlinklen <= 0)
panic("ufs_whiteout: old format filesystem");
#endif
cnp->cn_flags &= ~DOWHITEOUT;
error = ufs_dirremove(dvp, cnp);
break;
}
if (cnp->cn_flags & HASBUF) {
FREE(cnp->cn_pnbuf, M_NAMEI);
cnp->cn_flags &= ~HASBUF;
}
return (error);
}
/*
* Rename system call.
* rename("foo", "bar");
@ -1169,6 +1224,8 @@ ufs_mkdir(ap)
ip->i_mode = dmode;
tvp->v_type = VDIR; /* Rest init'd in getnewvnode(). */
ip->i_nlink = 2;
if (cnp->cn_flags & ISWHITEOUT)
ip->i_flags |= UF_OPAQUE;
tv = time;
error = VOP_UPDATE(tvp, &tv, &tv, 1);
@ -1941,6 +1998,9 @@ ufs_makeinode(mode, dvp, vpp, cnp)
suser(cnp->cn_cred, NULL))
ip->i_mode &= ~ISGID;
if (cnp->cn_flags & ISWHITEOUT)
ip->i_flags |= UF_OPAQUE;
/*
* Make sure inode goes to disk before directory entry.
*/