Thu Oct 15 06:25:34 2015 UTC ()
Enable mounting lfs64 volumes.


(dholland)
diff -r1.347 -r1.348 src/sys/ufs/lfs/lfs_vfsops.c

cvs diff -r1.347 -r1.348 src/sys/ufs/lfs/lfs_vfsops.c (expand / switch to unified diff)

--- src/sys/ufs/lfs/lfs_vfsops.c 2015/10/15 06:15:48 1.347
+++ src/sys/ufs/lfs/lfs_vfsops.c 2015/10/15 06:25:34 1.348
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: lfs_vfsops.c,v 1.347 2015/10/15 06:15:48 dholland Exp $ */ 1/* $NetBSD: lfs_vfsops.c,v 1.348 2015/10/15 06:25:34 dholland Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007, 2007 4 * Copyright (c) 1999, 2000, 2001, 2002, 2003, 2007, 2007
5 * The NetBSD Foundation, Inc. 5 * The NetBSD Foundation, Inc.
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * This code is derived from software contributed to The NetBSD Foundation 8 * This code is derived from software contributed to The NetBSD Foundation
9 * by Konrad E. Schroder <perseant@hhhh.org>. 9 * by Konrad E. Schroder <perseant@hhhh.org>.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -51,27 +51,27 @@ @@ -51,27 +51,27 @@
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 * 59 *
60 * @(#)lfs_vfsops.c 8.20 (Berkeley) 6/10/95 60 * @(#)lfs_vfsops.c 8.20 (Berkeley) 6/10/95
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.347 2015/10/15 06:15:48 dholland Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: lfs_vfsops.c,v 1.348 2015/10/15 06:25:34 dholland Exp $");
65 65
66#if defined(_KERNEL_OPT) 66#if defined(_KERNEL_OPT)
67#include "opt_lfs.h" 67#include "opt_lfs.h"
68#include "opt_quota.h" 68#include "opt_quota.h"
69#endif 69#endif
70 70
71#include <sys/param.h> 71#include <sys/param.h>
72#include <sys/systm.h> 72#include <sys/systm.h>
73#include <sys/namei.h> 73#include <sys/namei.h>
74#include <sys/proc.h> 74#include <sys/proc.h>
75#include <sys/kernel.h> 75#include <sys/kernel.h>
76#include <sys/vnode.h> 76#include <sys/vnode.h>
77#include <sys/mount.h> 77#include <sys/mount.h>
@@ -819,163 +819,228 @@ lfs_mount(struct mount *mp, const char * @@ -819,163 +819,228 @@ lfs_mount(struct mount *mp, const char *
819 } 819 }
820 820
821 error = set_statvfs_info(path, UIO_USERSPACE, args->fspec, 821 error = set_statvfs_info(path, UIO_USERSPACE, args->fspec,
822 UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l); 822 UIO_USERSPACE, mp->mnt_op->vfs_name, mp, l);
823 if (error == 0) 823 if (error == 0)
824 lfs_sb_setfsmnt(fs, mp->mnt_stat.f_mntonname); 824 lfs_sb_setfsmnt(fs, mp->mnt_stat.f_mntonname);
825 return error; 825 return error;
826 826
827fail: 827fail:
828 vrele(devvp); 828 vrele(devvp);
829 return (error); 829 return (error);
830} 830}
831 831
 832/*
 833 * Helper for mountfs. Note that the fs pointer may be a dummy one
 834 * pointing into a superblock buffer. (Which is gross; see below.)
 835 */
 836static int
 837lfs_checkmagic(struct lfs *fs)
 838{
 839 switch (fs->lfs_dlfs_u.u_32.dlfs_magic) {
 840 case LFS_MAGIC:
 841 fs->lfs_is64 = false;
 842 fs->lfs_dobyteswap = false;
 843 break;
 844 case LFS64_MAGIC:
 845 fs->lfs_is64 = true;
 846 fs->lfs_dobyteswap = false;
 847 break;
 848#ifdef LFS_EI
 849 case LFS_MAGIC_SWAPPED:
 850 fs->lfs_is64 = false;
 851 fs->lfs_dobyteswap = true;
 852 break;
 853 case LFS64_MAGIC_SWAPPED:
 854 fs->lfs_is64 = true;
 855 fs->lfs_dobyteswap = true;
 856 break;
 857#endif
 858 default:
 859 /* XXX needs translation */
 860 return EINVAL;
 861 }
 862 return 0;
 863}
832 864
833/* 865/*
834 * Common code for mount and mountroot 866 * Common code for mount and mountroot
835 * LFS specific 867 * LFS specific
836 */ 868 */
837int 869int
838lfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l) 870lfs_mountfs(struct vnode *devvp, struct mount *mp, struct lwp *l)
839{ 871{
840 struct dlfs *tdfs, *dfs, *adfs; 872 struct lfs *primarysb, *altsb, *thesb;
 873 struct buf *primarybuf, *altbuf;
841 struct lfs *fs; 874 struct lfs *fs;
842 struct ulfsmount *ump; 875 struct ulfsmount *ump;
843 struct vnode *vp; 876 struct vnode *vp;
844 struct buf *bp, *abp; 
845 dev_t dev; 877 dev_t dev;
846 int error, i, ronly, fsbsize; 878 int error, i, ronly, fsbsize;
847 kauth_cred_t cred; 879 kauth_cred_t cred;
848 CLEANERINFO *cip; 880 CLEANERINFO *cip;
849 SEGUSE *sup; 881 SEGUSE *sup;
850 daddr_t sb_addr; 882 daddr_t sb_addr;
851 883
852 cred = l ? l->l_cred : NOCRED; 884 cred = l ? l->l_cred : NOCRED;
853 885
854 /* The superblock is supposed to be 512 bytes. */ 886 /* The superblock is supposed to be 512 bytes. */
855 __CTASSERT(sizeof(struct dlfs) == DEV_BSIZE); 887 __CTASSERT(sizeof(struct dlfs) == DEV_BSIZE);
856 888
857 /* 889 /*
858 * Flush out any old buffers remaining from a previous use. 890 * Flush out any old buffers remaining from a previous use.
859 */ 891 */
860 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); 892 vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY);
861 error = vinvalbuf(devvp, V_SAVE, cred, l, 0, 0); 893 error = vinvalbuf(devvp, V_SAVE, cred, l, 0, 0);
862 VOP_UNLOCK(devvp); 894 VOP_UNLOCK(devvp);
863 if (error) 895 if (error)
864 return (error); 896 return (error);
865 897
866 ronly = (mp->mnt_flag & MNT_RDONLY) != 0; 898 ronly = (mp->mnt_flag & MNT_RDONLY) != 0;
867 899
868 /* Don't free random space on error. */ 900 /* Don't free random space on error. */
869 bp = NULL; 901 primarybuf = NULL;
870 abp = NULL; 902 altbuf = NULL;
871 ump = NULL; 903 ump = NULL;
872 904
873 sb_addr = LFS_LABELPAD / DEV_BSIZE; 905 sb_addr = LFS_LABELPAD / DEV_BSIZE;
874 while (1) { 906 while (1) {
875 /* Read in the superblock. */ 907 /*
876 error = bread(devvp, sb_addr, LFS_SBPAD, 0, &bp); 908 * Read in the superblock.
 909 *
 910 * Note that because LFS_SBPAD is substantially larger
 911 * (8K) than the actual on-disk superblock (512 bytes)
 912 * the buffer contains enough space to be used as a
 913 * whole struct lfs (in-memory superblock) - we do this
 914 * only so we can set and use the is64 and dobyteswap
 915 * members. XXX this is gross and the logic here should
 916 * be reworked.
 917 */
 918 error = bread(devvp, sb_addr, LFS_SBPAD, 0, &primarybuf);
877 if (error) 919 if (error)
878 goto out; 920 goto out;
879 dfs = (struct dlfs *)bp->b_data; 921 primarysb = (struct lfs *)primarybuf->b_data;
880 922
881 /* Check the basics. */ 923 /* Check the basics. */
882 if (dfs->dlfs_magic != LFS_MAGIC || dfs->dlfs_bsize > MAXBSIZE || 924 error = lfs_checkmagic(primarysb);
883 dfs->dlfs_version > LFS_VERSION || 925 if (error) {
884 dfs->dlfs_bsize < sizeof(struct dlfs)) { 926 DLOG((DLOG_MOUNT, "lfs_mountfs: primary superblock wrong magic\n"));
 927 goto out;
 928 }
 929 if (lfs_sb_getbsize(primarysb) > MAXBSIZE ||
 930 lfs_sb_getversion(primarysb) > LFS_VERSION ||
 931 lfs_sb_getbsize(primarysb) < sizeof(struct dlfs)) {
885 DLOG((DLOG_MOUNT, "lfs_mountfs: primary superblock sanity failed\n")); 932 DLOG((DLOG_MOUNT, "lfs_mountfs: primary superblock sanity failed\n"));
886 error = EINVAL; /* XXX needs translation */ 933 /* XXX needs translation */
 934 error = EINVAL;
887 goto out; 935 goto out;
888 } 936 }
889 if (dfs->dlfs_inodefmt > LFS_MAXINODEFMT) { 937 if (lfs_sb_getinodefmt(primarysb) > LFS_MAXINODEFMT) {
890 DLOG((DLOG_MOUNT, "lfs_mountfs: unknown inode format %d\n", 938 DLOG((DLOG_MOUNT, "lfs_mountfs: unknown inode format %d\n",
891 dfs->dlfs_inodefmt)); 939 lfs_sb_getinodefmt(primarysb)));
892 error = EINVAL; 940 error = EINVAL;
893 goto out; 941 goto out;
894 } 942 }
895 943
896 if (dfs->dlfs_version == 1) 944 if (lfs_sb_getversion(primarysb) == 1)
897 fsbsize = DEV_BSIZE; 945 fsbsize = DEV_BSIZE;
898 else { 946 else {
899 fsbsize = 1 << dfs->dlfs_ffshift; 947 fsbsize = 1 << lfs_sb_getffshift(primarysb);
900 /* 948 /*
901 * Could be, if the frag size is large enough, that we 949 * Could be, if the frag size is large enough, that we
902 * don't have the "real" primary superblock. If that's 950 * don't have the "real" primary superblock. If that's
903 * the case, get the real one, and try again. 951 * the case, get the real one, and try again.
904 */ 952 */
905 if (sb_addr != (dfs->dlfs_sboffs[0] << (dfs->dlfs_ffshift - DEV_BSHIFT))) { 953 if (sb_addr != (lfs_sb_getsboff(primarysb, 0) << (lfs_sb_getffshift(primarysb) - DEV_BSHIFT))) {
906 DLOG((DLOG_MOUNT, "lfs_mountfs: sb daddr" 954 DLOG((DLOG_MOUNT, "lfs_mountfs: sb daddr"
907 " 0x%llx is not right, trying 0x%llx\n", 955 " 0x%llx is not right, trying 0x%llx\n",
908 (long long)sb_addr, 956 (long long)sb_addr,
909 (long long)(dfs->dlfs_sboffs[0] << (dfs->dlfs_ffshift - DEV_BSHIFT)))); 957 (long long)(lfs_sb_getsboff(primarysb, 0) << (lfs_sb_getffshift(primarysb) - DEV_BSHIFT))));
910 sb_addr = dfs->dlfs_sboffs[0] << (dfs->dlfs_ffshift - DEV_BSHIFT); 958 sb_addr = lfs_sb_getsboff(primarysb, 0) << (lfs_sb_getffshift(primarysb) - DEV_BSHIFT);
911 brelse(bp, 0); 959 brelse(primarybuf, BC_INVAL);
912 continue; 960 continue;
913 } 961 }
914 } 962 }
915 break; 963 break;
916 } 964 }
917 965
918 /* 966 /*
919 * Check the second superblock to see which is newer; then mount 967 * Check the second superblock to see which is newer; then mount
920 * using the older of the two. This is necessary to ensure that 968 * using the older of the two. This is necessary to ensure that
921 * the filesystem is valid if it was not unmounted cleanly. 969 * the filesystem is valid if it was not unmounted cleanly.
922 */ 970 */
923 971
924 if (dfs->dlfs_sboffs[1] && 972 if (lfs_sb_getsboff(primarysb, 1) &&
925 dfs->dlfs_sboffs[1] - LFS_LABELPAD / fsbsize > LFS_SBPAD / fsbsize) 973 lfs_sb_getsboff(primarysb, 1) - LFS_LABELPAD / fsbsize > LFS_SBPAD / fsbsize)
926 { 974 {
927 error = bread(devvp, dfs->dlfs_sboffs[1] * (fsbsize / DEV_BSIZE), 975 error = bread(devvp, lfs_sb_getsboff(primarysb, 1) * (fsbsize / DEV_BSIZE),
928 LFS_SBPAD, 0, &abp); 976 LFS_SBPAD, 0, &altbuf);
929 if (error) 977 if (error)
930 goto out; 978 goto out;
931 adfs = (struct dlfs *)abp->b_data; 979 altsb = (struct lfs *)altbuf->b_data;
932 980
933 if (dfs->dlfs_version == 1) { 981 /*
934 /* 1s resolution comparison */ 982 * Note: this used to do the sanity check only if the
935 if (adfs->dlfs_tstamp < dfs->dlfs_tstamp) 983 * timestamp/serial comparison required use of altsb;
936 tdfs = adfs; 984 * this way is less tolerant, but if altsb is corrupted
937 else 985 * enough that the magic number, version, and blocksize
938 tdfs = dfs; 986 * are bogus, why would the timestamp or serial fields
939 } else { 987 * mean anything either? If this kind of thing happens,
940 /* monotonic infinite-resolution comparison */ 988 * you need to fsck anyway.
941 if (adfs->dlfs_serial < dfs->dlfs_serial) 989 */
942 tdfs = adfs; 990
943 else 991 error = lfs_checkmagic(altsb);
944 tdfs = dfs; 992 if (error)
945 } 993 goto out;
946 994
947 /* Check the basics. */ 995 /* Check the basics. */
948 if (tdfs->dlfs_magic != LFS_MAGIC || 996 if (lfs_sb_getbsize(altsb) > MAXBSIZE ||
949 tdfs->dlfs_bsize > MAXBSIZE || 997 lfs_sb_getversion(altsb) > LFS_VERSION ||
950 tdfs->dlfs_version > LFS_VERSION || 998 lfs_sb_getbsize(altsb) < sizeof(struct dlfs)) {
951 tdfs->dlfs_bsize < sizeof(struct dlfs)) { 
952 DLOG((DLOG_MOUNT, "lfs_mountfs: alt superblock" 999 DLOG((DLOG_MOUNT, "lfs_mountfs: alt superblock"
953 " sanity failed\n")); 1000 " sanity failed\n"));
954 error = EINVAL; /* XXX needs translation */ 1001 error = EINVAL; /* XXX needs translation */
955 goto out; 1002 goto out;
956 } 1003 }
 1004
 1005 if (lfs_sb_getversion(primarysb) == 1) {
 1006 /* 1s resolution comparison */
 1007 if (lfs_sb_gettstamp(altsb) < lfs_sb_gettstamp(primarysb))
 1008 thesb = altsb;
 1009 else
 1010 thesb = primarysb;
 1011 } else {
 1012 /* monotonic infinite-resolution comparison */
 1013 if (lfs_sb_getserial(altsb) < lfs_sb_getserial(primarysb))
 1014 thesb = altsb;
 1015 else
 1016 thesb = primarysb;
 1017 }
957 } else { 1018 } else {
958 DLOG((DLOG_MOUNT, "lfs_mountfs: invalid alt superblock" 1019 DLOG((DLOG_MOUNT, "lfs_mountfs: invalid alt superblock location"
959 " daddr=0x%x\n", dfs->dlfs_sboffs[1])); 1020 " daddr=0x%x\n", lfs_sb_getsboff(primarysb, 1)));
960 error = EINVAL; 1021 error = EINVAL;
961 goto out; 1022 goto out;
962 } 1023 }
963 1024
964 /* Allocate the mount structure, copy the superblock into it. */ 1025 /*
 1026 * Allocate the mount structure, copy the superblock into it.
 1027 * Note that the 32-bit and 64-bit superblocks are the same size.
 1028 */
965 fs = kmem_zalloc(sizeof(struct lfs), KM_SLEEP); 1029 fs = kmem_zalloc(sizeof(struct lfs), KM_SLEEP);
966 memcpy(&fs->lfs_dlfs_u.u_32, tdfs, sizeof(struct dlfs)); 1030 memcpy(&fs->lfs_dlfs_u.u_32, &thesb->lfs_dlfs_u.u_32,
967 fs->lfs_is64 = false; /* XXX notyet */ 1031 sizeof(struct dlfs));
968 fs->lfs_dobyteswap = false; /* XXX notyet */ 1032 fs->lfs_is64 = thesb->lfs_is64;
 1033 fs->lfs_dobyteswap = thesb->lfs_dobyteswap;
969 fs->lfs_hasolddirfmt = false; /* set for real below */ 1034 fs->lfs_hasolddirfmt = false; /* set for real below */
970 1035
971 /* Compatibility */ 1036 /* Compatibility */
972 if (lfs_sb_getversion(fs) < 2) { 1037 if (lfs_sb_getversion(fs) < 2) {
973 lfs_sb_setsumsize(fs, LFS_V1_SUMMARY_SIZE); 1038 lfs_sb_setsumsize(fs, LFS_V1_SUMMARY_SIZE);
974 lfs_sb_setibsize(fs, lfs_sb_getbsize(fs)); 1039 lfs_sb_setibsize(fs, lfs_sb_getbsize(fs));
975 lfs_sb_sets0addr(fs, lfs_sb_getsboff(fs, 0)); 1040 lfs_sb_sets0addr(fs, lfs_sb_getsboff(fs, 0));
976 lfs_sb_settstamp(fs, lfs_sb_getotstamp(fs)); 1041 lfs_sb_settstamp(fs, lfs_sb_getotstamp(fs));
977 lfs_sb_setfsbtodb(fs, 0); 1042 lfs_sb_setfsbtodb(fs, 0);
978 } 1043 }
979 if (lfs_sb_getresvseg(fs) == 0) 1044 if (lfs_sb_getresvseg(fs) == 0)
980 lfs_sb_setresvseg(fs, MIN(lfs_sb_getminfreeseg(fs) - 1, \ 1045 lfs_sb_setresvseg(fs, MIN(lfs_sb_getminfreeseg(fs) - 1, \
981 MAX(MIN_RESV_SEGS, lfs_sb_getminfreeseg(fs) / 2 + 1))); 1046 MAX(MIN_RESV_SEGS, lfs_sb_getminfreeseg(fs) / 2 + 1)));
@@ -995,35 +1060,30 @@ lfs_mountfs(struct vnode *devvp, struct  @@ -995,35 +1060,30 @@ lfs_mountfs(struct vnode *devvp, struct
995 goto out; 1060 goto out;
996 } 1061 }
997 1062
998 /* Before rolling forward, lock so vget will sleep for other procs */ 1063 /* Before rolling forward, lock so vget will sleep for other procs */
999 if (l != NULL) { 1064 if (l != NULL) {
1000 fs->lfs_flags = LFS_NOTYET; 1065 fs->lfs_flags = LFS_NOTYET;
1001 fs->lfs_rfpid = l->l_proc->p_pid; 1066 fs->lfs_rfpid = l->l_proc->p_pid;
1002 } 1067 }
1003 1068
1004 ump = kmem_zalloc(sizeof(*ump), KM_SLEEP); 1069 ump = kmem_zalloc(sizeof(*ump), KM_SLEEP);
1005 ump->um_lfs = fs; 1070 ump->um_lfs = fs;
1006 ump->um_fstype = ULFS1; 1071 ump->um_fstype = ULFS1;
1007 /* ump->um_cleaner_thread = NULL; */ 1072 /* ump->um_cleaner_thread = NULL; */
1008 if (sizeof(struct lfs) < LFS_SBPAD) { /* XXX why? */ 1073 brelse(primarybuf, BC_INVAL);
1009 brelse(bp, BC_INVAL); 1074 brelse(altbuf, BC_INVAL);
1010 brelse(abp, BC_INVAL); 1075 primarybuf = NULL;
1011 } else { 1076 altbuf = NULL;
1012 brelse(bp, 0); 
1013 brelse(abp, 0); 
1014 } 
1015 bp = NULL; 
1016 abp = NULL; 
1017 1077
1018 1078
1019 /* Set up the I/O information */ 1079 /* Set up the I/O information */
1020 fs->lfs_devbsize = DEV_BSIZE; 1080 fs->lfs_devbsize = DEV_BSIZE;
1021 fs->lfs_iocount = 0; 1081 fs->lfs_iocount = 0;
1022 fs->lfs_diropwait = 0; 1082 fs->lfs_diropwait = 0;
1023 fs->lfs_activesb = 0; 1083 fs->lfs_activesb = 0;
1024 lfs_sb_setuinodes(fs, 0); 1084 lfs_sb_setuinodes(fs, 0);
1025 fs->lfs_ravail = 0; 1085 fs->lfs_ravail = 0;
1026 fs->lfs_favail = 0; 1086 fs->lfs_favail = 0;
1027 fs->lfs_sbactive = 0; 1087 fs->lfs_sbactive = 0;
1028 1088
1029 /* Set up the ifile and lock aflags */ 1089 /* Set up the ifile and lock aflags */
@@ -1112,26 +1172,27 @@ lfs_mountfs(struct vnode *devvp, struct  @@ -1112,26 +1172,27 @@ lfs_mountfs(struct vnode *devvp, struct
1112 lfs_order_freelist(fs); 1172 lfs_order_freelist(fs);
1113 1173
1114 /* Set up segment usage flags for the autocleaner. */ 1174 /* Set up segment usage flags for the autocleaner. */
1115 fs->lfs_nactive = 0; 1175 fs->lfs_nactive = 0;
1116 fs->lfs_suflags = malloc(2 * sizeof(u_int32_t *), 1176 fs->lfs_suflags = malloc(2 * sizeof(u_int32_t *),
1117 M_SEGMENT, M_WAITOK); 1177 M_SEGMENT, M_WAITOK);
1118 fs->lfs_suflags[0] = malloc(lfs_sb_getnseg(fs) * sizeof(u_int32_t), 1178 fs->lfs_suflags[0] = malloc(lfs_sb_getnseg(fs) * sizeof(u_int32_t),
1119 M_SEGMENT, M_WAITOK); 1179 M_SEGMENT, M_WAITOK);
1120 fs->lfs_suflags[1] = malloc(lfs_sb_getnseg(fs) * sizeof(u_int32_t), 1180 fs->lfs_suflags[1] = malloc(lfs_sb_getnseg(fs) * sizeof(u_int32_t),
1121 M_SEGMENT, M_WAITOK); 1181 M_SEGMENT, M_WAITOK);
1122 memset(fs->lfs_suflags[1], 0, lfs_sb_getnseg(fs) * sizeof(u_int32_t)); 1182 memset(fs->lfs_suflags[1], 0, lfs_sb_getnseg(fs) * sizeof(u_int32_t));
1123 for (i = 0; i < lfs_sb_getnseg(fs); i++) { 1183 for (i = 0; i < lfs_sb_getnseg(fs); i++) {
1124 int changed; 1184 int changed;
 1185 struct buf *bp;
1125 1186
1126 LFS_SEGENTRY(sup, fs, i, bp); 1187 LFS_SEGENTRY(sup, fs, i, bp);
1127 changed = 0; 1188 changed = 0;
1128 if (!ronly) { 1189 if (!ronly) {
1129 if (sup->su_nbytes == 0 && 1190 if (sup->su_nbytes == 0 &&
1130 !(sup->su_flags & SEGUSE_EMPTY)) { 1191 !(sup->su_flags & SEGUSE_EMPTY)) {
1131 sup->su_flags |= SEGUSE_EMPTY; 1192 sup->su_flags |= SEGUSE_EMPTY;
1132 ++changed; 1193 ++changed;
1133 } else if (!(sup->su_nbytes == 0) && 1194 } else if (!(sup->su_nbytes == 0) &&
1134 (sup->su_flags & SEGUSE_EMPTY)) { 1195 (sup->su_flags & SEGUSE_EMPTY)) {
1135 sup->su_flags &= ~SEGUSE_EMPTY; 1196 sup->su_flags &= ~SEGUSE_EMPTY;
1136 ++changed; 1197 ++changed;
1137 } 1198 }
@@ -1208,63 +1269,71 @@ lfs_mountfs(struct vnode *devvp, struct  @@ -1208,63 +1269,71 @@ lfs_mountfs(struct vnode *devvp, struct
1208 lfs_sb_setpflags(fs, lfs_sb_getpflags(fs) & ~LFS_PF_CLEAN); 1269 lfs_sb_setpflags(fs, lfs_sb_getpflags(fs) & ~LFS_PF_CLEAN);
1209 lfs_writesuper(fs, lfs_sb_getsboff(fs, 0)); 1270 lfs_writesuper(fs, lfs_sb_getsboff(fs, 0));
1210 lfs_writesuper(fs, lfs_sb_getsboff(fs, 1)); 1271 lfs_writesuper(fs, lfs_sb_getsboff(fs, 1));
1211 } 1272 }
1212 1273
1213 /* Allow vget now that roll-forward is complete */ 1274 /* Allow vget now that roll-forward is complete */
1214 fs->lfs_flags &= ~(LFS_NOTYET); 1275 fs->lfs_flags &= ~(LFS_NOTYET);
1215 wakeup(&fs->lfs_flags); 1276 wakeup(&fs->lfs_flags);
1216 1277
1217 /* 1278 /*
1218 * Initialize the ifile cleaner info with information from 1279 * Initialize the ifile cleaner info with information from
1219 * the superblock. 1280 * the superblock.
1220 */ 1281 */
1221 LFS_CLEANERINFO(cip, fs, bp); 1282 {
1222 lfs_ci_setclean(fs, cip, lfs_sb_getnclean(fs)); 1283 struct buf *bp;
1223 lfs_ci_setdirty(fs, cip, lfs_sb_getnseg(fs) - lfs_sb_getnclean(fs)); 1284
1224 lfs_ci_setavail(fs, cip, lfs_sb_getavail(fs)); 1285 LFS_CLEANERINFO(cip, fs, bp);
1225 lfs_ci_setbfree(fs, cip, lfs_sb_getbfree(fs)); 1286 lfs_ci_setclean(fs, cip, lfs_sb_getnclean(fs));
1226 (void) LFS_BWRITE_LOG(bp); /* Ifile */ 1287 lfs_ci_setdirty(fs, cip, lfs_sb_getnseg(fs) - lfs_sb_getnclean(fs));
 1288 lfs_ci_setavail(fs, cip, lfs_sb_getavail(fs));
 1289 lfs_ci_setbfree(fs, cip, lfs_sb_getbfree(fs));
 1290 (void) LFS_BWRITE_LOG(bp); /* Ifile */
 1291 }
1227 1292
1228 /* 1293 /*
1229 * Mark the current segment as ACTIVE, since we're going to 1294 * Mark the current segment as ACTIVE, since we're going to
1230 * be writing to it. 1295 * be writing to it.
1231 */ 1296 */
1232 LFS_SEGENTRY(sup, fs, lfs_dtosn(fs, lfs_sb_getoffset(fs)), bp); 1297 {
1233 sup->su_flags |= SEGUSE_DIRTY | SEGUSE_ACTIVE; 1298 struct buf *bp;
1234 fs->lfs_nactive++; 1299
1235 LFS_WRITESEGENTRY(sup, fs, lfs_dtosn(fs, lfs_sb_getoffset(fs)), bp); /* Ifile */ 1300 LFS_SEGENTRY(sup, fs, lfs_dtosn(fs, lfs_sb_getoffset(fs)), bp);
 1301 sup->su_flags |= SEGUSE_DIRTY | SEGUSE_ACTIVE;
 1302 fs->lfs_nactive++;
 1303 LFS_WRITESEGENTRY(sup, fs, lfs_dtosn(fs, lfs_sb_getoffset(fs)), bp); /* Ifile */
 1304 }
1236 1305
1237 /* Now that roll-forward is done, unlock the Ifile */ 1306 /* Now that roll-forward is done, unlock the Ifile */
1238 vput(vp); 1307 vput(vp);
1239 1308
1240 /* Start the pagedaemon-anticipating daemon */ 1309 /* Start the pagedaemon-anticipating daemon */
1241 mutex_enter(&lfs_lock); 1310 mutex_enter(&lfs_lock);
1242 if (lfs_writer_daemon == 0 && lfs_writer_lid == 0 && 1311 if (lfs_writer_daemon == 0 && lfs_writer_lid == 0 &&
1243 kthread_create(PRI_BIO, 0, NULL, 1312 kthread_create(PRI_BIO, 0, NULL,
1244 lfs_writerd, NULL, NULL, "lfs_writer") != 0) 1313 lfs_writerd, NULL, NULL, "lfs_writer") != 0)
1245 panic("fork lfs_writer"); 1314 panic("fork lfs_writer");
1246 mutex_exit(&lfs_lock); 1315 mutex_exit(&lfs_lock);
1247 1316
1248 printf("WARNING: the log-structured file system is experimental\n" 1317 printf("WARNING: the log-structured file system is experimental\n"
1249 "WARNING: it may cause system crashes and/or corrupt data\n"); 1318 "WARNING: it may cause system crashes and/or corrupt data\n");
1250 1319
1251 return (0); 1320 return (0);
1252 1321
1253out: 1322out:
1254 if (bp) 1323 if (primarybuf)
1255 brelse(bp, 0); 1324 brelse(primarybuf, BC_INVAL);
1256 if (abp) 1325 if (altbuf)
1257 brelse(abp, 0); 1326 brelse(altbuf, BC_INVAL);
1258 if (ump) { 1327 if (ump) {
1259 kmem_free(ump->um_lfs, sizeof(struct lfs)); 1328 kmem_free(ump->um_lfs, sizeof(struct lfs));
1260 kmem_free(ump, sizeof(*ump)); 1329 kmem_free(ump, sizeof(*ump));
1261 mp->mnt_data = NULL; 1330 mp->mnt_data = NULL;
1262 } 1331 }
1263 1332
1264 return (error); 1333 return (error);
1265} 1334}
1266 1335
1267/* 1336/*
1268 * unmount system call 1337 * unmount system call
1269 */ 1338 */
1270int 1339int