| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ffs_vfsops.c,v 1.260 2010/07/21 17:52:13 hannken Exp $ */ | | 1 | /* $NetBSD: ffs_vfsops.c,v 1.261 2010/08/09 15:50:13 pooka Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2008, 2009 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Wasabi Systems, Inc, and by Andrew Doran. | | 8 | * by Wasabi Systems, Inc, and by Andrew Doran. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -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 | * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 | | 60 | * @(#)ffs_vfsops.c 8.31 (Berkeley) 5/20/95 |
61 | */ | | 61 | */ |
62 | | | 62 | |
63 | #include <sys/cdefs.h> | | 63 | #include <sys/cdefs.h> |
64 | __KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.260 2010/07/21 17:52:13 hannken Exp $"); | | 64 | __KERNEL_RCSID(0, "$NetBSD: ffs_vfsops.c,v 1.261 2010/08/09 15:50:13 pooka Exp $"); |
65 | | | 65 | |
66 | #if defined(_KERNEL_OPT) | | 66 | #if defined(_KERNEL_OPT) |
67 | #include "opt_ffs.h" | | 67 | #include "opt_ffs.h" |
68 | #include "opt_quota.h" | | 68 | #include "opt_quota.h" |
69 | #include "opt_wapbl.h" | | 69 | #include "opt_wapbl.h" |
70 | #endif | | 70 | #endif |
71 | | | 71 | |
72 | #include <sys/param.h> | | 72 | #include <sys/param.h> |
73 | #include <sys/systm.h> | | 73 | #include <sys/systm.h> |
74 | #include <sys/namei.h> | | 74 | #include <sys/namei.h> |
75 | #include <sys/proc.h> | | 75 | #include <sys/proc.h> |
76 | #include <sys/kernel.h> | | 76 | #include <sys/kernel.h> |
77 | #include <sys/vnode.h> | | 77 | #include <sys/vnode.h> |
| @@ -818,26 +818,27 @@ ffs_mountfs(struct vnode *devvp, struct | | | @@ -818,26 +818,27 @@ ffs_mountfs(struct vnode *devvp, struct |
818 | struct fs *fs; | | 818 | struct fs *fs; |
819 | dev_t dev; | | 819 | dev_t dev; |
820 | struct partinfo dpart; | | 820 | struct partinfo dpart; |
821 | void *space; | | 821 | void *space; |
822 | daddr_t sblockloc, fsblockloc; | | 822 | daddr_t sblockloc, fsblockloc; |
823 | int blks, fstype; | | 823 | int blks, fstype; |
824 | int error, i, bsize, ronly, bset = 0; | | 824 | int error, i, bsize, ronly, bset = 0; |
825 | #ifdef FFS_EI | | 825 | #ifdef FFS_EI |
826 | int needswap = 0; /* keep gcc happy */ | | 826 | int needswap = 0; /* keep gcc happy */ |
827 | #endif | | 827 | #endif |
828 | int32_t *lp; | | 828 | int32_t *lp; |
829 | kauth_cred_t cred; | | 829 | kauth_cred_t cred; |
830 | u_int32_t sbsize = 8192; /* keep gcc happy*/ | | 830 | u_int32_t sbsize = 8192; /* keep gcc happy*/ |
| | | 831 | int32_t fsbsize; |
831 | | | 832 | |
832 | dev = devvp->v_rdev; | | 833 | dev = devvp->v_rdev; |
833 | cred = l ? l->l_cred : NOCRED; | | 834 | cred = l ? l->l_cred : NOCRED; |
834 | | | 835 | |
835 | /* Flush out any old buffers remaining from a previous use. */ | | 836 | /* Flush out any old buffers remaining from a previous use. */ |
836 | vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); | | 837 | vn_lock(devvp, LK_EXCLUSIVE | LK_RETRY); |
837 | error = vinvalbuf(devvp, V_SAVE, cred, l, 0, 0); | | 838 | error = vinvalbuf(devvp, V_SAVE, cred, l, 0, 0); |
838 | VOP_UNLOCK(devvp); | | 839 | VOP_UNLOCK(devvp); |
839 | if (error) | | 840 | if (error) |
840 | return (error); | | 841 | return (error); |
841 | | | 842 | |
842 | ronly = (mp->mnt_flag & MNT_RDONLY) != 0; | | 843 | ronly = (mp->mnt_flag & MNT_RDONLY) != 0; |
843 | | | 844 | |
| @@ -876,41 +877,45 @@ ffs_mountfs(struct vnode *devvp, struct | | | @@ -876,41 +877,45 @@ ffs_mountfs(struct vnode *devvp, struct |
876 | goto out; | | 877 | goto out; |
877 | } | | 878 | } |
878 | error = bread(devvp, sblock_try[i] / DEV_BSIZE, SBLOCKSIZE, cred, | | 879 | error = bread(devvp, sblock_try[i] / DEV_BSIZE, SBLOCKSIZE, cred, |
879 | 0, &bp); | | 880 | 0, &bp); |
880 | if (error) { | | 881 | if (error) { |
881 | fs = NULL; | | 882 | fs = NULL; |
882 | goto out; | | 883 | goto out; |
883 | } | | 884 | } |
884 | fs = (struct fs*)bp->b_data; | | 885 | fs = (struct fs*)bp->b_data; |
885 | fsblockloc = sblockloc = sblock_try[i]; | | 886 | fsblockloc = sblockloc = sblock_try[i]; |
886 | if (fs->fs_magic == FS_UFS1_MAGIC) { | | 887 | if (fs->fs_magic == FS_UFS1_MAGIC) { |
887 | sbsize = fs->fs_sbsize; | | 888 | sbsize = fs->fs_sbsize; |
888 | fstype = UFS1; | | 889 | fstype = UFS1; |
| | | 890 | fsbsize = fs->fs_bsize; |
889 | #ifdef FFS_EI | | 891 | #ifdef FFS_EI |
890 | needswap = 0; | | 892 | needswap = 0; |
891 | } else if (fs->fs_magic == bswap32(FS_UFS1_MAGIC)) { | | 893 | } else if (fs->fs_magic == bswap32(FS_UFS1_MAGIC)) { |
892 | sbsize = bswap32(fs->fs_sbsize); | | 894 | sbsize = bswap32(fs->fs_sbsize); |
893 | fstype = UFS1; | | 895 | fstype = UFS1; |
| | | 896 | fsbsize = bswap32(fs->fs_bsize); |
894 | needswap = 1; | | 897 | needswap = 1; |
895 | #endif | | 898 | #endif |
896 | } else if (fs->fs_magic == FS_UFS2_MAGIC) { | | 899 | } else if (fs->fs_magic == FS_UFS2_MAGIC) { |
897 | sbsize = fs->fs_sbsize; | | 900 | sbsize = fs->fs_sbsize; |
898 | fstype = UFS2; | | 901 | fstype = UFS2; |
| | | 902 | fsbsize = fs->fs_bsize; |
899 | #ifdef FFS_EI | | 903 | #ifdef FFS_EI |
900 | needswap = 0; | | 904 | needswap = 0; |
901 | } else if (fs->fs_magic == bswap32(FS_UFS2_MAGIC)) { | | 905 | } else if (fs->fs_magic == bswap32(FS_UFS2_MAGIC)) { |
902 | sbsize = bswap32(fs->fs_sbsize); | | 906 | sbsize = bswap32(fs->fs_sbsize); |
903 | fstype = UFS2; | | 907 | fstype = UFS2; |
| | | 908 | fsbsize = bswap32(fs->fs_bsize); |
904 | needswap = 1; | | 909 | needswap = 1; |
905 | #endif | | 910 | #endif |
906 | } else | | 911 | } else |
907 | continue; | | 912 | continue; |
908 | | | 913 | |
909 | | | 914 | |
910 | /* fs->fs_sblockloc isn't defined for old filesystems */ | | 915 | /* fs->fs_sblockloc isn't defined for old filesystems */ |
911 | if (fstype == UFS1 && !(fs->fs_old_flags & FS_FLAGS_UPDATED)) { | | 916 | if (fstype == UFS1 && !(fs->fs_old_flags & FS_FLAGS_UPDATED)) { |
912 | if (sblockloc == SBLOCK_UFS2) | | 917 | if (sblockloc == SBLOCK_UFS2) |
913 | /* | | 918 | /* |
914 | * This is likely to be the first alternate | | 919 | * This is likely to be the first alternate |
915 | * in a filesystem with 64k blocks. | | 920 | * in a filesystem with 64k blocks. |
916 | * Don't use it. | | 921 | * Don't use it. |
| @@ -923,26 +928,33 @@ ffs_mountfs(struct vnode *devvp, struct | | | @@ -923,26 +928,33 @@ ffs_mountfs(struct vnode *devvp, struct |
923 | if (needswap) | | 928 | if (needswap) |
924 | fsblockloc = bswap64(fsblockloc); | | 929 | fsblockloc = bswap64(fsblockloc); |
925 | #endif | | 930 | #endif |
926 | } | | 931 | } |
927 | | | 932 | |
928 | /* Check we haven't found an alternate superblock */ | | 933 | /* Check we haven't found an alternate superblock */ |
929 | if (fsblockloc != sblockloc) | | 934 | if (fsblockloc != sblockloc) |
930 | continue; | | 935 | continue; |
931 | | | 936 | |
932 | /* Validate size of superblock */ | | 937 | /* Validate size of superblock */ |
933 | if (sbsize > MAXBSIZE || sbsize < sizeof(struct fs)) | | 938 | if (sbsize > MAXBSIZE || sbsize < sizeof(struct fs)) |
934 | continue; | | 939 | continue; |
935 | | | 940 | |
| | | 941 | /* Check that we can handle the file system blocksize */ |
| | | 942 | if (fsbsize > MAXBSIZE) { |
| | | 943 | printf("ffs_mountfs: block size (%d) > MAXBSIZE (%d)", |
| | | 944 | fsbsize, MAXBSIZE); |
| | | 945 | continue; |
| | | 946 | } |
| | | 947 | |
936 | /* Ok seems to be a good superblock */ | | 948 | /* Ok seems to be a good superblock */ |
937 | break; | | 949 | break; |
938 | } | | 950 | } |
939 | | | 951 | |
940 | fs = malloc((u_long)sbsize, M_UFSMNT, M_WAITOK); | | 952 | fs = malloc((u_long)sbsize, M_UFSMNT, M_WAITOK); |
941 | memcpy(fs, bp->b_data, sbsize); | | 953 | memcpy(fs, bp->b_data, sbsize); |
942 | ump->um_fs = fs; | | 954 | ump->um_fs = fs; |
943 | | | 955 | |
944 | #ifdef FFS_EI | | 956 | #ifdef FFS_EI |
945 | if (needswap) { | | 957 | if (needswap) { |
946 | ffs_sb_swap((struct fs*)bp->b_data, fs); | | 958 | ffs_sb_swap((struct fs*)bp->b_data, fs); |
947 | fs->fs_flags |= FS_SWAPPED; | | 959 | fs->fs_flags |= FS_SWAPPED; |
948 | } else | | 960 | } else |