diff options
author | Jiro SEKIBA <jir@unicus.jp> | 2010-07-09 18:51:56 +0900 |
---|---|---|
committer | Jim Meyering <meyering@redhat.com> | 2011-02-26 11:47:48 +0100 |
commit | d463e7ded8d486c95977f4501969056600a73501 (patch) | |
tree | 1142048f0091c4e66108c20250df386aaab034e4 /libparted/fs/nilfs2/nilfs2.c | |
parent | dff6b96b551bec36dfe1c4783184755da72b2901 (diff) | |
download | parted-d463e7ded8d486c95977f4501969056600a73501.tar.gz |
libparted: add nilfs2 module
* libparted/fs/nilfs2/Makefile.am: New file.
* libparted/fs/nilfs2/nilfs2.c: New file.
(is_valid_nilfs_sb, nilfs2_probe, nilfs2_clobber): New functions.
(ped_file_system_nilfs2_init, ped_file_system_nilfs2_done): Likewise.
(nilfs2_ops, nilfs2_type): Define.
* libparted/fs/Makefile.am (SUBDIRS): Add nilfs2.
* configure.ac (AC_OUTPUT): Add the new Makefile.
* libparted/libparted.c: Declare and use the _init and _done functions.
Add a new fs module to provide following:
- probe nilfs2 filesystem partition
- clobber nilfs2 filesystem partition
The is_valid_nilfs_sb function came from the grub nilfs2 module,
which is written by me and assigned to FSF.
Diffstat (limited to 'libparted/fs/nilfs2/nilfs2.c')
-rw-r--r-- | libparted/fs/nilfs2/nilfs2.c | 199 |
1 files changed, 199 insertions, 0 deletions
diff --git a/libparted/fs/nilfs2/nilfs2.c b/libparted/fs/nilfs2/nilfs2.c new file mode 100644 index 0000000..49634c0 --- /dev/null +++ b/libparted/fs/nilfs2/nilfs2.c @@ -0,0 +1,199 @@ +/* + * nilfs2.c - New Implementation of Log filesystem + * + * Written by Jiro SEKIBA <jir@unicus.jp> + * + * Copyright (C) 2011 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); +} |