[parted-devel] [PATCH] libparted: add nilfs2 module

Jiro SEKIBA jir at unicus.jp
Fri Jul 9 09:51:56 UTC 2010


Hi, 

This is a new fs module to provide following:
- probe nilfs2 filesystem partition
- clobber nilfs2 filesystem partition

I bollowed a is_valid_nilfs_sb function from grub nilfs2 module,
which is written by me and assigned to FSF.
Therefore I added Copyright as FSF and thus GPL3 code.

Signed-off-by: Jiro SEKIBA <jir at unicus.jp>
---
 configure.ac                    |    1 +
 libparted/fs/Makefile.am        |    6 +-
 libparted/fs/nilfs2/Makefile.am |    8 ++
 libparted/fs/nilfs2/nilfs2.c    |  199 +++++++++++++++++++++++++++++++++++++++
 libparted/libparted.c           |    4 +
 5 files changed, 216 insertions(+), 2 deletions(-)
 create mode 100644 libparted/fs/nilfs2/Makefile.am
 create mode 100644 libparted/fs/nilfs2/nilfs2.c

diff --git a/configure.ac b/configure.ac
index 9ae5783..f951d5e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -634,6 +634,7 @@ libparted/fs/ntfs/Makefile
 libparted/fs/reiserfs/Makefile
 libparted/fs/ufs/Makefile
 libparted/fs/xfs/Makefile
+libparted/fs/nilfs2/Makefile
 libparted/tests/Makefile
 libparted.pc
 parted/Makefile
diff --git a/libparted/fs/Makefile.am b/libparted/fs/Makefile.am
index 97fe32e..4714320 100644
--- a/libparted/fs/Makefile.am
+++ b/libparted/fs/Makefile.am
@@ -4,7 +4,8 @@
 #
 # This file may be modified and/or distributed without restriction.
 
-SUBDIRS       = amiga ext2 ufs fat ntfs hfs linux_swap xfs jfs reiserfs # bfs
+SUBDIRS       = amiga ext2 ufs fat ntfs hfs linux_swap xfs jfs reiserfs \
+		nilfs2 # bfs
 
 partedincludedir      =	-I$(top_srcdir)/include
 noinst_LTLIBRARIES    =	libfs.la
@@ -24,7 +25,8 @@ libfs_la_LIBADD   = $(UUID_LIBS)		\
 		    linux_swap/liblinuxswap.la	\
 		    xfs/libxfs.la		\
 		    jfs/libjfs.la		\
-		    reiserfs/libreiserfs.la
+		    reiserfs/libreiserfs.la	\
+		    nilfs2/libnilfs2.la
 #		    bfs/libbfs.la
 
 libfs_la_SOURCES   =
diff --git a/libparted/fs/nilfs2/Makefile.am b/libparted/fs/nilfs2/Makefile.am
new file mode 100644
index 0000000..9bb87b6
--- /dev/null
+++ b/libparted/fs/nilfs2/Makefile.am
@@ -0,0 +1,8 @@
+partedincludedir	= -I$(top_srcdir)/include
+
+noinst_LTLIBRARIES	= libnilfs2.la
+libnilfs2_la_SOURCES	= nilfs2.c
+
+INCLUDES = $(partedincludedir) $(INTLINCS)
+
+MAINTAINERCLEANFILES = Makefile.in
diff --git a/libparted/fs/nilfs2/nilfs2.c b/libparted/fs/nilfs2/nilfs2.c
new file mode 100644
index 0000000..4d8ccbd
--- /dev/null
+++ b/libparted/fs/nilfs2/nilfs2.c
@@ -0,0 +1,199 @@
+/* 
+ *  nilfs2.c - New Implementation of Log filesystem 
+ *
+ *  Written by  Jiro SEKIBA <jir at unicus.jp>
+ *
+ *  Copyright (C) 2003,2004,2005,2007,2008,2010 Free Software Foundation, Inc.
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+
+#include <parted/parted.h>
+#include <parted/crc32.h>
+#include <parted/endian.h>
+
+/* Magic value for nilfs2 superblock. */
+#define	NILFS2_SUPER_MAGIC		0x3434
+
+/* primariy superblock offset in 512bytes blocks. */
+#define NILFS_SB_OFFSET			2
+
+/* secondary superblock offset in 512byte blocks. */
+#define NILFS_SB2_OFFSET(devsize)	((((devsize)>>3) - 1) << 3)
+
+struct nilfs2_super_block
+{
+	uint32_t	s_rev_level;
+	uint16_t	s_minor_rev_level;
+	uint16_t	s_magic;
+	uint16_t	s_bytes;
+	uint16_t	s_flags;
+	uint32_t	s_crc_seed;
+	uint32_t	s_sum;
+	uint32_t	s_log_block_size;
+	uint64_t	s_nsegments;
+	uint64_t	s_dev_size;
+	uint64_t	s_first_data_block;
+	uint32_t	s_blocks_per_segment;
+	uint32_t	s_r_segments_percentage;
+	uint64_t	s_last_cno;
+	uint64_t	s_last_pseg;
+	uint64_t	s_last_seq;
+	uint64_t	s_free_blocks_count;
+	uint64_t	s_ctime;
+	uint64_t	s_mtime;
+	uint64_t	s_wtime;
+	uint16_t	s_mnt_count;
+	uint16_t	s_max_mnt_count;
+	uint16_t	s_state;
+	uint16_t	s_errors;
+	uint64_t	s_lastcheck;
+	uint32_t	s_checkinterval;
+	uint32_t	s_creator_os;
+	uint16_t	s_def_resuid;
+	uint16_t	s_def_resgid;
+	uint32_t	s_first_ino;
+	uint16_t	s_inode_size;
+	uint16_t	s_dat_entry_size;
+	uint16_t	s_checkpoint_size;
+	uint16_t	s_segment_usage_size;
+	uint8_t		s_uuid[16];
+	char		s_volume_name[80];
+	uint32_t	s_c_interval;
+	uint32_t	s_c_block_max;
+	uint32_t	s_reserved[192];
+};
+
+static int
+is_valid_nilfs_sb(struct nilfs2_super_block *sb)
+{
+	static unsigned char sum[4];
+	const int sumoff = offsetof (struct nilfs2_super_block, s_sum);
+	size_t bytes;
+	uint32_t crc;
+
+	if (PED_LE16_TO_CPU(sb->s_magic) != NILFS2_SUPER_MAGIC)
+		return 0;
+
+	bytes = PED_LE16_TO_CPU(sb->s_bytes);
+	if (bytes > 1024)
+		return 0;
+
+	crc = __efi_crc32(sb, sumoff, PED_LE32_TO_CPU(sb->s_crc_seed));
+	crc = __efi_crc32(sum, 4, crc);
+	crc = __efi_crc32((unsigned char *)sb + sumoff + 4,
+			  bytes - sumoff - 4, crc);
+
+	return crc == PED_LE32_TO_CPU(sb->s_sum);
+}
+
+PedGeometry*
+nilfs2_probe (PedGeometry* geom)
+{
+	void *sb_v;
+	void *sb2_v;
+	struct nilfs2_super_block *sb = NULL;
+	struct nilfs2_super_block *sb2 = NULL;
+	PedSector length = geom->length;
+	PedSector sb2off;
+
+	/* ignore if sector size is not 512bytes for now  */
+	if (geom->dev->sector_size != PED_SECTOR_SIZE_DEFAULT)
+		return NULL;
+
+	sb2off = NILFS_SB2_OFFSET(length);
+
+	if (ped_geometry_read_alloc(geom, &sb_v, 2, 1))
+		sb = sb_v;
+
+	if (ped_geometry_read_alloc(geom, &sb2_v, sb2off, 1)) 
+		sb2 = sb2_v;
+
+	if ((!sb || !is_valid_nilfs_sb(sb)) &&
+	    (!sb2 || !is_valid_nilfs_sb(sb2)) ) {
+		free(sb);
+		free(sb2);
+		return NULL;
+	}
+
+	/* reserve 4k bytes for secondary superblock */
+	length = sb2off + 8;
+
+	free(sb);
+	free(sb2);
+	return ped_geometry_new(geom->dev, geom->start, length);
+}
+
+#ifndef DISCOVER_ONLY
+static int
+nilfs2_clobber (PedGeometry* geom)
+{
+	char buf[512];
+	int ret[2];
+
+	printf("nilfs2_clobber\n");
+	memset (buf, 0, 512);
+
+	ret[0] = ped_geometry_write (geom, buf, NILFS_SB_OFFSET, 1);
+	ret[1] = ped_geometry_write (geom, buf,
+				     NILFS_SB2_OFFSET(geom->length), 1);
+
+	return ret[0]|ret[1];
+}
+#endif /* !DISCOVER_ONLY */
+
+static PedFileSystemOps nilfs2_ops = {
+	probe:			nilfs2_probe,
+#ifndef DISCOVER_ONLY
+ #if 0
+	clobber:		nilfs2_clobber,
+ #else
+	clobber:		NULL,
+ #endif
+#else
+	clobber:		NULL,
+#endif
+	open:			NULL,
+	create:			NULL,
+	close:			NULL,
+	check:			NULL,
+	copy:			NULL,
+	resize:			NULL,
+	get_create_constraint:	NULL,
+	get_resize_constraint:	NULL,
+	get_copy_constraint:	NULL
+};
+
+#define NILFS2_BLOCK_SIZES ((int[5]){1024, 2048, 4096, 8192, 0})
+
+static PedFileSystemType nilfs2_type = {
+	next:   NULL,
+	ops:    &nilfs2_ops,
+	name:   "nilfs2",
+	block_sizes: NILFS2_BLOCK_SIZES
+};
+
+void
+ped_file_system_nilfs2_init ()
+{
+	ped_file_system_type_register (&nilfs2_type);
+}
+
+void
+ped_file_system_nilfs2_done ()
+{
+	ped_file_system_type_unregister (&nilfs2_type);
+}
diff --git a/libparted/libparted.c b/libparted/libparted.c
index 1cb085c..1a73be6 100644
--- a/libparted/libparted.c
+++ b/libparted/libparted.c
@@ -109,6 +109,7 @@ extern void ped_file_system_jfs_init (void);
 extern void ped_file_system_hfs_init (void);
 extern void ped_file_system_fat_init (void);
 extern void ped_file_system_ext2_init (void);
+extern void ped_file_system_nilfs2_init (void);
 
 static void
 init_file_system_types ()
@@ -123,6 +124,7 @@ init_file_system_types ()
 	ped_file_system_hfs_init ();
 	ped_file_system_fat_init ();
 	ped_file_system_ext2_init ();
+	ped_file_system_nilfs2_init ();
 }
 #endif /* ENABLE_FS */
 
@@ -179,6 +181,7 @@ _init()
 }
 
 #ifdef ENABLE_FS
+extern void ped_file_system_nilfs2_done (void);
 extern void ped_file_system_ext2_done (void);
 extern void ped_file_system_fat_done (void);
 extern void ped_file_system_hfs_done (void);
@@ -193,6 +196,7 @@ extern void ped_file_system_amiga_done (void);
 static void
 done_file_system_types ()
 {
+	ped_file_system_nilfs2_done ();
 	ped_file_system_ext2_done ();
 	ped_file_system_fat_done ();
 	ped_file_system_hfs_done ();
-- 
1.7.1





More information about the parted-devel mailing list