From owner-svn-src-all@FreeBSD.ORG Wed Jun 3 13:25:51 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 26377106566B; Wed, 3 Jun 2009 13:25:51 +0000 (UTC) (envelope-from stas@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 143638FC1D; Wed, 3 Jun 2009 13:25:51 +0000 (UTC) (envelope-from stas@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n53DPpc9055631; Wed, 3 Jun 2009 13:25:51 GMT (envelope-from stas@svn.freebsd.org) Received: (from stas@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n53DPo2W055626; Wed, 3 Jun 2009 13:25:50 GMT (envelope-from stas@svn.freebsd.org) Message-Id: <200906031325.n53DPo2W055626@svn.freebsd.org> From: Stanislav Sedov Date: Wed, 3 Jun 2009 13:25:50 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r193377 - head/sys/gnu/fs/ext2fs X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 03 Jun 2009 13:25:51 -0000 Author: stas Date: Wed Jun 3 13:25:50 2009 New Revision: 193377 URL: http://svn.freebsd.org/changeset/base/193377 Log: - Sync our copies of ext2fs Linux headers to current Linux versions. Minimize differencies between our ext2fs headers and relevant Linux versions by using EXT2_SB macro to access the superblock fields. Most of the differencies in access to these fields are now hidden inside this macro. - Rename the s_db_per_group field of ext2fs_sb_info to s_gdb_count to reflect the similar change in Linux headers. New name also seem to be more appropriate for this field. - Use proper types for s_first_inode and s_inode_size in-core superblock fields. Now they reflec types used in the on-disk superblock version. - Add support for older filesystem revisions that doesn't have proper s_first_ino and s_inode_size fields in the on-disk superblock. In these cases predefined values for these fields are used. - Add simple sanity checks for s_first_inode and s_inode_size correctness. Reviewed by: bde (previous version) MFC after: 2 weeks Modified: head/sys/gnu/fs/ext2fs/ext2_fs.h head/sys/gnu/fs/ext2fs/ext2_fs_sb.h head/sys/gnu/fs/ext2fs/ext2_lookup.c head/sys/gnu/fs/ext2fs/ext2_vfsops.c head/sys/gnu/fs/ext2fs/ext2_vnops.c Modified: head/sys/gnu/fs/ext2fs/ext2_fs.h ============================================================================== --- head/sys/gnu/fs/ext2fs/ext2_fs.h Wed Jun 3 13:19:12 2009 (r193376) +++ head/sys/gnu/fs/ext2fs/ext2_fs.h Wed Jun 3 13:25:50 2009 (r193377) @@ -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 +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(s) ((s)->s_inode_size) -#define EXT2_FIRST_INO(s) ((s)->s_first_inode) -#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: head/sys/gnu/fs/ext2fs/ext2_fs_sb.h ============================================================================== --- head/sys/gnu/fs/ext2fs/ext2_fs_sb.h Wed Jun 3 13:19:12 2009 (r193376) +++ head/sys/gnu/fs/ext2fs/ext2_fs_sb.h Wed Jun 3 13:25:50 2009 (r193377) @@ -60,11 +60,9 @@ 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 */ - unsigned long s_first_inode; /* First inode on fs */ - unsigned int s_inode_size; /* Size for inode with extra data */ struct buffer_head * s_sbh; /* Buffer containing the super block */ struct ext2_super_block * s_es; /* Pointer to the super block in the buffer */ struct buffer_head ** s_group_desc; @@ -74,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: head/sys/gnu/fs/ext2fs/ext2_lookup.c ============================================================================== --- head/sys/gnu/fs/ext2fs/ext2_lookup.c Wed Jun 3 13:19:12 2009 (r193376) +++ head/sys/gnu/fs/ext2fs/ext2_lookup.c Wed Jun 3 13:25:50 2009 (r193377) @@ -46,6 +46,7 @@ #include #include #include +#include #include #include #include @@ -771,7 +772,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 @@ -949,7 +950,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: head/sys/gnu/fs/ext2fs/ext2_vfsops.c ============================================================================== --- head/sys/gnu/fs/ext2fs/ext2_vfsops.c Wed Jun 3 13:19:12 2009 (r193376) +++ head/sys/gnu/fs/ext2fs/ext2_vfsops.c Wed Jun 3 13:25:50 2009 (r193377) @@ -78,8 +78,8 @@ #include #include -#include #include +#include static int ext2_flushfiles(struct mount *mp, int flags, struct thread *td); static int ext2_mountfs(struct vnode *, struct mount *); @@ -412,7 +412,7 @@ static int compute_sb_data(devvp, es, fs V(s_fsbtodb) fs->s_qbmask = fs->s_blocksize - 1; V(s_qbmask) - fs->s_blocksize_bits = EXT2_BLOCK_SIZE_BITS(es); + fs->s_blocksize_bits = es->s_log_block_size + 10; V(s_blocksize_bits) fs->s_frag_size = EXT2_MIN_FRAG_SIZE << es->s_log_frag_size; V(s_frag_size) @@ -425,10 +425,23 @@ static int compute_sb_data(devvp, es, fs V(s_frags_per_group) fs->s_inodes_per_group = es->s_inodes_per_group; V(s_inodes_per_group) - fs->s_inode_size = es->s_inode_size; - V(s_inode_size) - fs->s_first_inode = es->s_first_ino; - V(s_first_inode); + 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; + + /* + * 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); V(s_inodes_per_block) fs->s_itb_per_group = fs->s_inodes_per_group /fs->s_inodes_per_block; @@ -443,8 +456,8 @@ static int compute_sb_data(devvp, es, 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) + fs->s_gdb_count = db_count; + V(s_gdb_count) fs->s_group_desc = bsd_malloc(db_count * sizeof (struct buf *), M_EXT2MNT, M_WAITOK); @@ -761,7 +774,7 @@ ext2_unmount(mp, mntflags) } /* 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); @@ -839,7 +852,7 @@ ext2_statfs(mp, sbp) nsb = fs->s_groups_count; overhead = es->s_first_data_block + /* Superblocks and block group descriptors: */ - nsb * (1 + fs->s_db_per_group) + + nsb * (1 + fs->s_gdb_count) + /* Inode bitmap, block bitmap, and inode table: */ fs->s_groups_count * (1 + 1 + fs->s_itb_per_group); Modified: head/sys/gnu/fs/ext2fs/ext2_vnops.c ============================================================================== --- head/sys/gnu/fs/ext2fs/ext2_vnops.c Wed Jun 3 13:19:12 2009 (r193376) +++ head/sys/gnu/fs/ext2fs/ext2_vnops.c Wed Jun 3 13:25:50 2009 (r193377) @@ -52,6 +52,7 @@ #include #include #include +#include #include #include #include @@ -1185,7 +1186,7 @@ ext2_mkdir(ap) goto bad; /* Initialize directory with "." and ".." from static template. */ - if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs->s_es, + if (EXT2_HAS_INCOMPAT_FEATURE(ip->i_e2fs, EXT2_FEATURE_INCOMPAT_FILETYPE)) dtp = &mastertemplate; else