Sync with CSRG.
This commit is contained in:
parent
d67f9f7960
commit
a63cb01c7d
|
@ -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_ */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 *));
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue