📄 mkreiserfs.c
字号:
/* * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README *//* mkreiserfs is very simple. It skips first 64k of device, and then writes the super block, the needed amount of bitmap blocks (this amount is calculated based on file system size), and root block. Bitmap policy is primitive: it assumes, that device does not have unreadable blocks, and it occupies first blocks for super, bitmap and root blocks. bitmap blocks are interleaved across the disk, mainly to make resizing faster. */#define _GNU_SOURCE#ifndef HAVE_CONFIG_H# include "config.h"#endif#include "io.h"#include "misc.h"#include "reiserfs_lib.h"#include "../version.h"#include <getopt.h>#include <stdarg.h>#include <string.h>#include <errno.h>#include <sys/utsname.h>#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H)# include <uuid/uuid.h>#endifchar *program_name;static void message( const char * fmt, ... ) __attribute__ ((format (printf, 1, 2)));static void message( const char * fmt, ... ) { char *buf; va_list args; buf = NULL; va_start( args, fmt ); vasprintf( &buf, fmt, args ); va_end( args ); if( buf ) { fprintf( stderr, "%s: %s\n", program_name, buf ); free( buf ); }}static void print_usage_and_exit(void){ fprintf(stderr, "Usage: %s [options] " " device [block-count]\n" "\n" "Options:\n\n" " -b | --block-size N size of file-system block, in bytes\n" " -j | --journal-device FILE path to separate device to hold journal\n" " -s | --journal-size N size of the journal in blocks\n" " -o | --journal-offset N offset of the journal from the start of\n" " the separate device, in blocks\n" " -t | --transaction-max-size N maximal size of transaction, in blocks\n" " -B | --badblocks file store all bad blocks given in file on the fs\n" " -h | --hash rupasov|tea|r5 hash function to use by default\n" " -u | --uuid UUID store UUID in the superblock\n" " -l | --label LABEL store LABEL in the superblock\n" " --format 3.5|3.6 old 3.5 format or newer 3.6\n" " -f | --force specified once, make mkreiserfs the whole\n" " disk, not block device or mounted partition;\n" " specified twice, do not ask for confirmation\n" " -q | --quiet quiet work without messages, progress and\n" " questions. Useful if run in a script. For use\n" " by end users only.\n" " -d | --debug print debugging information during mkreiser\n" " -V print version and exit\n", program_name); exit (1);}int Create_default_journal = 1;int Block_size = 4096;/* size of journal + 1 block for journal header */unsigned long Journal_size = 0;int Max_trans_size = 0; //JOURNAL_TRANS_MAX;int Hash = DEFAULT_HASH;int Offset = 0;char * Format;unsigned char UUID[16];unsigned char * LABEL = NULL;char * badblocks_file;enum mkfs_mode { DEBUG_MODE = 1 << 0, QUIET_MODE = 1 << 1, DO_NOTHING = 1 << 2};int mode;/* form super block (old one) */static void make_super_block (reiserfs_filsys_t * fs){ set_sb_umount_state (fs->fs_ondisk_sb, FS_CLEANLY_UMOUNTED); set_sb_tree_height (fs->fs_ondisk_sb, 2); set_sb_hash_code (fs->fs_ondisk_sb, Hash); if (fs->fs_format == REISERFS_FORMAT_3_6) {#if defined(HAVE_LIBUUID) && defined(HAVE_UUID_UUID_H) if (uuid_is_null(UUID)) uuid_generate(UUID); memcpy (fs->fs_ondisk_sb->s_uuid, UUID, 16);#endif if (LABEL != NULL) { if (strlen (LABEL) > 16) reiserfs_warning (stderr, "\nSpecified LABEL is longer then 16 " "characters, will be truncated\n\n"); strncpy (fs->fs_ondisk_sb->s_label, LABEL, 16); } set_sb_v2_flag (fs->fs_ondisk_sb, reiserfs_attrs_cleared); } if (!is_reiserfs_jr_magic_string (fs->fs_ondisk_sb) || strcmp (fs->fs_file_name, fs->fs_j_file_name)) /* either standard journal (and we leave all new fields to be 0) or journal is created on separate device so there is no space on data device which can be used as a journal */ set_sb_reserved_for_journal (fs->fs_ondisk_sb, 0); else set_sb_reserved_for_journal (fs->fs_ondisk_sb, get_jp_journal_size (sb_jp (fs->fs_ondisk_sb)) + 1); if (fs->fs_badblocks_bm) set_sb_free_blocks(fs->fs_ondisk_sb, get_sb_free_blocks(fs->fs_ondisk_sb) - fs->fs_badblocks_bm->bm_set_bits);}/* wipe out first 64 k of a device and both possible reiserfs super block */static void invalidate_other_formats (int dev){ struct buffer_head * bh; bh = bread (dev, 0, 64 * 1024); if (!bh) { reiserfs_exit(1, "Unable to read first blocks of the device"); }#if defined(__sparc__) || defined(__sparc_v9__) memset (bh->b_data + 1024, 0, bh->b_size - 1024);#else memset (bh->b_data, 0, bh->b_size);#endif mark_buffer_uptodate (bh, 1); mark_buffer_dirty (bh); bwrite (bh); brelse (bh);}void zero_journal (reiserfs_filsys_t * fs){ unsigned long start, len, done; struct buffer_head * bh; unsigned int i; fprintf (stdout, "Initializing journal - "); start = get_jp_journal_1st_block (sb_jp (fs->fs_ondisk_sb)); len = get_jp_journal_size (sb_jp (fs->fs_ondisk_sb)); done = 0; for (i = 0; i < len; i ++) { print_how_far (stdout, &done, len, 1, 1/*be quiet*/); bh = getblk (fs->fs_journal_dev, start + i, fs->fs_blocksize); if (!bh) { reiserfs_exit(1, "zero_journal: getblk failed"); } memset (bh->b_data, 0, bh->b_size); mark_buffer_dirty (bh); mark_buffer_uptodate (bh, 1); bwrite (bh); brelse (bh); } fprintf (stdout, "\n"); fflush (stdout);}/* this only sets few first bits in bitmap block. Fills not initialized fields of super block (root block and bitmap block numbers) */static void make_bitmap (reiserfs_filsys_t * fs) { struct reiserfs_super_block * sb = fs->fs_ondisk_sb; unsigned int i; unsigned long block; int marked; marked = 0; /* mark skipped area and super block */ for (i = 0; i <= fs->fs_super_bh->b_blocknr; i ++) { reiserfs_bitmap_set_bit (fs->fs_bitmap2, i); marked ++; } if (fs->fs_badblocks_bm) { for (i = 0; i < get_sb_block_count (sb); i ++) { if (reiserfs_bitmap_test_bit (fs->fs_badblocks_bm, i)) { reiserfs_bitmap_set_bit (fs->fs_bitmap2, i); marked ++; } } } /* mark bitmaps as used */ block = fs->fs_super_bh->b_blocknr + 1; for (i = 0; i < get_sb_bmap_nr (sb); i ++) { reiserfs_bitmap_set_bit (fs->fs_bitmap2, block); marked ++; if (spread_bitmaps (fs)) block = (block / (fs->fs_blocksize * 8) + 1) * (fs->fs_blocksize * 8); else block ++; } if (!get_size_of_journal_or_reserved_area (fs->fs_ondisk_sb)) /* root block follows directly super block and first bitmap */ block = fs->fs_super_bh->b_blocknr + 1 + 1; else { /* makr journal blocks as used */ for (i = 0; i <= get_jp_journal_size (sb_jp (sb)); i ++) { reiserfs_bitmap_set_bit (fs->fs_bitmap2, i + get_jp_journal_1st_block (sb_jp (sb))); marked ++; } block = get_jp_journal_1st_block (sb_jp (sb)) + i; } /*get correct block - not journal nor bitmap*/ while (block_of_journal (fs, block) || block_of_bitmap (fs, block)) { block++; } while ((block < get_sb_block_count (sb)) && reiserfs_bitmap_test_bit (fs->fs_bitmap2, block)) { block++; } if (block >= get_sb_block_count (sb)) reiserfs_exit(1, "mkreiserfs: too many bad blocks"); reiserfs_bitmap_set_bit (fs->fs_bitmap2, block); marked ++; set_sb_root_block (sb, block); set_sb_free_blocks (sb, get_sb_block_count (sb) - marked);}static void set_root_dir_nlink (struct item_head * ih, void * sd){ __u32 nlink; nlink = 3; set_sd_nlink (ih, sd, &nlink);}/* form the root block of the tree (the block head, the item head, the root directory) */static void make_root_block (reiserfs_filsys_t * fs){ struct reiserfs_super_block * sb; struct buffer_head * bh; sb = fs->fs_ondisk_sb; /* get memory for root block */ bh = getblk (fs->fs_dev, get_sb_root_block (sb), get_sb_block_size (sb)); if (!bh) { reiserfs_exit(1, "getblk failed"); } mark_buffer_uptodate (bh, 1); make_empty_leaf (bh); make_sure_root_dir_exists (fs, set_root_dir_nlink, 0); brelse (bh); mark_objectid_used (fs, REISERFS_ROOT_PARENT_OBJECTID); mark_objectid_used (fs, REISERFS_ROOT_OBJECTID);}static void report (reiserfs_filsys_t * fs, char * j_filename){// print_block (stdout, fs, fs->fs_super_bh); struct reiserfs_super_block * sb = (struct reiserfs_super_block *)(fs->fs_super_bh->b_data); struct stat st; dev_t rdev; if (!is_any_reiserfs_magic_string (sb)) return; if (fstat (fs->fs_super_bh->b_dev, &st) == -1) { /*reiserfs_warning (stderr, "fstat failed: %s\n", strerror(errno));*/ rdev = 0; } else rdev = st.st_rdev; if (mode & DEBUG_MODE) { reiserfs_warning (stdout, "Block %lu (0x%x) contains super block. ", fs->fs_super_bh->b_blocknr, rdev); } switch (get_reiserfs_format (sb)) { case REISERFS_FORMAT_3_5: reiserfs_warning (stdout, " Format 3.5 with "); break; case REISERFS_FORMAT_3_6: reiserfs_warning (stdout, "Format 3.6 with "); break; } if (is_reiserfs_jr_magic_string (sb)) reiserfs_warning (stdout, "non-"); reiserfs_warning (stdout, "standard journal\n"); reiserfs_warning (stdout, "Count of blocks on the device: %u\n", get_sb_block_count (sb)); reiserfs_warning (stdout, "Number of blocks consumed by mkreiserfs " "formatting process: %u\n", get_sb_block_count (sb) - get_sb_free_blocks (sb)); if (mode & DEBUG_MODE) reiserfs_warning (stdout, "Free blocks: %u\n", get_sb_free_blocks (sb)); reiserfs_warning (stdout, "Blocksize: %d\n", get_sb_block_size (sb)); reiserfs_warning (stdout, "Hash function used to sort names: %s\n", code2name (get_sb_hash_code (sb))); if (mode & DEBUG_MODE) { reiserfs_warning (stdout, "Number of bitmaps: %u\n", get_sb_bmap_nr (sb)); reiserfs_warning (stdout, "Root block: %u\n", get_sb_root_block (sb)); reiserfs_warning (stdout, "Tree height: %d\n", get_sb_tree_height (sb)); reiserfs_warning (stdout, "Objectid map size %d, max %d\n", get_sb_oid_cursize (sb), get_sb_oid_maxsize (sb)); reiserfs_warning (stdout, "Journal parameters:\n"); print_journal_params (stdout, sb_jp (sb)); } else { if (j_filename && strcmp (j_filename, fs->fs_file_name)) reiserfs_warning (stdout, "Journal Device [0x%x]\n", get_jp_journal_dev (sb_jp (sb))); reiserfs_warning (stdout, "Journal Size %u blocks (first block %u)\n", get_jp_journal_size (sb_jp (sb)) + 1, get_jp_journal_1st_block (sb_jp (sb))); reiserfs_warning (stdout, "Journal Max transaction length %u\n", get_jp_journal_max_trans_len (sb_jp (sb))); } if (j_filename && strcmp (j_filename, fs->fs_file_name)) { reiserfs_warning (stdout, "Space on this device reserved by journal: " "%u\n", get_sb_reserved_for_journal (sb)); } if (mode & DEBUG_MODE) { reiserfs_warning (stdout, "Filesystem state 0x%x\n", get_sb_fs_state (sb)); reiserfs_warning (stdout, "sb_version %u\n", get_sb_version (sb)); } if (get_reiserfs_format (sb) == REISERFS_FORMAT_3_6) { reiserfs_warning (stdout, "inode generation number: %u\n", get_sb_v2_inode_generation (sb)); reiserfs_warning (stdout, "UUID: %U\n", sb->s_uuid); if (strcmp (sb->s_label, "")) reiserfs_warning (stdout, "LABEL: %s\n", sb->s_label);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -