--- //depot/vendor/freebsd/src/sbin/dumpfs/dumpfs.c 2003/01/23 16:35:42 +++ //depot/user/gordon/volume/src/sbin/dumpfs/dumpfs.c 2003/01/24 12:49:22 @@ -237,6 +237,9 @@ if (fsflags != 0) printf("unknown flags (%#x)", fsflags); putchar('\n'); + printf("fsmnt\t%s\n", afs.fs_fsmnt); + printf("volname\t%s\tswuid\t%qu\n", + afs.fs_volname, afs.fs_swuid); printf("\ncs[].cs_(nbfree,ndir,nifree,nffree):\n\t"); afs.fs_csp = calloc(1, afs.fs_cssize); if (bread(&disk, fsbtodb(&afs, afs.fs_csaddr), afs.fs_csp, afs.fs_cssize) == -1) --- //depot/vendor/freebsd/src/sbin/newfs/mkfs.c 2002/12/02 11:35:38 +++ //depot/user/gordon/volume/src/sbin/newfs/mkfs.c 2002/12/06 17:48:48 @@ -140,6 +140,8 @@ sblock.fs_flags = 0; if (Uflag) sblock.fs_flags |= FS_DOSOFTDEP; + if (Lflag) + strlcpy(sblock.fs_volname, volumelabel, MAXVOLLEN); /* * Validate the given file system size. * Verify that its last block can actually be accessed. --- //depot/vendor/freebsd/src/sbin/newfs/newfs.8 2002/08/26 18:40:52 +++ //depot/user/gordon/volume/src/sbin/newfs/newfs.8 2002/10/30 21:19:15 @@ -40,6 +40,7 @@ .Nd construct a new file system .Sh SYNOPSIS .Nm +.Op Fl L Ar volname .Op Fl NU .Op Fl O Ar filesystem-type .Op Fl S Ar sector-size @@ -82,6 +83,8 @@ .Bl -tag -width indent .It Fl T Ar disktype For backward compatibility. +.It Fl L Ar volname +Add a volume label to the new file system. .It Fl N Cause the file system parameters to be printed out without really creating the file system. --- //depot/vendor/freebsd/src/sbin/newfs/newfs.c 2002/11/30 10:35:39 +++ //depot/user/gordon/volume/src/sbin/newfs/newfs.c 2002/12/06 17:48:48 @@ -117,6 +117,7 @@ */ #define NFPI 4 +int Lflag; /* add a volume label */ int Nflag; /* run without writing file system */ int Oflag = 1; /* file system format (1 => UFS1, 2 => UFS2) */ int Rflag; /* regression test */ @@ -136,6 +137,7 @@ int avgfilesize = AVFILESIZ;/* expected average file size */ int avgfilesperdir = AFPDIR;/* expected number of files per directory */ int fso; /* filedescriptor to device */ +u_char *volumelabel = NULL; /* volume label for filesystem */ static char device[MAXPATHLEN]; static char *disktype; @@ -153,12 +155,25 @@ struct partition oldpartition; struct stat st; char *cp, *special; - int ch; + int ch, i; off_t mediasize; while ((ch = getopt(argc, argv, - "NO:RS:T:Ua:b:c:d:e:f:g:h:i:m:o:s:")) != -1) + "L:NO:RS:T:Ua:b:c:d:e:f:g:h:i:m:o:s:")) != -1) switch (ch) { + case 'L': + volumelabel = optarg; + i = -1; + while (isalnum(volumelabel[++i])); + if (volumelabel[i] != '\0') { + errx(1, "bad volume label. Valid characters are alphanumerics."); + } + if (strlen(volumelabel) >= MAXVOLLEN) { + errx(1, "bad volume label. Length is longer than %d.", + MAXVOLLEN); + } + Lflag = 1; + break; case 'N': Nflag = 1; break; @@ -390,6 +405,7 @@ getprogname(), " [device-type]"); fprintf(stderr, "where fsoptions are:\n"); + fprintf(stderr, "\t-L volume label to add to superblock\n"); fprintf(stderr, "\t-N do not create file system, just print out parameters\n"); fprintf(stderr, "\t-O file system format: 1 => UFS1, 2 => UFS2\n"); --- //depot/vendor/freebsd/src/sbin/newfs/newfs.h 2002/08/21 11:41:13 +++ //depot/user/gordon/volume/src/sbin/newfs/newfs.h 2002/10/30 09:39:20 @@ -49,6 +49,7 @@ /* * variables set up by front end. */ +extern int Lflag; /* add a volume label */ extern int Nflag; /* run mkfs without writing file system */ extern int Oflag; /* build UFS1 format file system */ extern int Rflag; /* regression test */ @@ -68,5 +69,6 @@ extern int avgfilesize; /* expected average file size */ extern int avgfilesperdir; /* expected number of files per directory */ extern int fso; /* filedescriptor to device */ +extern u_char *volumelabel; /* volume label for filesystem */ void mkfs (struct partition *, char *); --- //depot/vendor/freebsd/src/sbin/tunefs/tunefs.8 2002/10/15 08:36:03 +++ //depot/user/gordon/volume/src/sbin/tunefs/tunefs.8 2002/10/30 21:19:15 @@ -41,6 +41,7 @@ .Sh SYNOPSIS .Nm .Op Fl A +.Op Fl L Ar volname .Op Fl a Cm enable | disable .Op Fl e Ar maxbpg .Op Fl f Ar avgfilesize @@ -71,6 +72,8 @@ this option will cause all backups to be modified as well as the primary super-block. This is potentially dangerous - use with caution. +.It Fl L Ar volname +Add/modify an optional file system volume label. .It Fl a Cm enable | disable Turn on/off the administrative ACL enable flag. .It Fl e Ar maxbpg --- //depot/vendor/freebsd/src/sbin/tunefs/tunefs.c 2003/01/20 13:35:42 +++ //depot/user/gordon/volume/src/sbin/tunefs/tunefs.c 2003/01/24 12:49:22 @@ -57,6 +57,7 @@ #include #include +#include #include #include #include @@ -82,28 +83,44 @@ char *special; const char *name; struct stat st; - int Aflag = 0, active = 0, aflag = 0; + int Aflag = 0, Lflag = 0, active = 0, aflag = 0; int eflag = 0, fflag = 0, lflag = 0, mflag = 0; int nflag = 0, oflag = 0, pflag = 0, sflag = 0; int evalue = 0, fvalue = 0; int mvalue = 0, ovalue = 0, svalue = 0; - char *avalue = NULL, *lvalue = NULL, *nvalue = NULL; + char *Lvalue = NULL, *avalue = NULL, *lvalue = NULL, *nvalue = NULL; struct fstab *fs; const char *chg[2]; char device[MAXPATHLEN]; struct ufs_args args; struct statfs stfs; - int found_arg, ch; + int found_arg, ch, i; if (argc < 3) usage(); found_arg = 0; /* at least one arg is required */ - while ((ch = getopt(argc, argv, "Aa:e:f:l:m:n:o:ps:")) != -1) + while ((ch = getopt(argc, argv, "AL:a:e:f:l:m:n:o:ps:")) != -1) switch (ch) { case 'A': found_arg = 1; Aflag++; break; + case 'L': + found_arg = 1; + name = "volume label"; + Lvalue = optarg; + i = -1; + while (isalnum(Lvalue[++i])); + if (Lvalue[i] != '\0') { + errx(10, "bad %s. Valid characters are alphanumerics.", + name); + } + if (strlen(Lvalue) >= MAXVOLLEN) { + errx(10, "bad %s. Length is longer than %d.", + name, MAXVOLLEN - 1); + } + Lflag = 1; + break; case 'a': found_arg = 1; name = "ACLs"; @@ -227,6 +244,10 @@ printfs(); exit(0); } + if (Lflag) { + name = "volume label"; + strlcpy(sblock.fs_volname, Lvalue, MAXVOLLEN); + } if (aflag) { name = "ACLs"; if (strcmp(avalue, "enable") == 0) { @@ -370,10 +391,11 @@ void usage(void) { - fprintf(stderr, "%s\n%s\n%s\n", -"usage: tunefs [-A] [-a enable | disable] [-e maxbpg] [-f avgfilesize]", -" [-l enable | disable] [-m minfree] [-n enable | disable]", -" [-o space | time] [-p] [-s avgfpdir] special | filesystem"); + fprintf(stderr, "%s\n%s\n%s\n%s\n", +"usage: tunefs [-A] [-L volname] [-a enable | disable] [-e maxbpg]", +" [-f avgfilesize] [-l enable | disable] [-m minfree]", +" [-n enable | disable] [-o space | time] [-p]", +" [-s avgfpdir] special | filesystem"); exit(2); } @@ -402,4 +424,6 @@ if (sblock.fs_minfree < MINFREE && sblock.fs_optim == FS_OPTTIME) warnx(OPTWARN, "space", "<", MINFREE); + warnx("volume label: (-L) %s", + sblock.fs_volname); } --- /dev/null Fri Jan 24 12:55:00 2003 +++ //depot/user/gordon/volume/src/sys/geom/geom_vol_ffs.c Mon Jan 13 12:31:08 2003 @@ -0,0 +1,146 @@ +/*- + * Copyright (c) 2002, 2003 Gordon Tetlow + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#ifndef _KERNEL +#include +#include +#include +#include +#include +#include +#else +#include +#include +#include +#include +#include +#include +#endif + +#include +#include + +#include +#include + +#define VOL_FFS_CLASS_NAME "VOL_FFS" + +static int superblocks[] = SBLOCKSEARCH; + +struct g_vol_ffs_softc { + char * vol; +}; + +static int +g_vol_ffs_start(struct bio *bp) +{ + return(0); +} + +static struct g_geom * +g_vol_ffs_taste(struct g_class *mp, struct g_provider *pp, int flags) +{ + struct g_geom *gp; + struct g_consumer *cp; + struct g_vol_ffs_softc *ms; + int error, sb, superblock; + struct fs *fs; + + g_trace(G_T_TOPOLOGY, "vol_taste(%s,%s)", mp->name, pp->name); + g_topology_assert(); + + if (flags == G_TF_NORMAL && + !strcmp(pp->geom->class->name, VOL_FFS_CLASS_NAME)) + return (NULL); + + gp = g_slice_new(mp, 1, pp, &cp, &ms, sizeof(*ms), g_vol_ffs_start); + if (gp == NULL) + return (NULL); + g_topology_unlock(); + /* + * Walk through the standard places that superblocks hide and look + * for UFS magic. If we find magic, then check that the size in the + * superblock corresponds to the size of the underlying provider. + * Finally, look for a volume label and create an appropriate /dev + * entry based on that. + */ + for (sb=0; (superblock = superblocks[sb]) != -1; sb++) { + fs = (struct fs *) g_read_data(cp, superblock, + SBLOCKSIZE, &error); + if (fs == NULL || error != 0) + continue; + /* Check for magic and make sure things are the right size */ + if (fs->fs_magic == FS_UFS1_MAGIC) { + if (fs->fs_old_size * fs->fs_fsize != + (int32_t) pp->mediasize) { + g_free(fs); + continue; + } + } else if (fs->fs_magic == FS_UFS2_MAGIC) { + if (fs->fs_size * fs->fs_fsize != + (int64_t) pp->mediasize) { + g_free(fs); + continue; + } + } else { + g_free(fs); + continue; + } + /* Check for volume label */ + if (fs->fs_volname[0] == '\0') { + g_free(fs); + continue; + } + g_topology_lock(); + /* Alright, we have a label and a volume name, reconfig. */ + g_slice_config(gp, 0, G_SLICE_CONFIG_SET, (off_t) 0, + pp->mediasize, pp->sectorsize, "vol/%s", + fs->fs_volname); + g_free(fs); + g_topology_unlock(); + break; + } + g_topology_lock(); + g_access_rel(cp, -1, 0, 0); + if (LIST_EMPTY(&gp->provider)) { + g_std_spoiled(cp); + return (NULL); + } + return (gp); +} + +static struct g_class g_vol_ffs_class = { + VOL_FFS_CLASS_NAME, + g_vol_ffs_taste, + NULL, + G_CLASS_INITIALIZER +}; + +DECLARE_GEOM_CLASS(g_vol_ffs_class, g_vol_ffs);