From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1Nimhg-0005Ip-T8 for mharc-grub-devel@gnu.org; Sat, 20 Feb 2010 05:36:52 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1Nimhd-0005IT-34 for grub-devel@gnu.org; Sat, 20 Feb 2010 05:36:49 -0500 Received: from [140.186.70.92] (port=59904 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1Nimha-0005IC-Is for grub-devel@gnu.org; Sat, 20 Feb 2010 05:36:48 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1NimhY-000524-4z for grub-devel@gnu.org; Sat, 20 Feb 2010 05:36:47 -0500 Received: from mail-ew0-f228.google.com ([209.85.219.228]:33274) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1NimhX-00051w-Is for grub-devel@gnu.org; Sat, 20 Feb 2010 05:36:44 -0500 Received: by ewy28 with SMTP id 28so938644ewy.8 for ; Sat, 20 Feb 2010 02:36:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:received:received:message-id:date:from :user-agent:mime-version:to:subject:references:in-reply-to :x-enigmail-version:content-type; bh=6obbBuoreFC+rKjrl0xAFnSPERRljL+0HsdeM1jo1Og=; b=s9uehKyyPNF3qEPzfCPI9H0cg7L3x5gQ3LzgOZSoglC3iGElj03vUu+HDheVcQ7vVS 9pL0oVGZMbrxvvIQowbnOxck9eDVkf4r9VVslViZZAqb/KdSFC3wbodPKrjvVSAXL/2q rS0AtwrJr4Ed4JTwdRitojtLqR2MF2GBYEewE= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=message-id:date:from:user-agent:mime-version:to:subject:references :in-reply-to:x-enigmail-version:content-type; b=wp8zzBQV8BX5u1OfhppKDZYIFnaCsv5K0Icw/hKQwbdL76ElyIWraWqs1ztCWX7jiw 98MtDPcFlbjVoD+k5sxmIg6acV+kSfJLeh74vsolu6eOw92Oq5ivdL+FqTlVBL1la6lt LDvPJjQiCq6csCwnk5mm4fHv9kDVsjccpq4Io= Received: by 10.213.104.19 with SMTP id m19mr4031849ebo.40.1266662202011; Sat, 20 Feb 2010 02:36:42 -0800 (PST) Received: from debian.bg45.phnet ([81.62.151.15]) by mx.google.com with ESMTPS id 14sm692807ewy.7.2010.02.20.02.36.38 (version=TLSv1/SSLv3 cipher=RC4-MD5); Sat, 20 Feb 2010 02:36:40 -0800 (PST) Message-ID: <4B7FBB35.2090901@gmail.com> Date: Sat, 20 Feb 2010 11:36:37 +0100 From: =?UTF-8?B?VmxhZGltaXIgJ8+GLWNvZGVyL3BoY29kZXInIFNlcmJpbmVua28=?= User-Agent: Mozilla-Thunderbird 2.0.0.22 (X11/20091109) MIME-Version: 1.0 To: The development of GNU GRUB References: <878waq3nzx.wl%jir@sekiba.com> In-Reply-To: <878waq3nzx.wl%jir@sekiba.com> X-Enigmail-Version: 0.95.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="------------enig14F53AFB8FD28BFC5EF70D0E" X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) Subject: Re: [PATCHv2] a new filesystem module for nilfs2 X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GNU GRUB List-Id: The development of GNU GRUB List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 20 Feb 2010 10:36:49 -0000 This is an OpenPGP/MIME signed message (RFC 2440 and 3156) --------------enig14F53AFB8FD28BFC5EF70D0E Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Jiro SEKIBA wrote: > Hi, > > This is a revised patch to support nilfs2, a log file system. > > I've checked it the first one on qemu-system-ppc and found a few bugs. > Thank you for encouraging me to test it on qemu-system-ppc! > > This is a bug fixed version. I've checked it by grub-fstest on PPC > and by installing and booting it to boot sector of nilfs2 partition on = i386. > > Here are the change logs from the first one > > - big endian bug fixes > * add "packed" attribute for all structs > =20 Are you sure about this? It greatly impacts the performance on non-x86. At first glance no structure in your patch should need this attribute. Which structures were a problem? > * swap physical block number bytes > - separate pkglib_MODULES addition > - leftover removal > - moved DIV_ROUND_UP macro into misc.h > - add separate function to check super block > * add major version checking > > ToDo: > 1. CRC check for superblock to ensure the partition is a nilfs2 partiti= on > 2. CRC check latest log block to ensure valid log=20 > 3. search the latest log in case unclean unmount happened > > thanks > > regards > =20 > -----------------------------------------------------------------------= - > > =3D=3D=3D modified file 'conf/any-emu.rmk' > --- conf/any-emu.rmk 2010-02-03 00:24:07 +0000 > +++ conf/any-emu.rmk 2010-02-18 13:57:40 +0000 > @@ -38,7 +38,7 @@ > \ > fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ > fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ > - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ > + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ > fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ > fs/befs.c fs/befs_be.c fs/tar.c \ > \ > > =3D=3D=3D modified file 'conf/common.rmk' > --- conf/common.rmk 2010-02-06 14:37:23 +0000 > +++ conf/common.rmk 2010-02-18 13:57:40 +0000 > @@ -28,9 +28,9 @@ > \ > fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ > fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ > - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ > - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ > - fs/befs.c fs/befs_be.c fs/tar.c \ > + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ > + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ > + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ > \ > partmap/msdos.c partmap/apple.c partmap/sun.c partmap/gpt.c\ > kern/fs.c kern/env.c fs/fshelp.c \ > @@ -65,7 +65,7 @@ > \ > fs/affs.c fs/cpio.c fs/fat.c fs/ext2.c fs/hfs.c \ > fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ > - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ > + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ > fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c fs/befs.c \ > fs/befs_be.c fs/tar.c \ > \ > @@ -270,6 +270,12 @@ > minix_mod_CFLAGS =3D $(COMMON_CFLAGS) > minix_mod_LDFLAGS =3D $(COMMON_LDFLAGS) > =20 > +# For nilfs2.mod. > +pkglib_MODULES +=3D nilfs2.mod > +nilfs2_mod_SOURCES =3D fs/nilfs2.c > +nilfs2_mod_CFLAGS =3D $(COMMON_CFLAGS) > +nilfs2_mod_LDFLAGS =3D $(COMMON_LDFLAGS) > + > # For hfs.mod. > hfs_mod_SOURCES =3D fs/hfs.c > hfs_mod_CFLAGS =3D $(COMMON_CFLAGS) > > =3D=3D=3D modified file 'conf/i386-pc.rmk' > --- conf/i386-pc.rmk 2010-02-03 00:24:07 +0000 > +++ conf/i386-pc.rmk 2010-02-18 13:57:40 +0000 > @@ -100,9 +100,9 @@ > \ > fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ > fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ > - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ > - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ > - fs/befs.c fs/befs_be.c fs/tar.c \ > + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ > + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ > + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ > \ > partmap/msdos.c partmap/gpt.c \ > \ > > =3D=3D=3D modified file 'conf/sparc64-ieee1275.rmk' > --- conf/sparc64-ieee1275.rmk 2010-01-20 20:31:39 +0000 > +++ conf/sparc64-ieee1275.rmk 2010-02-18 13:57:40 +0000 > @@ -74,9 +74,9 @@ > \ > fs/affs.c fs/cpio.c fs/ext2.c fs/fat.c fs/hfs.c \ > fs/hfsplus.c fs/iso9660.c fs/udf.c fs/jfs.c fs/minix.c \ > - fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c fs/sfs.c \ > - fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c fs/afs_be.c \ > - fs/befs.c fs/befs_be.c fs/tar.c \ > + fs/nilfs2.c fs/ntfs.c fs/ntfscomp.c fs/reiserfs.c \ > + fs/sfs.c fs/ufs.c fs/ufs2.c fs/xfs.c fs/afs.c \ > + fs/afs_be.c fs/befs.c fs/befs_be.c fs/tar.c \ > \ > partmap/amiga.c partmap/apple.c partmap/msdos.c \ > partmap/sun.c partmap/acorn.c \ > > =3D=3D=3D added file 'fs/nilfs2.c' > --- fs/nilfs2.c 1970-01-01 00:00:00 +0000 > +++ fs/nilfs2.c 2010-02-18 13:57:40 +0000 > @@ -0,0 +1,1126 @@ > +/*=20 > + * nilfs2.c - New Implementation of Log filesystem=20 > + * Copyright (C) 2010 Jiro SEKIBA =20 > + */ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2003,2004,2005,2007,2008 Free Software Foundation, = Inc. > + * > + * GRUB 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. > + * > + * GRUB 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 GRUB. If not, see . > + */ > + > + > +/* Filetype information as used in inodes. */ > +#define FILETYPE_INO_MASK 0170000 > +#define FILETYPE_INO_REG 0100000 > +#define FILETYPE_INO_DIRECTORY 0040000 > +#define FILETYPE_INO_SYMLINK 0120000 > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/** nilfs_fs.h **/ > +#define NILFS_INODE_BMAP_SIZE 7 > + > +#define NILFS_SUPORT_REV 2 > +#define NILFS_MINOR_REV 0 > + > +/* Magic value used to identify an nilfs2 filesystem. */ > +#define NILFS2_SUPER_MAGIC 0x3434 > +/* nilfs btree node flag */ > +#define NILFS_BTREE_NODE_ROOT 0x01 > + > +/* nilfs btree node level */ > +#define NILFS_BTREE_LEVEL_DATA 0 > +#define NILFS_BTREE_LEVEL_NODE_MIN (NILFS_BTREE_LEVEL_DATA + 1) > +#define NILFS_BTREE_LEVEL_MAX 14 > + > +struct grub_nilfs2_inode > +{ > + grub_uint64_t i_blocks; > + grub_uint64_t i_size; > + grub_uint64_t i_ctime; > + grub_uint64_t i_mtime; > + grub_uint32_t i_ctime_nsec; > + grub_uint32_t i_mtime_nsec; > + grub_uint32_t i_uid; > + grub_uint32_t i_gid; > + grub_uint16_t i_mode;=20 > + grub_uint16_t i_links_count; > + grub_uint32_t i_flags; > + grub_uint64_t i_bmap[NILFS_INODE_BMAP_SIZE]; > +#define i_device_code i_bmap[0] > + grub_uint64_t i_xattr; > + grub_uint32_t i_generation; > + grub_uint32_t i_pad; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_super_root > +{ > + grub_uint32_t sr_sum; > + grub_uint16_t sr_bytes; > + grub_uint16_t sr_flags; > + grub_uint64_t sr_nongc_ctime; > + struct grub_nilfs2_inode sr_dat; > + struct grub_nilfs2_inode sr_cpfile; > + struct grub_nilfs2_inode sr_sufile; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_super_block > +{ > + grub_uint32_t s_rev_level; > + grub_uint16_t s_minor_rev_level; > + grub_uint16_t s_magic; > + grub_uint16_t s_bytes; > + grub_uint16_t s_flags; > + grub_uint32_t s_crc_seed; > + grub_uint32_t s_sum; > + grub_uint32_t s_log_block_size; > + grub_uint64_t s_nsegments; > + grub_uint64_t s_dev_size; > + grub_uint64_t s_first_data_block; > + grub_uint32_t s_blocks_per_segment; > + grub_uint32_t s_r_segments_percentage; > + grub_uint64_t s_last_cno; > + grub_uint64_t s_last_pseg; > + grub_uint64_t s_last_seq; > + grub_uint64_t s_free_blocks_count; > + grub_uint64_t s_ctime; > + grub_uint64_t s_mtime; > + grub_uint64_t s_wtime; > + grub_uint16_t s_mnt_count; > + grub_uint16_t s_max_mnt_count; > + grub_uint16_t s_state; > + grub_uint16_t s_errors; > + grub_uint64_t s_lastcheck; > + grub_uint32_t s_checkinterval; > + grub_uint32_t s_creator_os; > + grub_uint16_t s_def_resuid; > + grub_uint16_t s_def_resgid; > + grub_uint32_t s_first_ino; > + grub_uint16_t s_inode_size; > + grub_uint16_t s_dat_entry_size; > + grub_uint16_t s_checkpoint_size; > + grub_uint16_t s_segment_usage_size; > + grub_uint8_t s_uuid[16]; > + char s_volume_name[16]; > + char s_last_mounted[64]; > + grub_uint32_t s_c_interval; > + grub_uint32_t s_c_block_max; > + grub_uint32_t s_reserved[192]; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_dir_entry > +{ > + grub_uint64_t inode; > + grub_uint16_t rec_len; > + grub_uint8_t name_len; > + grub_uint8_t file_type; > +#if 0 /* followed by file name */ > + char name[NILFS_NAME_LEN]; > + char pad; > +#endif > +} __attribute__ ((packed)); > + > +enum > +{ > + NILFS_FT_UNKNOWN, > + NILFS_FT_REG_FILE, > + NILFS_FT_DIR, > + NILFS_FT_CHRDEV, > + NILFS_FT_BLKDEV, > + NILFS_FT_FIFO, > + NILFS_FT_SOCK, > + NILFS_FT_SYMLINK, > + NILFS_FT_MAX > +}; > + > +struct grub_nilfs2_finfo > +{ > + grub_uint64_t fi_ino; > + grub_uint64_t fi_cno; > + grub_uint32_t fi_nblocks; > + grub_uint32_t fi_ndatablk; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_binfo_v > +{ > + grub_uint64_t bi_vblocknr; > + grub_uint64_t bi_blkoff; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_binfo_dat > +{ > + grub_uint64_t bi_blkoff; > + grub_uint8_t bi_level; > + grub_uint8_t bi_pad[7]; > +} __attribute__ ((packed)); > + > +union grub_nilfs2_binfo > +{ > + struct grub_nilfs2_binfo_v bi_v; > + struct grub_nilfs2_binfo_dat bi_dat; > +}; > + > +struct grub_nilfs2_segment_summary > +{ > + grub_uint32_t ss_datasum; > + grub_uint32_t ss_sumsum; > + grub_uint32_t ss_magic; > + grub_uint16_t ss_bytes; > + grub_uint16_t ss_flags; > + grub_uint64_t ss_seq; > + grub_uint64_t ss_create; > + grub_uint64_t ss_next; > + grub_uint32_t ss_nblocks; > + grub_uint32_t ss_nfinfo; > + grub_uint32_t ss_sumbytes; > + grub_uint32_t ss_pad; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_btree_node > +{ > + grub_uint8_t bn_flags; > + grub_uint8_t bn_level; > + grub_uint16_t bn_nchildren; > + grub_uint32_t bn_pad; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_palloc_group_desc > +{ > + grub_uint32_t pg_nfrees; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_dat_entry > +{ > + grub_uint64_t de_blocknr; > + grub_uint64_t de_start; > + grub_uint64_t de_end; > + grub_uint64_t de_rsv; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_snapshot_list { > + grub_uint64_t ssl_next; > + grub_uint64_t ssl_prev; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_cpfile_header > +{ > + grub_uint64_t ch_ncheckpoints; > + grub_uint64_t ch_nsnapshots; > + struct grub_nilfs2_snapshot_list ch_snapshot_list; > +} __attribute__ ((packed)); > + > +struct grub_nilfs2_checkpoint > +{ > + grub_uint32_t cp_flags; > + grub_uint32_t cp_checkpoints_count; > + struct grub_nilfs2_snapshot_list cp_snapshot_list; > + grub_uint64_t cp_cno; > + grub_uint64_t cp_create; > + grub_uint64_t cp_nblk_inc; > + grub_uint64_t cp_inodes_count; > + grub_uint64_t cp_blocks_count; > + struct grub_nilfs2_inode cp_ifile_inode; > +} __attribute__ ((packed)); > + > +/** nilfs_fs.h **/ > + > +/** bmap.h **/ > +#define NILFS_BMAP_LARGE 0x1 > +#define NILFS_BMAP_SIZE (NILFS_INODE_BMAP_SIZE * sizeof(grub_uint64_t)= ) > +/** bmap.h **/ > + > +/** btree.h **/ > +/* nilfs extra padding for nonroot btree node */ > +#define NILFS_BTREE_NODE_EXTRA_PAD_SIZE (sizeof(grub_uint64_t)) > +#define NILFS_BTREE_ROOT_SIZE NILFS_BMAP_SIZE > +#define NILFS_BTREE_ROOT_NCHILDREN_MAX \ > + ((NILFS_BTREE_ROOT_SIZE - sizeof(struct nilfs_btree_node)) / \ > + (sizeof(grub_uint64_t) + sizeof(grub_uint64_t)) ) > +/** btree.h **/ > + > + > +struct grub_fshelp_node > +{ > + struct grub_nilfs2_data *data; > + struct grub_nilfs2_inode inode; > + grub_uint64_t ino; > + int inode_read; > +}; > + > +struct grub_nilfs2_data > +{ > + struct grub_nilfs2_super_block sblock; > + struct grub_nilfs2_super_root sroot; > + struct grub_nilfs2_inode ifile; > + grub_disk_t disk; > + struct grub_nilfs2_inode *inode; > + struct grub_fshelp_node diropen; > +}; > + > +/* Log2 size of nilfs2 block in 512 blocks. */ > +#define LOG2_NILFS2_BLOCK_SIZE(data) \ > + (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 1) > + > +/* Log2 size of nilfs2 block in bytes. */ > +#define LOG2_BLOCK_SIZE(data) \ > + (grub_le_to_cpu32 (data->sblock.s_log_block_size) + 10) > + > +/* The size of an nilfs2 block in bytes. */ > +#define NILFS2_BLOCK_SIZE(data) (1 << LOG2_BLOCK_SIZE (data)) > + > +static grub_uint64_t > +grub_nilfs2_dat_translate(struct grub_nilfs2_data *data, grub_uint64_t= key); > +static grub_dl_t my_mod; > + > +=0C > + > +static inline unsigned long > +grub_nilfs2_palloc_entries_per_group(struct grub_nilfs2_data *data) > +{ > + return 1UL << (LOG2_BLOCK_SIZE(data) + 3); > +} > + > +static inline grub_uint64_t > +grub_nilfs2_palloc_group(struct grub_nilfs2_data *data, > + grub_uint64_t nr, grub_uint32_t *offset) > +{ > + return grub_divmod64(nr, grub_nilfs2_palloc_entries_per_group(data),= offset); > +} > + > +static inline grub_uint32_t > +grub_nilfs2_palloc_groups_per_desc_block(struct grub_nilfs2_data *data= ) > +{ > + return NILFS2_BLOCK_SIZE(data) / sizeof(struct grub_nilfs2_palloc_gr= oup_desc); > +} > + > +static inline grub_uint32_t > +grub_nilfs2_entries_per_block(struct grub_nilfs2_data *data, > + unsigned long entry_size) > +{ > + return NILFS2_BLOCK_SIZE(data) / entry_size; > +} > + > + > +static inline grub_uint32_t > +grub_nilfs2_blocks_per_group(struct grub_nilfs2_data *data, > + unsigned long entry_size) > +{ > + return DIV_ROUND_UP(grub_nilfs2_palloc_entries_per_group(data), > + grub_nilfs2_entries_per_block(data,entry_size)) + 1; > +} > + > +static inline grub_uint32_t > +grub_nilfs2_blocks_per_desc_block(struct grub_nilfs2_data *data, > + unsigned long entry_size) > +{ > + return grub_nilfs2_palloc_groups_per_desc_block(data) * > + grub_nilfs2_blocks_per_group(data,entry_size) + 1; > +} > + > +static inline grub_uint32_t > +grub_nilfs2_palloc_desc_block_offset(struct grub_nilfs2_data *data, > + unsigned long group, > + unsigned long entry_size) > +{ > + grub_uint32_t desc_block =3D > + group / grub_nilfs2_palloc_groups_per_desc_block(data); > + return desc_block * grub_nilfs2_blocks_per_desc_block(data,entry_siz= e); > +} > + > +static inline grub_uint32_t > +grub_nilfs2_palloc_bitmap_block_offset(struct grub_nilfs2_data *data, > + unsigned long group, > + unsigned long entry_size) > +{ > + unsigned long desc_offset =3D group % > + grub_nilfs2_palloc_groups_per_desc_block(data); > + > + return grub_nilfs2_palloc_desc_block_offset(data, group, entry_size)= + 1 + > + desc_offset * grub_nilfs2_blocks_per_group(data, entry_size);= > +} > + > +static inline grub_uint32_t > +grub_nilfs2_palloc_entry_offset(struct grub_nilfs2_data *data, > + grub_uint64_t nr, unsigned long entry_size) > +{ > + unsigned long group; > + grub_uint32_t group_offset; > + > + group =3D grub_nilfs2_palloc_group(data, nr, &group_offset); > + > + return grub_nilfs2_palloc_bitmap_block_offset(data, group,entry_size= ) + 1 + > + group_offset / grub_nilfs2_entries_per_block(data, entry_siz= e); > + > +} > + > +static inline struct grub_nilfs2_btree_node * > +grub_nilfs2_btree_get_root(struct grub_nilfs2_inode *inode) > +{ > + return (struct grub_nilfs2_btree_node *)&inode->i_bmap[0]; > +} > + > +static inline int > +grub_nilfs2_btree_get_level(struct grub_nilfs2_btree_node *node) > +{ > + return node->bn_level; > +} > + > +static inline grub_uint64_t * > +grub_nilfs2_btree_node_dkeys(struct grub_nilfs2_btree_node *node) > +{ > + return (grub_uint64_t *)((char *)(node + 1) + > + ((node->bn_flags & NILFS_BTREE_NODE_ROOT) ?= > + 0 : NILFS_BTREE_NODE_EXTRA_PAD_SIZE)); > +} > + > +static inline grub_uint64_t > +grub_nilfs2_btree_node_get_key(struct grub_nilfs2_btree_node *node, in= t index) > +{ > + return grub_le_to_cpu64(*(grub_nilfs2_btree_node_dkeys(node) + index= )); > +} > + > +static inline int > +grub_nilfs2_btree_node_lookup(struct grub_nilfs2_btree_node *node, > + grub_uint64_t key, int *indexp) > +{ > + grub_uint64_t nkey; > + int index, low, high, s; > + > + low =3D 0; > + high =3D grub_le_to_cpu16(node->bn_nchildren) - 1; > + index =3D 0; > + s =3D 0; > + while(low <=3D high) > + { > + index =3D (low+high)/2; > + nkey =3D grub_nilfs2_btree_node_get_key(node, index); > + if(nkey =3D=3D key) > + { > + s =3D 0; > + goto out; > + } > + else if (nkey < key) > + { > + low =3D index +1; > + s =3D -1; > + } > + else > + { > + high =3D index - 1; > + s =3D 1; > + } > + } > + > + if (node->bn_level > NILFS_BTREE_LEVEL_NODE_MIN) > + { > + if (s > 0 && index > 0) > + index--; > + } > + else if (s < 0) > + index++; > + > + out: > + *indexp =3D index; > + return s =3D=3D 0; > +} > + > +static inline int > +grub_nilfs2_btree_node_nchildren_max(struct grub_nilfs2_data *data, > + struct grub_nilfs2_btree_node *node) > +{ > + int node_children_max =3D (( NILFS2_BLOCK_SIZE(data) - > + sizeof(struct grub_nilfs2_btree_node) - > + NILFS_BTREE_NODE_EXTRA_PAD_SIZE ) / > + (sizeof(grub_uint64_t) + sizeof(grub_uint64= _t)) ); > + > + return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_= max; > +} > + > +static inline grub_uint64_t * > +grub_nilfs2_btree_node_dptrs(struct grub_nilfs2_data *data, > + struct grub_nilfs2_btree_node *node) > +{ > + return (grub_uint64_t *)(grub_nilfs2_btree_node_dkeys(node) + > + grub_nilfs2_btree_node_nchildren_max(data,node)); > +} > + > +static inline grub_uint64_t > +grub_nilfs2_btree_node_get_ptr(struct grub_nilfs2_data *data, > + struct grub_nilfs2_btree_node *node, int index) > +{ > + return grub_le_to_cpu64(*(grub_nilfs2_btree_node_dptrs(data,node) + = index)); > +} > + > +static inline int > +grub_nilfs2_btree_get_nonroot_node(struct grub_nilfs2_data *data, > + grub_uint64_t ptr, void *block) > +{ > + grub_disk_t disk =3D data->disk; > + unsigned int nilfs2_block_count =3D (1 << LOG2_NILFS2_BLOCK_SIZE(dat= a)); > + > + return grub_disk_read (disk, ptr * nilfs2_block_count, 0,=20 > + NILFS2_BLOCK_SIZE(data), block); > +} > + > +static grub_uint64_t > +grub_nilfs2_btree_lookup(struct grub_nilfs2_data *data, > + struct grub_nilfs2_inode *inode, > + grub_uint64_t key, int need_translate) > +{ > + struct grub_nilfs2_btree_node *node; > + unsigned char block[NILFS2_BLOCK_SIZE(data)]; > + grub_uint64_t ptr; > + int level, found, index; > + > + node =3D grub_nilfs2_btree_get_root(inode); > + level =3D grub_nilfs2_btree_get_level(node); > + > + found =3D grub_nilfs2_btree_node_lookup(node, key, &index); > + ptr =3D grub_nilfs2_btree_node_get_ptr(data, node, index); > + if(need_translate) > + ptr =3D grub_nilfs2_dat_translate(data, ptr); > + > + for(level--; level >=3D NILFS_BTREE_LEVEL_NODE_MIN; level--) > + { > + grub_nilfs2_btree_get_nonroot_node(data, ptr, block); > + if(grub_errno) > + { > + grub_error(GRUB_ERR_BAD_FS,"disk read error\n"); > + return -1; > + } > + node =3D (struct grub_nilfs2_btree_node *)block; > + > + if(node->bn_level !=3D level) > + { > + grub_error(GRUB_ERR_BAD_FS,"btree level mismatch\n"); > + return -1; > + } > + > + if(!found) > + found =3D grub_nilfs2_btree_node_lookup(node, key, &index); > + else > + index =3D 0; > + > + if(index < grub_nilfs2_btree_node_nchildren_max(data, node)) > + { > + ptr =3D grub_nilfs2_btree_node_get_ptr(data, node, index); > + if(need_translate) > + ptr =3D grub_nilfs2_dat_translate(data, ptr); > + } > + else > + { > + grub_error(GRUB_ERR_BAD_FS,"btree corruption\n"); > + return -1; > + } > + } > + > + if(!found) > + return -1; > + > + return ptr; > +} > + > +static inline grub_uint64_t > +grub_nilfs2_direct_lookup(struct grub_nilfs2_inode *inode, grub_uint64= _t key) > +{ > + return grub_le_to_cpu64(inode->i_bmap[1+key]); > +} > + > +static inline grub_uint64_t > +grub_nilfs2_bmap_lookup(struct grub_nilfs2_data *data, > + struct grub_nilfs2_inode *inode, > + grub_uint64_t key, int need_translate) > +{ > + struct grub_nilfs2_btree_node *root =3D grub_nilfs2_btree_get_root(i= node); > + if(root->bn_flags & NILFS_BMAP_LARGE) > + return grub_nilfs2_btree_lookup(data, inode, key, need_translate);= > + else > + { > + grub_uint64_t ptr; > + ptr =3D grub_nilfs2_direct_lookup(inode, key); > + if(need_translate) > + ptr =3D grub_nilfs2_dat_translate(data, ptr); > + return ptr; > + }=20 > +} > + > +static grub_uint64_t > +grub_nilfs2_dat_translate(struct grub_nilfs2_data *data, grub_uint64_t= key) > +{ > + struct grub_nilfs2_dat_entry entry; > + grub_disk_t disk =3D data->disk; > + grub_uint64_t pptr; > + grub_uint32_t blockno, offset; > + unsigned int nilfs2_block_count =3D (1 << LOG2_NILFS2_BLOCK_SIZE(dat= a)); > + > + blockno =3D grub_nilfs2_palloc_entry_offset(data, key, > + sizeof(struct grub_nilfs2_dat_entry)); > + > + grub_divmod64(key * sizeof(struct grub_nilfs2_dat_entry), > + NILFS2_BLOCK_SIZE(data), &offset); > + > + pptr =3D grub_nilfs2_bmap_lookup(data, &data->sroot.sr_dat, blockno,= 0); > + if(pptr =3D=3D (grub_uint64_t)-1) { > + grub_error(GRUB_ERR_BAD_FS,"btree lookup failure"); > + return -1; > + }=20 > + > + grub_disk_read (disk, pptr * nilfs2_block_count, offset,=20 > + sizeof (struct grub_nilfs2_dat_entry), &entry); > + > + return grub_le_to_cpu64(entry.de_blocknr); > +} > + > + > +static grub_disk_addr_t > +grub_nilfs2_read_block (grub_fshelp_node_t node, grub_disk_addr_t file= block) > +{ > + struct grub_nilfs2_data *data =3D node->data; > + struct grub_nilfs2_inode *inode =3D &node->inode; > + grub_uint64_t pptr =3D -1; > + > + pptr =3D grub_nilfs2_bmap_lookup(data, inode, fileblock, 1); > + if(pptr =3D=3D (grub_uint64_t)-1) { > + grub_error(GRUB_ERR_BAD_FS,"btree lookup failure"); > + return -1; > + }=20 > + > + return pptr; > +} > + > +/* Read LEN bytes from the file described by DATA starting with byte > + POS. Return the amount of read bytes in READ. */ > +static grub_ssize_t > +grub_nilfs2_read_file (grub_fshelp_node_t node, > + void NESTED_FUNC_ATTR (*read_hook) (grub_disk_addr_t sector, > + unsigned offset, unsigned length), > + int pos, grub_size_t len, char *buf) > +{ > + return grub_fshelp_read_file (node->data->disk, node, read_hook, > + pos, len, buf, grub_nilfs2_read_block, > + grub_le_to_cpu64(node->inode.i_size), > + LOG2_NILFS2_BLOCK_SIZE (node->data)); > + > +} > + > +static grub_err_t > +grub_nilfs2_read_checkpoint(struct grub_nilfs2_data *data, > + grub_uint64_t cpno, > + struct grub_nilfs2_checkpoint *cpp) > +{ > + grub_uint64_t blockno; > + grub_uint32_t offset; > + grub_uint64_t pptr; > + grub_disk_t disk =3D data->disk; > + unsigned int nilfs2_block_count =3D (1 << LOG2_NILFS2_BLOCK_SIZE(dat= a)); > + > + /* assume sizeof(struct grub_nilfs2_cpfile_header) <=20 > + sizeof(struct grub_nilfs2_checkpoint) > + */ > + blockno =3D grub_divmod64(cpno, NILFS2_BLOCK_SIZE(data) / > + sizeof(struct grub_nilfs2_checkpoint) , &offset); > + > + pptr =3D grub_nilfs2_bmap_lookup(data ,&data->sroot.sr_cpfile, block= no, 1); > + if(pptr =3D=3D (grub_uint64_t)-1) { > + grub_error(GRUB_ERR_BAD_FS,"btree lookup failure"); > + return GRUB_ERR_BAD_FS; > + }=20 > + > + return grub_disk_read (disk, pptr * nilfs2_block_count, > + offset * sizeof(struct grub_nilfs2_checkpoint),=20 > + sizeof (struct grub_nilfs2_checkpoint), > + cpp); > +} > + > +static inline grub_err_t > +grub_nilfs2_read_last_checkpoint(struct grub_nilfs2_data *data, > + struct grub_nilfs2_checkpoint *cpp) > +{ > + return grub_nilfs2_read_checkpoint(data, > + grub_le_to_cpu64(data->sblock.s_last_cno), > + cpp); > +} > + > +/* Read the inode INO for the file described by DATA into INODE. */ > +static grub_err_t > +grub_nilfs2_read_inode (struct grub_nilfs2_data *data, > + grub_uint64_t ino, struct grub_nilfs2_inode *inodep) > +{ > + grub_uint64_t blockno; > + unsigned int offset; > + grub_uint64_t pptr; > + grub_disk_t disk =3D data->disk; > + unsigned int nilfs2_block_count =3D (1 << LOG2_NILFS2_BLOCK_SIZE(dat= a)); > + > + blockno =3D grub_nilfs2_palloc_entry_offset(data, ino,=20 > + sizeof(struct grub_nilfs2_inode)); > + > + grub_divmod64(sizeof(struct grub_nilfs2_inode) * ino, > + NILFS2_BLOCK_SIZE(data), &offset); > + pptr =3D grub_nilfs2_bmap_lookup(data ,&data->ifile, blockno, 1); > + if(pptr =3D=3D (grub_uint64_t)-1) { > + grub_error(GRUB_ERR_BAD_FS,"btree lookup failure"); > + return GRUB_ERR_BAD_FS; > + }=20 > + > + return grub_disk_read (disk, pptr * nilfs2_block_count, offset,=20 > + sizeof (struct grub_nilfs2_inode), > + inodep); > +} > + > +static int grub_nilfs2_valid_sb(struct grub_nilfs2_super_block *sbp) > +{ > + if (grub_le_to_cpu16 (sbp->s_magic) !=3D NILFS2_SUPER_MAGIC)=20 > + return 0; > + > + if (grub_le_to_cpu32 (sbp->s_rev_level) !=3D NILFS_SUPORT_REV)=20 > + return 0; > + > + return 1; > +} > + > +static struct grub_nilfs2_data * > +grub_nilfs2_mount (grub_disk_t disk) > +{ > + struct grub_nilfs2_data *data; > + struct grub_nilfs2_segment_summary ss; > + struct grub_nilfs2_checkpoint last_checkpoint; > + grub_uint64_t last_pseg; > + grub_uint32_t nblocks; > + unsigned int nilfs2_block_count; > + > + data =3D grub_malloc (sizeof (struct grub_nilfs2_data)); > + if (!data) > + return 0; > + > + /* Read the superblock. */ > + grub_disk_read (disk, 1 * 2, 0, sizeof (struct grub_nilfs2_super_blo= ck), > + &data->sblock); > + if (grub_errno) > + goto fail; > + > + /* Make sure this is an nilfs2 filesystem. */ > + if (!grub_nilfs2_valid_sb(&data->sblock)) > + { > + grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); > + goto fail; > + } > + > + nilfs2_block_count =3D (1 << LOG2_NILFS2_BLOCK_SIZE(data)); > + > + /* Read the last segment summary */ > + last_pseg =3D grub_le_to_cpu64(data->sblock.s_last_pseg); > + grub_disk_read (disk, last_pseg * nilfs2_block_count, 0, > + sizeof (struct grub_nilfs2_segment_summary), &ss); > + > + if (grub_errno) > + goto fail; > + > + /* Read the super root block */ > + nblocks =3D grub_le_to_cpu32(ss.ss_nblocks);=20 > + grub_disk_read (disk, (last_pseg + (nblocks -1)) * nilfs2_block_cou= nt, 0,=20 > + sizeof (struct grub_nilfs2_super_root), &data->sroot); > + > + if (grub_errno) > + goto fail; > + > + data->disk =3D disk; > + > + grub_nilfs2_read_last_checkpoint(data, &last_checkpoint); > + > + if (grub_errno) > + goto fail; > + > + grub_memcpy(&data->ifile, &last_checkpoint.cp_ifile_inode, > + sizeof(struct grub_nilfs2_inode)); > + > + data->diropen.data =3D data; > + data->diropen.ino =3D 2; > + data->diropen.inode_read =3D 1; > + data->inode =3D &data->diropen.inode; > + > + grub_nilfs2_read_inode(data, 2, data->inode); > + > + return data; > + > + fail: > + if (grub_errno =3D=3D GRUB_ERR_OUT_OF_RANGE) > + grub_error (GRUB_ERR_BAD_FS, "not a nilfs2 filesystem"); > + > + grub_free (data); > + return 0; > +} > + > +static char * > +grub_nilfs2_read_symlink (grub_fshelp_node_t node) > +{ > + char *symlink; > + struct grub_fshelp_node *diro =3D node; > + > + if (! diro->inode_read) > + { > + grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode); > + if (grub_errno) > + return 0; > + } > + > + symlink =3D grub_malloc (grub_le_to_cpu64 (diro->inode.i_size) + 1);= > + if (! symlink) > + return 0; > + > + grub_nilfs2_read_file (diro, 0, 0, > + grub_le_to_cpu64 (diro->inode.i_size), > + symlink); > + if (grub_errno) > + { > + grub_free (symlink); > + return 0; > + } > + > + symlink[grub_le_to_cpu64 (diro->inode.i_size)] =3D '\0'; > + return symlink; > +} > + > +static int > +grub_nilfs2_iterate_dir (grub_fshelp_node_t dir, > + int NESTED_FUNC_ATTR > + (*hook) (const char *filename, > + enum grub_fshelp_filetype filetype, > + grub_fshelp_node_t node)) > +{ > + unsigned int fpos =3D 0; > + struct grub_fshelp_node *diro =3D (struct grub_fshelp_node *) dir; > + > + if (! diro->inode_read) > + { > + grub_nilfs2_read_inode (diro->data, diro->ino, &diro->inode); > + if (grub_errno) > + return 0; > + } > + > + /* Iterate files. */ > + while (fpos < grub_le_to_cpu64 (diro->inode.i_size)) > + { > + struct grub_nilfs2_dir_entry dirent; > + > + grub_nilfs2_read_file (diro, 0, fpos, > + sizeof (struct grub_nilfs2_dir_entry), > + (char *) &dirent); > + if (grub_errno) > + return 0; > + > + if (dirent.rec_len =3D=3D 0) > + return 0; > + > + if (dirent.name_len !=3D 0) > + { > + char filename[dirent.name_len + 1]; > + struct grub_fshelp_node *fdiro; > + enum grub_fshelp_filetype type =3D GRUB_FSHELP_UNKNOWN; > + > + grub_nilfs2_read_file (diro, 0,=20 > + fpos + sizeof (struct grub_nilfs2_dir_entry), > + dirent.name_len, filename); > + if (grub_errno) > + return 0; > + > + fdiro =3D grub_malloc (sizeof (struct grub_fshelp_node)); > + if (! fdiro) > + return 0; > + > + fdiro->data =3D diro->data; > + fdiro->ino =3D grub_le_to_cpu64 (dirent.inode); > + > + filename[dirent.name_len] =3D '\0'; > + > + if (dirent.file_type !=3D NILFS_FT_UNKNOWN) > + { > + fdiro->inode_read =3D 0; > + > + if (dirent.file_type =3D=3D NILFS_FT_DIR) > + type =3D GRUB_FSHELP_DIR; > + else if (dirent.file_type =3D=3D NILFS_FT_SYMLINK) > + type =3D GRUB_FSHELP_SYMLINK; > + else if (dirent.file_type =3D=3D NILFS_FT_REG_FILE) > + type =3D GRUB_FSHELP_REG; > + } > + else > + { > + /* The filetype can not be read from the dirent, read > + the inode to get more information. */ > + grub_nilfs2_read_inode (diro->data, > + grub_le_to_cpu64 (dirent.inode), > + &fdiro->inode); > + if (grub_errno) > + { > + grub_free (fdiro); > + return 0; > + } > + > + fdiro->inode_read =3D 1; > + > + if ((grub_le_to_cpu16 (fdiro->inode.i_mode) > + & FILETYPE_INO_MASK) =3D=3D FILETYPE_INO_DIRECTORY) > + type =3D GRUB_FSHELP_DIR; > + else if ((grub_le_to_cpu16 (fdiro->inode.i_mode) > + & FILETYPE_INO_MASK) =3D=3D FILETYPE_INO_SYMLINK) > + type =3D GRUB_FSHELP_SYMLINK; > + else if ((grub_le_to_cpu16 (fdiro->inode.i_mode) > + & FILETYPE_INO_MASK) =3D=3D FILETYPE_INO_REG) > + type =3D GRUB_FSHELP_REG; > + } > + > + if (hook (filename, type, fdiro)) > + return 1; > + } > + > + fpos +=3D grub_le_to_cpu16 (dirent.rec_len); > + } > + > + return 0; > +} > + > +/* Open a file named NAME and initialize FILE. */ > +static grub_err_t > +grub_nilfs2_open (struct grub_file *file, const char *name) > +{ > + struct grub_nilfs2_data *data =3D NULL; > + struct grub_fshelp_node *fdiro =3D 0; > + > + grub_dl_ref (my_mod); > + > + data =3D grub_nilfs2_mount (file->device->disk); > + if (! data) > + goto fail; > + > + grub_fshelp_find_file (name, &data->diropen, &fdiro, grub_nilfs2_ite= rate_dir, > + grub_nilfs2_read_symlink, GRUB_FSHELP_REG); > + if (grub_errno) > + goto fail; > + > + if (! fdiro->inode_read) > + { > + grub_nilfs2_read_inode (data, fdiro->ino, &fdiro->inode); > + if (grub_errno) > + goto fail; > + } > + > + grub_memcpy (data->inode, &fdiro->inode, sizeof (struct grub_nilfs2_= inode)); > + grub_free (fdiro); > + > + file->size =3D grub_le_to_cpu64 (data->inode->i_size); > + file->data =3D data; > + file->offset =3D 0; > + > + return 0; > + > + fail: > + if (fdiro !=3D &data->diropen) > + grub_free (fdiro); > + grub_free (data); > + > + grub_dl_unref (my_mod); > + > + return grub_errno; > +} > + > +static grub_err_t > +grub_nilfs2_close (grub_file_t file) > +{ > + grub_free (file->data); > + > + grub_dl_unref (my_mod); > + > + return GRUB_ERR_NONE; > +} > + > +/* Read LEN bytes data from FILE into BUF. */ > +static grub_ssize_t > +grub_nilfs2_read (grub_file_t file, char *buf, grub_size_t len) > +{ > + struct grub_nilfs2_data *data =3D (struct grub_nilfs2_data *) file->= data; > + > + return grub_nilfs2_read_file (&data->diropen, file->read_hook, > + file->offset, len, buf); > +} > + > +static grub_err_t > +grub_nilfs2_dir (grub_device_t device, const char *path, > + int (*hook) (const char *filename, > + const struct grub_dirhook_info *info)) > +{ > + struct grub_nilfs2_data *data =3D 0; > + struct grub_fshelp_node *fdiro =3D 0; > + > + auto int NESTED_FUNC_ATTR iterate (const char *filename, > + enum grub_fshelp_filetype filetype, > + grub_fshelp_node_t node); > + > + int NESTED_FUNC_ATTR iterate (const char *filename, > + enum grub_fshelp_filetype filetype, > + grub_fshelp_node_t node) > + { > + struct grub_dirhook_info info; > + grub_memset (&info, 0, sizeof (info)); > + if (! node->inode_read) > + { > + grub_nilfs2_read_inode (data, node->ino, &node->inode); > + if (!grub_errno) > + node->inode_read =3D 1; > + grub_errno =3D GRUB_ERR_NONE; > + } > + if (node->inode_read) > + { > + info.mtimeset =3D 1; > + info.mtime =3D grub_le_to_cpu64 (node->inode.i_mtime); > + } > + > + info.dir =3D ((filetype & GRUB_FSHELP_TYPE_MASK) =3D=3D GRUB_FSH= ELP_DIR); > + grub_free (node); > + return hook (filename, &info); > + } > + > + grub_dl_ref (my_mod); > + > + data =3D grub_nilfs2_mount (device->disk); > + if (! data) > + goto fail; > + > + grub_fshelp_find_file (path, &data->diropen, &fdiro, grub_nilfs2_ite= rate_dir, > + grub_nilfs2_read_symlink, GRUB_FSHELP_DIR); > + if (grub_errno) > + goto fail; > + > + grub_nilfs2_iterate_dir (fdiro, iterate); > + > + fail: > + if (fdiro !=3D &data->diropen) > + grub_free (fdiro); > + grub_free (data); > + > + grub_dl_unref (my_mod); > + > + return grub_errno; > +} > + > +static grub_err_t > +grub_nilfs2_label (grub_device_t device, char **label) > +{ > + struct grub_nilfs2_data *data; > + grub_disk_t disk =3D device->disk; > + > + grub_dl_ref (my_mod); > + > + data =3D grub_nilfs2_mount (disk); > + if (data) > + *label =3D grub_strndup (data->sblock.s_volume_name, 14); > + else > + *label =3D NULL; > + > + grub_dl_unref (my_mod); > + > + grub_free (data); > + > + return grub_errno; > +} > + > +static grub_err_t > +grub_nilfs2_uuid (grub_device_t device, char **uuid) > +{ > + struct grub_nilfs2_data *data; > + grub_disk_t disk =3D device->disk; > + > + grub_dl_ref (my_mod); > + > + data =3D grub_nilfs2_mount (disk); > + if (data) > + { > + *uuid =3D grub_xasprintf ("%02x%02x%02x%02x-%02x%02x-%02x%02x-%0= 2x%0x-%02x%02x%02x%02x%02x%02x", > + data->sblock.s_uuid[0], data->sblock.s_uuid[1], > + data->sblock.s_uuid[2], data->sblock.s_uuid[3], > + data->sblock.s_uuid[4], data->sblock.s_uuid[5], > + data->sblock.s_uuid[6], data->sblock.s_uuid[7], > + data->sblock.s_uuid[8], data->sblock.s_uuid[9], > + data->sblock.s_uuid[10], data->sblock.s_uuid[11], > + data->sblock.s_uuid[12], data->sblock.s_uuid[13], > + data->sblock.s_uuid[14], data->sblock.s_uuid[15]); > + } > + else > + *uuid =3D NULL; > + > + grub_dl_unref (my_mod); > + > + grub_free (data); > + > + return grub_errno; > +} > + > +/* Get mtime. */ > +static grub_err_t > +grub_nilfs2_mtime (grub_device_t device, grub_int32_t *tm) > +{ > + struct grub_nilfs2_data *data; > + grub_disk_t disk =3D device->disk; > + > + grub_dl_ref (my_mod); > + > + data =3D grub_nilfs2_mount (disk); > + if (!data) > + *tm =3D 0; > + else > + *tm =3D (grub_int32_t)grub_le_to_cpu64 (data->sblock.s_mtime); > + > + grub_dl_unref (my_mod); > + > + grub_free (data); > + > + return grub_errno; > +} > + > + > +=0C > +static struct grub_fs grub_nilfs2_fs=3D > + { > + .name =3D "nilfs2", > + .dir =3D grub_nilfs2_dir, > + .open =3D grub_nilfs2_open, > + .read =3D grub_nilfs2_read, > + .close =3D grub_nilfs2_close, > + .label =3D grub_nilfs2_label, > + .uuid =3D grub_nilfs2_uuid, > + .mtime =3D grub_nilfs2_mtime, > +#ifdef GRUB_UTIL > + .reserved_first_sector =3D 1, > +#endif > + .next =3D 0 > + }; > + > +GRUB_MOD_INIT(nilfs2) > +{ > + grub_fs_register (&grub_nilfs2_fs); > + my_mod =3D mod; > +} > + > +GRUB_MOD_FINI(nilfs2) > +{ > + grub_fs_unregister (&grub_nilfs2_fs); > +} > > =3D=3D=3D modified file 'include/grub/misc.h' > --- include/grub/misc.h 2010-02-03 00:24:07 +0000 > +++ include/grub/misc.h 2010-02-18 13:57:40 +0000 > @@ -45,6 +45,7 @@ > ((addr + (typeof (addr)) align - 1) & ~((typeof (addr)) align - 1)) > #define ARRAY_SIZE(array) (sizeof (array) / sizeof (array[0])) > #define COMPILE_TIME_ASSERT(cond) switch (0) { case 1: case !(cond): ;= } > +#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d)) > =20 > #define grub_dprintf(condition, fmt, args...) grub_real_dprintf(__FILE= __, __LINE__, condition, fmt, ## args) > /* XXX: If grub_memmove is too slow, we must implement grub_memcpy. *= / > > > =20 > -----------------------------------------------------------------------= - > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > http://lists.gnu.org/mailman/listinfo/grub-devel > =20 --=20 Regards Vladimir '=CF=86-coder/phcoder' Serbinenko --------------enig14F53AFB8FD28BFC5EF70D0E Content-Type: application/pgp-signature; name="signature.asc" Content-Description: OpenPGP digital signature Content-Disposition: attachment; filename="signature.asc" -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iF4EAREKAAYFAkt/uzUACgkQNak7dOguQgmK6AD/QK7wcZ9Svb09mRpOrb/Z0tbl FSv7tDtXK5DZDm1U98gA/3xO/qE8Ck36uMl3UIxRnZaYX5tHk6B/ZfYXAUKDxt3r =wbdQ -----END PGP SIGNATURE----- --------------enig14F53AFB8FD28BFC5EF70D0E--