svn commit: r193377 - head/sys/gnu/fs/ext2fs

Stanislav Sedov stas at FreeBSD.org
Wed Jun 3 13:25:51 UTC 2009


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 <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(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 <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>
@@ -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 <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 *);
@@ -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 <sys/stat.h>
 #include <sys/bio.h>
 #include <sys/buf.h>
+#include <sys/endian.h>
 #include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/mount.h>
@@ -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


More information about the svn-src-head mailing list