⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 reiserfslib.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 3 页
字号:
/* *  Copyright 2000-2004 by Hans Reiser, licensing governed by  *  reiserfsprogs/README */#define _GNU_SOURCE#include "includes.h"#include <linux/kdev_t.h>struct key root_dir_key = {0, 0, {{0, 0},}};struct key parent_root_dir_key = {0, 0, {{0, 0},}};struct key lost_found_dir_key = {0, 0, {{0, 0}, }};struct key badblock_key = {BADBLOCK_DIRID, BADBLOCK_OBJID, {{0, 0},}};__u16 root_dir_format = 0;__u16 lost_found_dir_format = 0;static void make_const_keys (void){    set_key_dirid (&root_dir_key, REISERFS_ROOT_PARENT_OBJECTID);    set_key_objectid (&root_dir_key, REISERFS_ROOT_OBJECTID);    set_key_dirid (&parent_root_dir_key, 0);    set_key_objectid (&parent_root_dir_key, REISERFS_ROOT_PARENT_OBJECTID);}/* reiserfs needs at least: enough blocks for journal, 64 k at the beginning,   one block for super block, bitmap block and root block. Note that first   bitmap block must point to all of them */int is_block_count_correct (unsigned long journal_offset, unsigned int block_size,    unsigned long block_count, unsigned long journal_size){    unsigned long blocks;    /* RESERVED, MD RAID SBs, super block, bitmap, root, journal size with journal header */    blocks = journal_offset + journal_size;    /* we have a limit: skipped area, super block, journal and root block    all have to be addressed by one first bitmap */    if (blocks > block_size * 8)    	return 0;    	    if (blocks > block_count)    	return 0;    	    return 1;}/* read super block. fixme: only 4k blocks, pre-journaled format   is refused. Journal and bitmap are to be opened separately.   skip_check is set to 1 if checks of openned SB should be omitted.*/reiserfs_filsys_t * reiserfs_open (char * filename, int flags, 				   int *error, void * vp, int check){    reiserfs_filsys_t * fs;    struct buffer_head * bh;    struct reiserfs_super_block * sb;    int fd, i;    /* convert root dir key and parent root dir key to little endian format */    make_const_keys ();    if (error) 	*error = 0;    fd = open (filename, flags #if defined(O_LARGEFILE)	       | O_LARGEFILE#endif	       );    if (fd == -1) {	if (error)	    *error = errno;	return 0;    }    fs = getmem (sizeof (*fs));    fs->fs_dev = fd;    fs->fs_vp = vp;    asprintf (&fs->fs_file_name, "%s", filename);        /* reiserfs super block is either in 16-th or in 2-nd 4k block of the       device */    for (i = 2; i < 17; i += 14) {	bh = bread (fd, i, 4096);	if (!bh) {	    reiserfs_warning (stderr, "reiserfs_open: bread failed reading block %d\n", i);	} else {	    sb = (struct reiserfs_super_block *)bh->b_data;	    	    if (is_any_reiserfs_magic_string(sb))		goto found;	    /* reiserfs signature is not found at the i-th 4k block */	    brelse (bh);	}    }    reiserfs_warning(stderr, 	"\nreiserfs_open: the reiserfs superblock cannot be found on %s.\n", filename);        freemem (fs);    close (fd);    fs = NULL;    return fs; found:    if (!is_blocksize_correct(get_sb_block_size(sb))) {	reiserfs_warning(stderr, "reiserfs_open: a superblock with wrong parameters "			 "was found in the block (%d).\n", i);	freemem (fs);	close (fd);	brelse(bh);	return NULL;    }    if (check) {	/* A few checks of found super block. */	struct buffer_head *tmp_bh;		tmp_bh = bread (fd, get_sb_block_count(sb) - 1, get_sb_block_size(sb));		if (!tmp_bh) {	    reiserfs_warning (stderr, "\n%s: Your partition is not big enough to contain the \n"		    "filesystem of (%lu) blocks as was specified in the found super block.\n", 		    __FUNCTION__,  get_sb_block_count(sb) - 1);	    	    freemem (fs);	    close (fd);	    brelse(bh);	    return NULL;	}		brelse(tmp_bh);    }       fs->fs_blocksize = get_sb_block_size (sb);        /* check block size on the filesystem */    if (fs->fs_blocksize != 4096) {	i = bh->b_blocknr * 4096 / fs->fs_blocksize;	brelse (bh);	bh = bread (fd, i, fs->fs_blocksize);	if (!bh) {	    reiserfs_warning (stderr, "reiserfs_open: bread failed reading block %d, size %d\n",			      i, fs->fs_blocksize);	    freemem (fs);	    return 0;	}	sb = (struct reiserfs_super_block *)bh->b_data;    }    fs->fs_hash_function = code2func (get_sb_hash_code (sb));    fs->fs_super_bh = bh;    fs->fs_ondisk_sb = sb;    fs->fs_flags = flags; /* O_RDONLY or O_RDWR */    fs->fs_format = get_reiserfs_format (sb);        /*reiserfs_read_bitmap_blocks(fs);*/    if (flags & O_RDWR)	fs->fs_dirt  = 1;    else	fs->fs_dirt = 0;    return fs;}/* creates buffer for super block and fills it up with fields which are   constant for given size and version of a filesystem */reiserfs_filsys_t * reiserfs_create (char * filename,				     int version,				     unsigned long block_count, 				     int block_size, 				     int default_journal, 				     int new_format){    reiserfs_filsys_t * fs;    /* convert root dir key and parent root dir key to little endian format */    make_const_keys ();    if (count_blocks (filename, block_size) < block_count) {	reiserfs_warning (stderr, "reiserfs_create: no enough blocks on device\n");	return 0;    }    if (!is_block_count_correct (REISERFS_DISK_OFFSET_IN_BYTES / block_size, 	block_size, block_count, 0))     {	reiserfs_warning (stderr, "reiserfs_create: can not create that small "	    "(%d blocks) filesystem\n", block_count);	return 0;    }    fs = getmem (sizeof (*fs));    if (!fs) {	reiserfs_warning (stderr, "reiserfs_create: getmem failed\n");	return 0;    }    fs->fs_dev = open (filename, O_RDWR #if defined(O_LARGEFILE)		       | O_LARGEFILE#endif		       );    if (fs->fs_dev == -1) {	reiserfs_warning (stderr, "reiserfs_create: could not open %s: %s\n",			  filename, strerror(errno));	freemem (fs);	return 0;    }    fs->fs_blocksize = block_size;    asprintf (&fs->fs_file_name, "%s", filename);    fs->fs_format = version;    if (new_format)        fs->fs_super_bh = getblk (fs->fs_dev, 	    REISERFS_DISK_OFFSET_IN_BYTES / block_size, block_size);    else         fs->fs_super_bh = getblk (fs->fs_dev, 	    REISERFS_OLD_DISK_OFFSET_IN_BYTES / block_size, block_size);        if (!fs->fs_super_bh) {	reiserfs_warning (stderr, "reiserfs_create: getblk failed\n");	return 0;    }    mark_buffer_uptodate (fs->fs_super_bh, 1);        fs->fs_ondisk_sb = (struct reiserfs_super_block *)fs->fs_super_bh->b_data;    memset (fs->fs_ondisk_sb, 0, block_size);        /* fill super block fields which are constant for given version and block count */    set_sb_block_count (fs->fs_ondisk_sb, block_count);    /* sb_free_blocks */    /* sb_root_block */    /* sb_journal_1st_block */    /* sb_journal_dev */    /* sb_orig_journal_size */    /* sb_joural_magic */    /* sb_journal magic_F */    /* sb_mount_id */    /* sb_not_used0 */    /* sb_generation_number */        set_sb_block_size (fs->fs_ondisk_sb, block_size);    switch (version) {    case REISERFS_FORMAT_3_5:	set_sb_oid_maxsize (fs->fs_ondisk_sb, 	    (block_size - SB_SIZE_V1) / sizeof(__u32) / 2 * 2);	/* sb_oid_cursize */	/* sb_state */	memcpy (fs->fs_ondisk_sb->s_v1.s_magic, REISERFS_3_5_SUPER_MAGIC_STRING,		strlen (REISERFS_3_5_SUPER_MAGIC_STRING));	break;    case REISERFS_FORMAT_3_6:	set_sb_oid_maxsize (fs->fs_ondisk_sb, 	    (block_size - SB_SIZE) / sizeof(__u32) / 2 * 2);	/* sb_oid_cursize */	/* sb_state */        memcpy (fs->fs_ondisk_sb->s_v1.s_magic, REISERFS_3_6_SUPER_MAGIC_STRING,                strlen (REISERFS_3_6_SUPER_MAGIC_STRING));	break;    }    if (!default_journal)        memcpy (fs->fs_ondisk_sb->s_v1.s_magic, REISERFS_JR_SUPER_MAGIC_STRING,                strlen (REISERFS_JR_SUPER_MAGIC_STRING));    /* sb_fsck_state */    /* sb_hash_function_code */    /* sb_tree_height */    set_sb_bmap_nr (fs->fs_ondisk_sb,		    (block_count + (block_size * 8 - 1)) / (block_size * 8));    set_sb_version (fs->fs_ondisk_sb, version);    /* sb_not_used1 */    mark_buffer_dirty (fs->fs_super_bh);    fs->fs_dirt = 1;    return fs;}int no_reiserfs_found (reiserfs_filsys_t * fs){    return (fs == NULL || fs->fs_blocksize == 0) ? 1 : 0;}int new_format (reiserfs_filsys_t * fs){    return fs->fs_super_bh->b_blocknr != 2;}int spread_bitmaps (reiserfs_filsys_t * fs){    return fs->fs_super_bh->b_blocknr != 2;}/* 0 means: do not guarantee that fs is consistent */int reiserfs_is_fs_consistent (reiserfs_filsys_t * fs){    if (get_sb_umount_state (fs->fs_ondisk_sb) == FS_CLEANLY_UMOUNTED &&	get_sb_fs_state (fs->fs_ondisk_sb) == FS_CONSISTENT)	return 1;    return 0;}/* flush bitmap, brelse super block, flush all dirty buffers, close and open   again the device, read super block */static void reiserfs_only_reopen (reiserfs_filsys_t * fs, int flag){    unsigned long super_block;    /*  reiserfs_flush_to_ondisk_bitmap (fs->fs_bitmap2, fs);*/    super_block = fs->fs_super_bh->b_blocknr;                    brelse (fs->fs_super_bh);    flush_buffers (fs->fs_dev);        invalidate_buffers (fs->fs_dev);    if (close (fs->fs_dev))	die ("reiserfs_reopen: closed failed: %s", strerror(errno));        fs->fs_dev = open (fs->fs_file_name, flag #if defined(O_LARGEFILE)		       | O_LARGEFILE#endif		       );    if (fs->fs_dev == -1)	die ("reiserfs_reopen: could not reopen device: %s", strerror(errno));    fs->fs_super_bh = bread (fs->fs_dev, super_block, fs->fs_blocksize);    if (!fs->fs_super_bh)	die ("reiserfs_reopen: reading super block failed");    fs->fs_ondisk_sb = (struct reiserfs_super_block *)fs->fs_super_bh->b_data;    fs->fs_flags = flag; /* O_RDONLY or O_RDWR */        if (flag & O_RDWR)	fs->fs_dirt  = 1;    else	fs->fs_dirt = 0;}void reiserfs_reopen (reiserfs_filsys_t * fs, int flag){    reiserfs_only_reopen (fs, flag);    reiserfs_reopen_journal (fs, flag);}int is_opened_rw (reiserfs_filsys_t * fs){    if ((fs->fs_flags) & O_RDWR)	return 1;    return 0;}/* flush all changes made on a filesystem */void reiserfs_flush (reiserfs_filsys_t * fs){    if (fs->fs_dirt) {	reiserfs_flush_journal (fs);	flush_buffers (fs->fs_dev);    }    fs->fs_dirt = 0;}/* free all memory involved into manipulating with filesystem */void reiserfs_free (reiserfs_filsys_t * fs){    reiserfs_free_journal (fs);    reiserfs_free_ondisk_bitmap (fs);    /* release super block and memory used by filesystem handler */    brelse (fs->fs_super_bh);    fs->fs_super_bh = 0;    free_buffers ();    free (fs->fs_file_name);    fs->fs_file_name = 0;    freemem (fs);}/* this closes everything: journal. bitmap and the fs itself */void reiserfs_close (reiserfs_filsys_t * fs){    reiserfs_close_journal (fs);    reiserfs_close_ondisk_bitmap (fs);    reiserfs_flush (fs);    reiserfs_free (fs);    fsync(fs->fs_dev);}int reiserfs_new_blocknrs (reiserfs_filsys_t * fs, 			   unsigned long * free_blocknrs, 			   unsigned long start, 			   int amount_needed){    if (fs->block_allocator)	return fs->block_allocator (fs, free_blocknrs, start, amount_needed);    die ("block allocator is not defined\n");    return 0;}int reiserfs_free_block (reiserfs_filsys_t * fs, unsigned long block){    if (fs->block_deallocator)	return fs->block_deallocator (fs, block);    die ("block deallocator is not defined\n");    return 0;}static int reiserfs_search_by_key_x (reiserfs_filsys_t * fs, struct key * key,				     struct path * path, int key_length){    struct buffer_head * bh;       unsigned long block;    struct path_element * curr;    int retval;        block = get_sb_root_block (fs->fs_ondisk_sb);    if (not_data_block(fs, block))	return IO_ERROR;        path->path_length = ILLEGAL_PATH_ELEMENT_OFFSET;    while (1) {	curr = PATH_OFFSET_PELEMENT (path, ++ path->path_length);	bh = curr->pe_buffer = bread (fs->fs_dev, block, fs->fs_blocksize);        if (bh == 0) {	    path->path_length --;	    pathrelse (path);	    return ITEM_NOT_FOUND;	}	retval = reiserfs_bin_search (key, B_N_PKEY (bh, 0), B_NR_ITEMS (bh),				      is_leaf_node (bh) ? IH_SIZE : KEY_SIZE,				      &(curr->pe_position), key_length == 4 ? comp_keys : comp_keys_3);	if (retval == POSITION_FOUND) {	    /* key found, return if this is leaf level */	    if (is_leaf_node (bh)) {		path->pos_in_item = 0;		return ITEM_FOUND;	    }	    curr->pe_position ++;	} else {	    /* key not found in the node */	    if (is_leaf_node (bh))		return ITEM_NOT_FOUND;	}	block = get_dc_child_blocknr (B_N_CHILD (bh, curr->pe_position));	if (not_data_block(fs, block))		return IO_ERROR;    }    printf ("search_by_key: you can not get here\n");    return ITEM_NOT_FOUND;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -