Date: Fri, 19 Jun 2009 16:27:41 +0000 (UTC) From: Stanislav Sedov <stas@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-7@freebsd.org Subject: svn commit: r194495 - in stable/7/sys: . contrib/pf gnu/fs/ext2fs Message-ID: <200906191627.n5JGRfsk048501@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: stas Date: Fri Jun 19 16:27:41 2009 New Revision: 194495 URL: http://svn.freebsd.org/changeset/base/194495 Log: - MFC r187395-187397,193377,193382,193390,193628. Add support for inode sizes other than 128 bytes. Cleanup. Deleted: stable/7/sys/gnu/fs/ext2fs/sparc64-bitops.h Modified: stable/7/sys/ (props changed) stable/7/sys/contrib/pf/ (props changed) stable/7/sys/gnu/fs/ext2fs/ext2_fs.h stable/7/sys/gnu/fs/ext2fs/ext2_fs_sb.h stable/7/sys/gnu/fs/ext2fs/ext2_inode.c stable/7/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c stable/7/sys/gnu/fs/ext2fs/ext2_lookup.c stable/7/sys/gnu/fs/ext2fs/ext2_vfsops.c stable/7/sys/gnu/fs/ext2fs/ext2_vnops.c Modified: stable/7/sys/gnu/fs/ext2fs/ext2_fs.h ============================================================================== --- stable/7/sys/gnu/fs/ext2fs/ext2_fs.h Fri Jun 19 15:58:24 2009 (r194494) +++ stable/7/sys/gnu/fs/ext2fs/ext2_fs.h Fri Jun 19 16:27:41 2009 (r194495) @@ -52,6 +52,8 @@ #define umode_t mode_t #define loff_t off_t +#define cpu_to_le32(x) htole32(x) + /* * The second extended filesystem constants/structures */ @@ -87,12 +89,10 @@ #endif /* - * Special inodes numbers + * Special inode numbers */ #define EXT2_BAD_INO 1 /* Bad blocks inode */ #define EXT2_ROOT_INO 2 /* Root inode */ -#define EXT2_ACL_IDX_INO 3 /* ACL inode */ -#define EXT2_ACL_DATA_INO 4 /* ACL inode */ #define EXT2_BOOT_LOADER_INO 5 /* Boot loader inode */ #define EXT2_UNDEL_DIR_INO 6 /* Undelete directory inode */ @@ -104,17 +104,29 @@ */ #define EXT2_SUPER_MAGIC 0xEF53 +#ifdef __KERNEL__ +#include <linux/ext2_fs_sb.h> +static inline struct ext2_sb_info *EXT2_SB(struct super_block *sb) +{ + return sb->s_fs_info; +} +#elif defined(_KERNEL) /* - * Maximal count of links to a file + * FreeBSD passes the pointer to the in-core struct with relevant + * fields to EXT2_SB macro when accessing superblock fields. */ -#define EXT2_LINK_MAX 32000 +#define EXT2_SB(sb) (sb) +#else +/* Assume that user mode programs are passing in an ext2fs superblock, not + * a kernel struct super_block. This will allow us to call the feature-test + * macros from user land. */ +#define EXT2_SB(sb) (sb) +#endif /* - * Note: under FreeBSD, the "user" versions of the following macros are - * used (and must be used) in most cases, because ((s)->u.ext2_sb.s_es is - * not accessible. This depends on __KERNEL__ not being defined for - * kernel builds under FreeBSD. + * Maximal count of links to a file */ +#define EXT2_LINK_MAX 32000 /* * Macro-instructions used to manage several block sizes @@ -122,23 +134,22 @@ #define EXT2_MIN_BLOCK_SIZE 1024 #define EXT2_MAX_BLOCK_SIZE 4096 #define EXT2_MIN_BLOCK_LOG_SIZE 10 -#if defined(__KERNEL__) || (defined(__FreeBSD__) && defined(_KERNEL)) +#if defined(__KERNEL__) || defined(_KERNEL) # define EXT2_BLOCK_SIZE(s) ((s)->s_blocksize) #else # define EXT2_BLOCK_SIZE(s) (EXT2_MIN_BLOCK_SIZE << (s)->s_log_block_size) #endif -#define EXT2_ACLE_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_acl_entry)) #define EXT2_ADDR_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (__u32)) -#ifdef __KERNEL__ +#if defined(__KERNEL__) || defined(_KERNEL) # define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_blocksize_bits) #else # define EXT2_BLOCK_SIZE_BITS(s) ((s)->s_log_block_size + 10) #endif -#ifdef notyet -#ifdef __KERNEL__ -#define EXT2_ADDR_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_addr_per_block_bits) -#define EXT2_INODE_SIZE(s) ((s)->u.ext2_sb.s_inode_size) -#define EXT2_FIRST_INO(s) ((s)->u.ext2_sb.s_first_ino) +#if defined(__KERNEL__) || defined(_KERNEL) +#define EXT2_ADDR_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_addr_per_block_bits) +#define EXT2_INODE_SIZE(s) (EXT2_SB(s)->s_inode_size) +#define EXT2_FIRST_INO(s) (EXT2_SB(s)->s_first_ino) +#define EXT2_INODES_PER_BLOCK(s) ((s)->s_inodes_per_block) #else #define EXT2_INODE_SIZE(s) (((s)->s_rev_level == EXT2_GOOD_OLD_REV) ? \ EXT2_GOOD_OLD_INODE_SIZE : \ @@ -147,12 +158,6 @@ EXT2_GOOD_OLD_FIRST_INO : \ (s)->s_first_ino) #endif -#else /* !notyet */ -#define EXT2_INODES_PER_BLOCK(s) ((s)->s_inodes_per_block) -/* Should be sizeof(struct ext2_inode): */ -#define EXT2_INODE_SIZE 128 -#define EXT2_FIRST_INO 11 -#endif /* notyet */ /* * Macro-instructions used to manage fragments @@ -160,15 +165,11 @@ #define EXT2_MIN_FRAG_SIZE 1024 #define EXT2_MAX_FRAG_SIZE 4096 #define EXT2_MIN_FRAG_LOG_SIZE 10 -#ifdef __KERNEL__ -# define EXT2_FRAG_SIZE(s) ((s)->u.ext2_sb.s_frag_size) -# define EXT2_FRAGS_PER_BLOCK(s) ((s)->u.ext2_sb.s_frags_per_block) +#if defined(__KERNEL__) || defined(_KERNEL) +# define EXT2_FRAG_SIZE(s) (EXT2_SB(s)->s_frag_size) +# define EXT2_FRAGS_PER_BLOCK(s) (EXT2_SB(s)->s_frags_per_block) #else -# if defined(_KERNEL) && defined(__FreeBSD__) -# define EXT2_FRAG_SIZE(s) ((s)->s_frag_size) -# else # define EXT2_FRAG_SIZE(s) (EXT2_MIN_FRAG_SIZE << (s)->s_log_frag_size) -# endif # define EXT2_FRAGS_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / EXT2_FRAG_SIZE(s)) #endif @@ -212,11 +213,11 @@ struct ext2_group_desc /* * Macro-instructions used to manage group descriptors */ -#ifdef __KERNEL__ -# define EXT2_BLOCKS_PER_GROUP(s) ((s)->u.ext2_sb.s_blocks_per_group) -# define EXT2_DESC_PER_BLOCK(s) ((s)->u.ext2_sb.s_desc_per_block) -# define EXT2_INODES_PER_GROUP(s) ((s)->u.ext2_sb.s_inodes_per_group) -# define EXT2_DESC_PER_BLOCK_BITS(s) ((s)->u.ext2_sb.s_desc_per_block_bits) +#if defined(__KERNEL__) || defined(_KERNEL) +# define EXT2_BLOCKS_PER_GROUP(s) (EXT2_SB(s)->s_blocks_per_group) +# define EXT2_DESC_PER_BLOCK(s) (EXT2_SB(s)->s_desc_per_block) +# define EXT2_INODES_PER_GROUP(s) (EXT2_SB(s)->s_inodes_per_group) +# define EXT2_DESC_PER_BLOCK_BITS(s) (EXT2_SB(s)->s_desc_per_block_bits) #else # define EXT2_BLOCKS_PER_GROUP(s) ((s)->s_blocks_per_group) # define EXT2_DESC_PER_BLOCK(s) (EXT2_BLOCK_SIZE(s) / sizeof (struct ext2_group_desc)) @@ -366,7 +367,7 @@ struct ext2_inode { #define clear_opt(o, opt) o &= ~EXT2_MOUNT_##opt #define set_opt(o, opt) o |= EXT2_MOUNT_##opt -#define test_opt(sb, opt) ((sb)->u.ext2_sb.s_mount_opt & \ +#define test_opt(sb, opt) (EXT2_SB(sb)->s_mount_opt & \ EXT2_MOUNT_##opt) /* * Maximal mount counts between two filesystem checks @@ -444,15 +445,6 @@ struct ext2_super_block { __u32 s_reserved[204]; /* Padding to the end of the block */ }; -#ifdef __KERNEL__ -#define EXT2_SB(sb) (&((sb)->u.ext2_sb)) -#else -/* Assume that user mode programs are passing in an ext2fs superblock, not - * a kernel struct super_block. This will allow us to call the feature-test - * macros from user land. */ -#define EXT2_SB(sb) (sb) -#endif - /* * Codes for operating systems */ @@ -478,11 +470,11 @@ struct ext2_super_block { */ #define EXT2_HAS_COMPAT_FEATURE(sb,mask) \ - ( EXT2_SB(sb)->s_feature_compat & (mask) ) + ( EXT2_SB(sb)->s_es->s_feature_compat & cpu_to_le32(mask) ) #define EXT2_HAS_RO_COMPAT_FEATURE(sb,mask) \ - ( EXT2_SB(sb)->s_feature_ro_compat & (mask) ) + ( EXT2_SB(sb)->s_es->s_feature_ro_compat & cpu_to_le32(mask) ) #define EXT2_HAS_INCOMPAT_FEATURE(sb,mask) \ - ( EXT2_SB(sb)->s_feature_incompat & (mask) ) + ( EXT2_SB(sb)->s_es->s_feature_incompat & cpu_to_le32(mask) ) #define EXT2_FEATURE_COMPAT_DIR_PREALLOC 0x0001 Modified: stable/7/sys/gnu/fs/ext2fs/ext2_fs_sb.h ============================================================================== --- stable/7/sys/gnu/fs/ext2fs/ext2_fs_sb.h Fri Jun 19 15:58:24 2009 (r194494) +++ stable/7/sys/gnu/fs/ext2fs/ext2_fs_sb.h Fri Jun 19 16:27:41 2009 (r194495) @@ -60,7 +60,7 @@ struct ext2_sb_info { unsigned long s_blocks_per_group;/* Number of blocks in a group */ unsigned long s_inodes_per_group;/* Number of inodes in a group */ unsigned long s_itb_per_group; /* Number of inode table blocks per group */ - unsigned long s_db_per_group; /* Number of descriptor blocks per group */ + unsigned long s_gdb_count; /* Number of group descriptor blocks */ unsigned long s_desc_per_block; /* Number of group descriptors per block */ unsigned long s_groups_count; /* Number of groups in the fs */ struct buffer_head * s_sbh; /* Buffer containing the super block */ @@ -72,10 +72,13 @@ struct ext2_sb_info { struct buffer_head * s_inode_bitmap[EXT2_MAX_GROUP_LOADED]; unsigned long s_block_bitmap_number[EXT2_MAX_GROUP_LOADED]; struct buffer_head * s_block_bitmap[EXT2_MAX_GROUP_LOADED]; - int s_rename_lock; unsigned long s_mount_opt; - unsigned short s_resuid; - unsigned short s_resgid; +#ifdef notyet + uid_t s_resuid; + gid_t s_resgid; +#endif + unsigned short s_inode_size; + unsigned int s_first_ino; unsigned short s_mount_state; /* stuff that FFS keeps in its super block or that linux Modified: stable/7/sys/gnu/fs/ext2fs/ext2_inode.c ============================================================================== --- stable/7/sys/gnu/fs/ext2fs/ext2_inode.c Fri Jun 19 15:58:24 2009 (r194494) +++ stable/7/sys/gnu/fs/ext2fs/ext2_inode.c Fri Jun 19 16:27:41 2009 (r194495) @@ -91,7 +91,7 @@ ext2_update(vp, waitfor) return (error); } ext2_i2ei(ip, (struct ext2_inode *)((char *)bp->b_data + - EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number))); + EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number))); if (waitfor && (vp->v_mount->mnt_kern_flag & MNTK_ASYNC) == 0) return (bwrite(bp)); else { Modified: stable/7/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c ============================================================================== --- stable/7/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c Fri Jun 19 15:58:24 2009 (r194494) +++ stable/7/sys/gnu/fs/ext2fs/ext2_linux_ialloc.c Fri Jun 19 16:27:41 2009 (r194495) @@ -225,7 +225,7 @@ void ext2_free_inode (struct inode * ino sb = inode->i_e2fs; lock_super (DEVVP(inode)); - if (inode->i_number < EXT2_FIRST_INO || + if (inode->i_number < EXT2_FIRST_INO(sb) || inode->i_number > sb->s_es->s_inodes_count) { printf ("free_inode reserved inode or nonexistent inode"); unlock_super (DEVVP(inode)); @@ -435,7 +435,7 @@ repeat: goto repeat; } j += i * EXT2_INODES_PER_GROUP(sb) + 1; - if (j < EXT2_FIRST_INO || j > es->s_inodes_count) { + if (j < EXT2_FIRST_INO(sb) || j > es->s_inodes_count) { printf ( "ext2_new_inode:" "reserved inode or inode > inodes count - " "block_group = %d,inode=%d", i, j); Modified: stable/7/sys/gnu/fs/ext2fs/ext2_lookup.c ============================================================================== --- stable/7/sys/gnu/fs/ext2fs/ext2_lookup.c Fri Jun 19 15:58:24 2009 (r194494) +++ stable/7/sys/gnu/fs/ext2fs/ext2_lookup.c Fri Jun 19 16:27:41 2009 (r194495) @@ -46,6 +46,7 @@ #include <sys/namei.h> #include <sys/bio.h> #include <sys/buf.h> +#include <sys/endian.h> #include <sys/mount.h> #include <sys/vnode.h> #include <sys/malloc.h> @@ -772,7 +773,7 @@ ext2_direnter(ip, dvp, cnp) dp = VTOI(dvp); newdir.inode = ip->i_number; newdir.name_len = cnp->cn_namelen; - if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es, + if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs, EXT2_FEATURE_INCOMPAT_FILETYPE)) newdir.file_type = DTTOFT(IFTODT(ip->i_mode)); else @@ -950,7 +951,7 @@ ext2_dirrewrite(dp, ip, cnp) &bp)) != 0) return (error); ep->inode = ip->i_number; - if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es, + if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs, EXT2_FEATURE_INCOMPAT_FILETYPE)) ep->file_type = DTTOFT(IFTODT(ip->i_mode)); else Modified: stable/7/sys/gnu/fs/ext2fs/ext2_vfsops.c ============================================================================== --- stable/7/sys/gnu/fs/ext2fs/ext2_vfsops.c Fri Jun 19 15:58:24 2009 (r194494) +++ stable/7/sys/gnu/fs/ext2fs/ext2_vfsops.c Fri Jun 19 16:27:41 2009 (r194495) @@ -5,7 +5,7 @@ * University of Utah, Department of Computer Science */ /*- - * Copyright (c) 1989, 1991, 1993, 1994 + * Copyright (c) 1989, 1991, 1993, 1994 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -78,13 +78,13 @@ #include <gnu/fs/ext2fs/fs.h> #include <gnu/fs/ext2fs/ext2_extern.h> -#include <gnu/fs/ext2fs/ext2_fs.h> #include <gnu/fs/ext2fs/ext2_fs_sb.h> +#include <gnu/fs/ext2fs/ext2_fs.h> -static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td); -static int ext2_mountfs(struct vnode *, struct mount *, struct thread *); -static int ext2_reload(struct mount *mp, struct thread *td); -static int ext2_sbupdate(struct ext2mount *, int); +static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td); +static int ext2_mountfs(struct vnode *, struct mount *, struct thread *); +static int ext2_reload(struct mount *mp, struct thread *td); +static int ext2_sbupdate(struct ext2mount *, int); static vfs_unmount_t ext2_unmount; static vfs_root_t ext2_root; @@ -109,9 +109,6 @@ static struct vfsops ext2fs_vfsops = { VFS_SET(ext2fs_vfsops, ext2fs, 0); -#define bsd_malloc malloc -#define bsd_free free - static int ext2_check_sb_compat(struct ext2_super_block *es, struct cdev *dev, int ronly); static int compute_sb_data(struct vnode * devvp, @@ -120,25 +117,23 @@ static int compute_sb_data(struct vnode static const char *ext2_opts[] = { "from", "export", "acls", "noexec", "noatime", "union", "suiddir", "multilabel", "nosymfollow", "noclusterr", "noclusterw", "force", NULL }; - + /* * VFS Operations. * * mount system call */ static int -ext2_mount(mp, td) - struct mount *mp; - struct thread *td; +ext2_mount(struct mount *mp, struct thread *td) { struct vfsoptlist *opts; struct vnode *devvp; struct ext2mount *ump = 0; struct ext2_sb_info *fs; + struct nameidata nd, *ndp = &nd; + mode_t accessmode; char *path, *fspec; int error, flags, len; - mode_t accessmode; - struct nameidata nd, *ndp = &nd; opts = mp->mnt_optnew; @@ -195,6 +190,7 @@ ext2_mount(mp, td) if (fs->s_rd_only && !vfs_flagopt(opts, "ro", NULL, 0)) { if (ext2_check_sb_compat(fs->s_es, devvp->v_rdev, 0)) return (EPERM); + /* * If upgrade to read-write by non-root, then verify * that user has necessary permissions on the device. @@ -221,8 +217,7 @@ ext2_mount(mp, td) (fs->s_es->s_state & EXT2_ERROR_FS)) { if (mp->mnt_flag & MNT_FORCE) { printf( -"WARNING: %s was not properly dismounted\n", - fs->fs_fsmnt); +"WARNING: %s was not properly dismounted\n", fs->fs_fsmnt); } else { printf( "WARNING: R/W mount of %s denied. Filesystem is not clean - run fsck\n", @@ -242,6 +237,7 @@ ext2_mount(mp, td) return (error); } } + /* * Not an update, or updating the name: look up the name * and verify that it refers to a sensible disk device. @@ -291,6 +287,7 @@ ext2_mount(mp, td) } ump = VFSTOEXT2(mp); fs = ump->um_e2fs; + /* * Note that this strncpy() is ok because of a check at the start * of ext2_mount(). @@ -302,63 +299,55 @@ ext2_mount(mp, td) } /* - * checks that the data in the descriptor blocks make sense - * this is taken from ext2/super.c + * Checks that the data in the descriptor blocks make sense + * this is taken from ext2/super.c. */ -static int ext2_check_descriptors (struct ext2_sb_info * sb) +static int +ext2_check_descriptors(struct ext2_sb_info *sb) { - int i; - int desc_block = 0; - unsigned long block = sb->s_es->s_first_data_block; - struct ext2_group_desc * gdp = NULL; - - /* ext2_debug ("Checking group descriptors"); */ + struct ext2_group_desc *gdp = NULL; + unsigned long block = sb->s_es->s_first_data_block; + int desc_block = 0; + int i; - for (i = 0; i < sb->s_groups_count; i++) - { + for (i = 0; i < sb->s_groups_count; i++) { /* examine next descriptor block */ - if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) - gdp = (struct ext2_group_desc *) - sb->s_group_desc[desc_block++]->b_data; - if (gdp->bg_block_bitmap < block || - gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) - { - printf ("ext2_check_descriptors: " - "Block bitmap for group %d" - " not in group (block %lu)!\n", - i, (unsigned long) gdp->bg_block_bitmap); - return 0; - } - if (gdp->bg_inode_bitmap < block || - gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) - { - printf ("ext2_check_descriptors: " - "Inode bitmap for group %d" - " not in group (block %lu)!\n", - i, (unsigned long) gdp->bg_inode_bitmap); - return 0; - } - if (gdp->bg_inode_table < block || - gdp->bg_inode_table + sb->s_itb_per_group >= - block + EXT2_BLOCKS_PER_GROUP(sb)) - { - printf ("ext2_check_descriptors: " - "Inode table for group %d" - " not in group (block %lu)!\n", - i, (unsigned long) gdp->bg_inode_table); - return 0; - } - block += EXT2_BLOCKS_PER_GROUP(sb); - gdp++; - } - return 1; + if ((i % EXT2_DESC_PER_BLOCK(sb)) == 0) + gdp = (struct ext2_group_desc *) + sb->s_group_desc[desc_block++]->b_data; + if (gdp->bg_block_bitmap < block || + gdp->bg_block_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) { + printf ("ext2_check_descriptors: " + "Block bitmap for group %d" + " not in group (block %lu)!\n", + i, (unsigned long) gdp->bg_block_bitmap); + return (0); + } + if (gdp->bg_inode_bitmap < block || + gdp->bg_inode_bitmap >= block + EXT2_BLOCKS_PER_GROUP(sb)) { + printf ("ext2_check_descriptors: " + "Inode bitmap for group %d" + " not in group (block %lu)!\n", + i, (unsigned long) gdp->bg_inode_bitmap); + return (0); + } + if (gdp->bg_inode_table < block || + gdp->bg_inode_table + sb->s_itb_per_group >= + block + EXT2_BLOCKS_PER_GROUP(sb)) { + printf ("ext2_check_descriptors: " + "Inode table for group %d" + " not in group (block %lu)!\n", + i, (unsigned long) gdp->bg_inode_table); + return (0); + } + block += EXT2_BLOCKS_PER_GROUP(sb); + gdp++; + } + return (1); } static int -ext2_check_sb_compat(es, dev, ronly) - struct ext2_super_block *es; - struct cdev *dev; - int ronly; +ext2_check_sb_compat(struct ext2_super_block *es, struct cdev *dev, int ronly) { if (es->s_magic != EXT2_SUPER_MAGIC) { @@ -375,9 +364,8 @@ ext2_check_sb_compat(es, dev, ronly) } if (!ronly && (es->s_feature_ro_compat & ~EXT2_FEATURE_RO_COMPAT_SUPP)) { - printf( -"WARNING: R/W mount of %s denied due to unsupported optional features\n", - devtoname(dev)); + printf("WARNING: R/W mount of %s denied due to " + "unsupported optional features\n", devtoname(dev)); return (1); } } @@ -385,107 +373,101 @@ ext2_check_sb_compat(es, dev, ronly) } /* - * this computes the fields of the ext2_sb_info structure from the - * data in the ext2_super_block structure read in + * This computes the fields of the ext2_sb_info structure from the + * data in the ext2_super_block structure read in. */ -static int compute_sb_data(devvp, es, fs) - struct vnode * devvp; - struct ext2_super_block * es; - struct ext2_sb_info * fs; +static int +compute_sb_data(struct vnode *devvp, struct ext2_super_block *es, + struct ext2_sb_info *fs) { - int db_count, error; - int i, j; - int logic_sb_block = 1; /* XXX for now */ - -#if 1 -#define V(v) -#else -#define V(v) printf(#v"= %d\n", fs->v); -#endif + int db_count, error; + int i, j; + int logic_sb_block = 1; /* XXX for now */ + + fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size; + fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size; + fs->s_fsbtodb = es->s_log_block_size + 1; + fs->s_qbmask = fs->s_blocksize - 1; + fs->s_blocksize_bits = es->s_log_block_size + 10; + fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size; + if (fs->s_frag_size) + fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size; + fs->s_blocks_per_group = es->s_blocks_per_group; + fs->s_frags_per_group = es->s_frags_per_group; + fs->s_inodes_per_group = es->s_inodes_per_group; + if (es->s_rev_level == EXT2_GOOD_OLD_REV) { + fs->s_first_ino = EXT2_GOOD_OLD_FIRST_INO; + fs->s_inode_size = EXT2_GOOD_OLD_INODE_SIZE; + } else { + fs->s_first_ino = es->s_first_ino; + fs->s_inode_size = es->s_inode_size; - fs->s_blocksize = EXT2_MIN_BLOCK_SIZE << es->s_log_block_size; - V(s_blocksize) - fs->s_bshift = EXT2_MIN_BLOCK_LOG_SIZE + es->s_log_block_size; - V(s_bshift) - fs->s_fsbtodb = es->s_log_block_size + 1; - V(s_fsbtodb) - fs->s_qbmask = fs->s_blocksize - 1; - V(s_bmask) - fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es); - V(s_blocksize_bits) - fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size; - V(s_frag_size) - if (fs->s_frag_size) - fs->s_frags_per_block = fs->s_blocksize / fs->s_frag_size; - V(s_frags_per_block) - fs->s_blocks_per_group = es->s_blocks_per_group; - V(s_blocks_per_group) - fs->s_frags_per_group = es->s_frags_per_group; - V(s_frags_per_group) - fs->s_inodes_per_group = es->s_inodes_per_group; - V(s_inodes_per_group) - fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE; - V(s_inodes_per_block) - fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block; - V(s_itb_per_group) - fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc); - V(s_desc_per_block) - /* s_resuid / s_resgid ? */ - fs->s_groups_count = (es->s_blocks_count - - es->s_first_data_block + - EXT2_BLOCKS_PER_GROUP(fs) - 1) / - EXT2_BLOCKS_PER_GROUP(fs); - V(s_groups_count) - db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) / - EXT2_DESC_PER_BLOCK(fs); - fs->s_db_per_group = db_count; - V(s_db_per_group) + /* + * Simple sanity check for superblock inode size value. + */ + if (fs->s_inode_size < EXT2_GOOD_OLD_INODE_SIZE || + fs->s_inode_size > fs->s_blocksize || + (fs->s_inode_size & (fs->s_inode_size - 1)) != 0) { + printf("EXT2-fs: invalid inode size %d\n", + fs->s_inode_size); + return (EIO); + } + } + fs->s_inodes_per_block = fs->s_blocksize / EXT2_INODE_SIZE(fs); + fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block; + fs->s_desc_per_block = fs->s_blocksize / sizeof (struct ext2_group_desc); + /* s_resuid / s_resgid ? */ + fs->s_groups_count = (es->s_blocks_count - es->s_first_data_block + + EXT2_BLOCKS_PER_GROUP(fs) - 1) / EXT2_BLOCKS_PER_GROUP(fs); + db_count = (fs->s_groups_count + EXT2_DESC_PER_BLOCK(fs) - 1) / + EXT2_DESC_PER_BLOCK(fs); + fs->s_gdb_count = db_count; + fs->s_group_desc = malloc(db_count * sizeof (struct buf *), + M_EXT2MNT, M_WAITOK); - fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *), - M_EXT2MNT, M_WAITOK); + /* + * Adjust logic_sb_block. + * Godmar thinks: if the blocksize is greater than 1024, then + * the superblock is logically part of block zero. + */ + if(fs->s_blocksize > SBSIZE) + logic_sb_block = 0; - /* adjust logic_sb_block */ - if(fs->s_blocksize > SBSIZE) - /* Godmar thinks: if the blocksize is greater than 1024, then - the superblock is logically part of block zero. - */ - logic_sb_block = 0; - - for (i = 0; i < db_count; i++) { - error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1), - fs->s_blocksize, NOCRED, &fs->s_group_desc[i]); - if(error) { - for (j = 0; j < i; j++) - brelse(fs->s_group_desc[j]); - bsd_free(fs->s_group_desc, M_EXT2MNT); - printf("EXT2-fs: unable to read group descriptors (%d)\n", error); - return EIO; - } - LCK_BUF(fs->s_group_desc[i]) - } - if(!ext2_check_descriptors(fs)) { - for (j = 0; j < db_count; j++) - ULCK_BUF(fs->s_group_desc[j]) - bsd_free(fs->s_group_desc, M_EXT2MNT); - printf("EXT2-fs: (ext2_check_descriptors failure) " - "unable to read group descriptors\n"); - return EIO; - } - - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) { - fs->s_inode_bitmap_number[i] = 0; - fs->s_inode_bitmap[i] = NULL; - fs->s_block_bitmap_number[i] = 0; - fs->s_block_bitmap[i] = NULL; - } - fs->s_loaded_inode_bitmaps = 0; - fs->s_loaded_block_bitmaps = 0; - if (es->s_rev_level == EXT2_GOOD_OLD_REV || (es->s_feature_ro_compat & - EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == 0) - fs->fs_maxfilesize = 0x7fffffff; - else - fs->fs_maxfilesize = 0x7fffffffffffffff; - return 0; + for (i = 0; i < db_count; i++) { + error = bread(devvp , fsbtodb(fs, logic_sb_block + i + 1), + fs->s_blocksize, NOCRED, &fs->s_group_desc[i]); + if(error) { + for (j = 0; j < i; j++) + brelse(fs->s_group_desc[j]); + free(fs->s_group_desc, M_EXT2MNT); + printf("EXT2-fs: unable to read group descriptors" + " (%d)\n", error); + return (EIO); + } + LCK_BUF(fs->s_group_desc[i]) + } + if(!ext2_check_descriptors(fs)) { + for (j = 0; j < db_count; j++) + ULCK_BUF(fs->s_group_desc[j]) + free(fs->s_group_desc, M_EXT2MNT); + printf("EXT2-fs: (ext2_check_descriptors failure) " + "unable to read group descriptors\n"); + return (EIO); + } + for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) { + fs->s_inode_bitmap_number[i] = 0; + fs->s_inode_bitmap[i] = NULL; + fs->s_block_bitmap_number[i] = 0; + fs->s_block_bitmap[i] = NULL; + } + fs->s_loaded_inode_bitmaps = 0; + fs->s_loaded_block_bitmaps = 0; + if (es->s_rev_level == EXT2_GOOD_OLD_REV || + (es->s_feature_ro_compat & EXT2_FEATURE_RO_COMPAT_LARGE_FILE) == 0) + fs->fs_maxfilesize = 0x7fffffff; + else + fs->fs_maxfilesize = 0x7fffffffffffffff; + return (0); } /* @@ -507,7 +489,7 @@ ext2_reload(struct mount *mp, struct thr struct vnode *vp, *mvp, *devvp; struct inode *ip; struct buf *bp; - struct ext2_super_block * es; + struct ext2_super_block *es; struct ext2_sb_info *fs; int error; @@ -538,7 +520,7 @@ ext2_reload(struct mount *mp, struct thr if((error = compute_sb_data(devvp, es, fs)) != 0) { brelse(bp); - return error; + return (error); } #ifdef UNKLAR if (fs->fs_sbsize < SBSIZE) @@ -564,12 +546,12 @@ loop: } if (vinvalbuf(vp, 0, td, 0, 0)) panic("ext2_reload: dirty2"); + /* * Step 5: re-read inode data for all active vnodes. */ ip = VTOI(vp); - error = - bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), + error = bread(devvp, fsbtodb(fs, ino_to_fsba(fs, ip->i_number)), (int)fs->s_blocksize, NOCRED, &bp); if (error) { VOP_UNLOCK(vp, 0, td); @@ -578,7 +560,7 @@ loop: return (error); } ext2_ei2i((struct ext2_inode *) ((char *)bp->b_data + - EXT2_INODE_SIZE * ino_to_fsbo(fs, ip->i_number)), ip); + EXT2_INODE_SIZE(fs) * ino_to_fsbo(fs, ip->i_number)), ip); brelse(bp); VOP_UNLOCK(vp, 0, td); vrele(vp); @@ -589,18 +571,15 @@ loop: } /* - * Common code for mount and mountroot + * Common code for mount and mountroot. */ static int -ext2_mountfs(devvp, mp, td) - struct vnode *devvp; - struct mount *mp; - struct thread *td; +ext2_mountfs(struct vnode *devvp, struct mount *mp, struct thread *td) { struct ext2mount *ump; struct buf *bp; struct ext2_sb_info *fs; - struct ext2_super_block * es; + struct ext2_super_block *es; struct cdev *dev = devvp->v_rdev; struct g_consumer *cp; struct bufobj *bo; @@ -658,19 +637,22 @@ ext2_mountfs(devvp, mp, td) goto out; } } - ump = bsd_malloc(sizeof *ump, M_EXT2MNT, M_WAITOK); + ump = malloc(sizeof *ump, M_EXT2MNT, M_WAITOK); bzero((caddr_t)ump, sizeof *ump); - /* I don't know whether this is the right strategy. Note that - we dynamically allocate both an ext2_sb_info and an ext2_super_block - while Linux keeps the super block in a locked buffer + + /* + * I don't know whether this is the right strategy. Note that + * we dynamically allocate both an ext2_sb_info and an ext2_super_block + * while Linux keeps the super block in a locked buffer. */ - ump->um_e2fs = bsd_malloc(sizeof(struct ext2_sb_info), + ump->um_e2fs = malloc(sizeof(struct ext2_sb_info), M_EXT2MNT, M_WAITOK); - ump->um_e2fs->s_es = bsd_malloc(sizeof(struct ext2_super_block), + ump->um_e2fs->s_es = malloc(sizeof(struct ext2_super_block), M_EXT2MNT, M_WAITOK); bcopy(es, ump->um_e2fs->s_es, (u_int)sizeof(struct ext2_super_block)); if ((error = compute_sb_data(devvp, ump->um_e2fs->s_es, ump->um_e2fs))) goto out; + /* * We don't free the group descriptors allocated by compute_sb_data() * until ext2_unmount(). This is OK since the mount will succeed. @@ -679,8 +661,10 @@ ext2_mountfs(devvp, mp, td) bp = NULL; fs = ump->um_e2fs; fs->s_rd_only = ronly; /* ronly is set according to mnt_flags */ - /* if the fs is not mounted read-only, make sure the super block is - always written back on a sync() + + /* + * If the fs is not mounted read-only, make sure the super block is + * always written back on a sync(). */ fs->s_wasvalid = fs->s_es->s_state & EXT2_VALID_FS ? 1 : 0; if (ronly == 0) { @@ -699,13 +683,15 @@ ext2_mountfs(devvp, mp, td) ump->um_devvp = devvp; ump->um_bo = &devvp->v_bufobj; ump->um_cp = cp; - /* setting those two parameters allowed us to use - ufs_bmap w/o changse ! - */ + + /* + * Setting those two parameters allowed us to use + * ufs_bmap w/o changse! + */ ump->um_nindir = EXT2_ADDR_PER_BLOCK(fs); ump->um_bptrtodb = fs->s_es->s_log_block_size + 1; ump->um_seqinc = EXT2_FRAGS_PER_BLOCK(fs); - if (ronly == 0) + if (ronly == 0) ext2_sbupdate(ump, MNT_WAIT); return (0); out: @@ -719,22 +705,19 @@ out: PICKUP_GIANT(); } if (ump) { - bsd_free(ump->um_e2fs->s_es, M_EXT2MNT); - bsd_free(ump->um_e2fs, M_EXT2MNT); - bsd_free(ump, M_EXT2MNT); + free(ump->um_e2fs->s_es, M_EXT2MNT); + free(ump->um_e2fs, M_EXT2MNT); + free(ump, M_EXT2MNT); mp->mnt_data = (qaddr_t)0; } return (error); } /* - * unmount system call + * Unmount system call. */ static int -ext2_unmount(mp, mntflags, td) - struct mount *mp; - int mntflags; - struct thread *td; +ext2_unmount(struct mount *mp, int mntflags, struct thread *td) { struct ext2mount *ump; struct ext2_sb_info *fs; @@ -758,18 +741,17 @@ ext2_unmount(mp, mntflags, td) } /* release buffers containing group descriptors */ - for(i = 0; i < fs->s_db_per_group; i++) + for(i = 0; i < fs->s_gdb_count; i++) ULCK_BUF(fs->s_group_desc[i]) - bsd_free(fs->s_group_desc, M_EXT2MNT); + free(fs->s_group_desc, M_EXT2MNT); /* release cached inode/block bitmaps */ - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_inode_bitmap[i]) - ULCK_BUF(fs->s_inode_bitmap[i]) - - for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) - if (fs->s_block_bitmap[i]) - ULCK_BUF(fs->s_block_bitmap[i]) + for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) + if (fs->s_inode_bitmap[i]) + ULCK_BUF(fs->s_inode_bitmap[i]) + for (i = 0; i < EXT2_MAX_GROUP_LOADED; i++) + if (fs->s_block_bitmap[i]) + ULCK_BUF(fs->s_block_bitmap[i]) DROP_GIANT(); g_topology_lock(); @@ -777,9 +759,9 @@ ext2_unmount(mp, mntflags, td) g_topology_unlock(); PICKUP_GIANT(); vrele(ump->um_devvp); - bsd_free(fs->s_es, M_EXT2MNT); - bsd_free(fs, M_EXT2MNT); - bsd_free(ump, M_EXT2MNT); + free(fs->s_es, M_EXT2MNT); + free(fs, M_EXT2MNT); + free(ump, M_EXT2MNT); mp->mnt_data = (qaddr_t)0; MNT_ILOCK(mp); mp->mnt_flag &= ~MNT_LOCAL; @@ -791,10 +773,7 @@ ext2_unmount(mp, mntflags, td) * Flush out all the files in a filesystem. */ static int -ext2_flushfiles(mp, flags, td) - struct mount *mp; - int flags; - struct thread *td; +ext2_flushfiles(struct mount *mp, int flags, struct thread *td) { int error; @@ -804,18 +783,15 @@ ext2_flushfiles(mp, flags, td) /* * Get file system statistics. - * taken from ext2/super.c ext2_statfs + * taken from ext2/super.c ext2_statfs. */ static int -ext2_statfs(mp, sbp, td) - struct mount *mp; - struct statfs *sbp; - struct thread *td; +ext2_statfs(struct mount *mp, struct statfs *sbp, struct thread *td) { - unsigned long overhead; struct ext2mount *ump; struct ext2_sb_info *fs; struct ext2_super_block *es; + unsigned long overhead; int i, nsb; ump = VFSTOEXT2(mp); @@ -835,19 +811,19 @@ ext2_statfs(mp, sbp, td) nsb++; } else nsb = fs->s_groups_count; - overhead = es->s_first_data_block + - /* Superblocks and block group descriptors: */ - nsb * (1 + fs->s_db_per_group) + - /* Inode bitmap, block bitmap, and inode table: */ - fs->s_groups_count * (1 + 1 + fs->s_itb_per_group); + overhead = es->s_first_data_block + + /* Superblocks and block group descriptors: */ + nsb * (1 + fs->s_gdb_count) + + /* Inode bitmap, block bitmap, and inode table: */ + fs->s_groups_count * (1 + 1 + fs->s_itb_per_group); - sbp->f_bsize = EXT2_FRAG_SIZE(fs); + sbp->f_bsize = EXT2_FRAG_SIZE(fs); sbp->f_iosize = EXT2_BLOCK_SIZE(fs); sbp->f_blocks = es->s_blocks_count - overhead; - sbp->f_bfree = es->s_free_blocks_count; - sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count; - sbp->f_files = es->s_inodes_count; - sbp->f_ffree = es->s_free_inodes_count; + sbp->f_bfree = es->s_free_blocks_count; + sbp->f_bavail = sbp->f_bfree - es->s_r_blocks_count; + sbp->f_files = es->s_inodes_count; + sbp->f_ffree = es->s_free_inodes_count; return (0); } @@ -859,10 +835,7 @@ ext2_statfs(mp, sbp, td) * Note: we are always called with the filesystem marked `MPBUSY'. */ static int -ext2_sync(mp, waitfor, td) - struct mount *mp; - int waitfor; - struct thread *td; +ext2_sync(struct mount *mp, int waitfor, struct thread *td) { struct vnode *mvp, *vp; struct inode *ip; @@ -875,6 +848,7 @@ ext2_sync(mp, waitfor, td) printf("fs = %s\n", fs->fs_fsmnt); panic("ext2_sync: rofs mod"); } + /* * Write back each (modified) inode. */ @@ -912,6 +886,7 @@ loop: MNT_ILOCK(mp); } MNT_IUNLOCK(mp); + /* * Force stale file system control information to be flushed. */ @@ -921,6 +896,7 @@ loop: allerror = error; VOP_UNLOCK(ump->um_devvp, 0, td); } + /* * Write back modified superblock. */ @@ -940,11 +916,7 @@ loop: * done by the calling routine. */ static int -ext2_vget(mp, ino, flags, vpp) - struct mount *mp; - ino_t ino; - int flags; - struct vnode **vpp; +ext2_vget(struct mount *mp, ino_t ino, int flags, struct vnode **vpp) { struct ext2_sb_info *fs; struct inode *ip; @@ -952,9 +924,9 @@ ext2_vget(mp, ino, flags, vpp) struct buf *bp; struct vnode *vp; struct cdev *dev; + struct thread *td; *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200906191627.n5JGRfsk048501>