📄 super.c
字号:
reiserfs_proc_unregister( s, "per-level" ); reiserfs_proc_unregister( s, "super" ); reiserfs_proc_unregister( s, "version" ); reiserfs_proc_info_done( s ); return;}/* we don't mark inodes dirty, we just log them */static void reiserfs_dirty_inode (struct inode * inode) { struct reiserfs_transaction_handle th ; if (inode->i_sb->s_flags & MS_RDONLY) { reiserfs_warning("clm-6006: writing inode %lu on readonly FS\n", inode->i_ino) ; return ; } lock_kernel() ; /* this is really only used for atime updates, so they don't have ** to be included in O_SYNC or fsync */ journal_begin(&th, inode->i_sb, 1) ; reiserfs_update_sd (&th, inode); journal_end(&th, inode->i_sb, 1) ; unlock_kernel() ;}struct super_operations reiserfs_sops = { read_inode: reiserfs_read_inode, read_inode2: reiserfs_read_inode2, write_inode: reiserfs_write_inode, dirty_inode: reiserfs_dirty_inode, delete_inode: reiserfs_delete_inode, put_super: reiserfs_put_super, write_super: reiserfs_write_super, write_super_lockfs: reiserfs_write_super_lockfs, unlockfs: reiserfs_unlockfs, statfs: reiserfs_statfs, remount_fs: reiserfs_remount, fh_to_dentry: reiserfs_fh_to_dentry, dentry_to_fh: reiserfs_dentry_to_fh,};/* this was (ext2)parse_options */static int parse_options (char * options, unsigned long * mount_options, unsigned long * blocks){ char * this_char; char * value; *blocks = 0; if (!options) /* use default configuration: create tails, journaling on, no conversion to newest format */ return 1; for (this_char = strtok (options, ","); this_char != NULL; this_char = strtok (NULL, ",")) { if ((value = strchr (this_char, '=')) != NULL) *value++ = 0; if (!strcmp (this_char, "notail")) { set_bit (NOTAIL, mount_options); } else if (!strcmp (this_char, "conv")) { // if this is set, we update super block such that // the partition will not be mounable by 3.5.x anymore set_bit (REISERFS_CONVERT, mount_options); } else if (!strcmp (this_char, "noborder")) { /* this is used for benchmarking experimental variations, it is not intended for users to use, only for developers who want to casually hack in something to test */ set_bit (REISERFS_NO_BORDER, mount_options); } else if (!strcmp (this_char, "no_unhashed_relocation")) { set_bit (REISERFS_NO_UNHASHED_RELOCATION, mount_options); } else if (!strcmp (this_char, "hashed_relocation")) { set_bit (REISERFS_HASHED_RELOCATION, mount_options); } else if (!strcmp (this_char, "test4")) { set_bit (REISERFS_TEST4, mount_options); } else if (!strcmp (this_char, "nolog")) { reiserfs_warning("reiserfs: nolog mount option not supported yet\n"); } else if (!strcmp (this_char, "replayonly")) { set_bit (REPLAYONLY, mount_options); } else if (!strcmp (this_char, "resize")) { if (value && *value){ *blocks = simple_strtoul (value, &value, 0); } else { printk("reiserfs: resize option requires a value\n"); return 0; } } else if (!strcmp (this_char, "hash")) { if (value && *value) { /* if they specify any hash option, we force detection ** to make sure they aren't using the wrong hash */ if (!strcmp(value, "rupasov")) { set_bit (FORCE_RUPASOV_HASH, mount_options); set_bit (FORCE_HASH_DETECT, mount_options); } else if (!strcmp(value, "tea")) { set_bit (FORCE_TEA_HASH, mount_options); set_bit (FORCE_HASH_DETECT, mount_options); } else if (!strcmp(value, "r5")) { set_bit (FORCE_R5_HASH, mount_options); set_bit (FORCE_HASH_DETECT, mount_options); } else if (!strcmp(value, "detect")) { set_bit (FORCE_HASH_DETECT, mount_options); } else { printk("reiserfs: invalid hash function specified\n") ; return 0 ; } } else { printk("reiserfs: hash option requires a value\n"); return 0 ; } } else { printk ("reiserfs: Unrecognized mount option %s\n", this_char); return 0; } } return 1;}int reiserfs_is_super(struct super_block *s) { return (s->s_dev != 0 && s->s_op == &reiserfs_sops) ;}//// a portion of this function, particularly the VFS interface portion,// was derived from minix or ext2's analog and evolved as the// prototype did. You should be able to tell which portion by looking// at the ext2 code and comparing. It's subfunctions contain no code// used as a template unless they are so labeled.//static int reiserfs_remount (struct super_block * s, int * flags, char * data){ struct reiserfs_super_block * rs; struct reiserfs_transaction_handle th ; unsigned long blocks; unsigned long mount_options; rs = SB_DISK_SUPER_BLOCK (s); if (!parse_options(data, &mount_options, &blocks)) return 0; if(blocks) { int rc = reiserfs_resize(s, blocks); if (rc != 0) return rc; } if ((unsigned long)(*flags & MS_RDONLY) == (s->s_flags & MS_RDONLY)) { /* there is nothing to do to remount read-only fs as read-only fs */ return 0; } if (*flags & MS_RDONLY) { /* try to remount file system with read-only permissions */ if (sb_state(rs) == REISERFS_VALID_FS || s->u.reiserfs_sb.s_mount_state != REISERFS_VALID_FS) { return 0; } journal_begin(&th, s, 10) ; /* Mounting a rw partition read-only. */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ; set_sb_state( rs, s->u.reiserfs_sb.s_mount_state ); journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s)); s->s_dirt = 0; } else { s->u.reiserfs_sb.s_mount_state = sb_state(rs) ; s->s_flags &= ~MS_RDONLY ; /* now it is safe to call journal_begin */ journal_begin(&th, s, 10) ; /* Mount a partition which is read-only, read-write */ reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ; s->u.reiserfs_sb.s_mount_state = sb_state(rs); s->s_flags &= ~MS_RDONLY; set_sb_state( rs, REISERFS_ERROR_FS ); /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */ journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s)); s->s_dirt = 0; s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ; } /* this will force a full flush of all journal lists */ SB_JOURNAL(s)->j_must_wait = 1 ; journal_end(&th, s, 10) ; if (!( *flags & MS_RDONLY ) ) finish_unfinished( s ); return 0;}static int read_bitmaps (struct super_block * s){ int i, bmp, dl ; struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s); SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * sb_bmap_nr(rs), GFP_NOFS, s); if (SB_AP_BITMAP (s) == 0) return 1; memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * sb_bmap_nr(rs)); /* reiserfs leaves the first 64k unused so that any partition labeling scheme currently used will have enough space. Then we need one block for the super. -Hans */ bmp = (REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */ SB_AP_BITMAP (s)[0] = reiserfs_bread (s, bmp, s->s_blocksize); if(!SB_AP_BITMAP(s)[0]) return 1; for (i = 1, bmp = dl = s->s_blocksize * 8; i < sb_bmap_nr(rs); i ++) { SB_AP_BITMAP (s)[i] = reiserfs_bread (s, bmp, s->s_blocksize); if (!SB_AP_BITMAP (s)[i]) return 1; bmp += dl; } return 0;}static int read_old_bitmaps (struct super_block * s){ int i ; struct reiserfs_super_block * rs = SB_DISK_SUPER_BLOCK(s); int bmp1 = (REISERFS_OLD_DISK_OFFSET_IN_BYTES / s->s_blocksize) + 1; /* first of bitmap blocks */ /* read true bitmap */ SB_AP_BITMAP (s) = reiserfs_kmalloc (sizeof (struct buffer_head *) * sb_bmap_nr(rs), GFP_NOFS, s); if (SB_AP_BITMAP (s) == 0) return 1; memset (SB_AP_BITMAP (s), 0, sizeof (struct buffer_head *) * sb_bmap_nr(rs)); for (i = 0; i < sb_bmap_nr(rs); i ++) { SB_AP_BITMAP (s)[i] = reiserfs_bread (s, bmp1 + i, s->s_blocksize); if (!SB_AP_BITMAP (s)[i]) return 1; } return 0;}void check_bitmap (struct super_block * s){ int i = 0; int free = 0; char * buf; while (i < SB_BLOCK_COUNT (s)) { buf = SB_AP_BITMAP (s)[i / (s->s_blocksize * 8)]->b_data; if (!reiserfs_test_le_bit (i % (s->s_blocksize * 8), buf)) free ++; i ++; } if (free != SB_FREE_BLOCKS (s)) reiserfs_warning ("vs-4000: check_bitmap: %d free blocks, must be %d\n", free, SB_FREE_BLOCKS (s));}static int read_super_block (struct super_block * s, int size, int offset){ struct buffer_head * bh; struct reiserfs_super_block * rs; bh = bread (s->s_dev, offset / size, size); if (!bh) { printk ("read_super_block: " "bread failed (dev %s, block %d, size %d)\n", kdevname (s->s_dev), offset / size, size); return 1; } rs = (struct reiserfs_super_block *)bh->b_data; if (!is_reiserfs_magic_string (rs)) { printk ("read_super_block: " "can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n", kdevname(s->s_dev), bh->b_blocknr, size); brelse (bh); return 1; } // // ok, reiserfs signature (old or new) found in at the given offset // s->s_blocksize = sb_blocksize(rs); s->s_blocksize_bits = 0; while ((1 << s->s_blocksize_bits) != s->s_blocksize) s->s_blocksize_bits ++; brelse (bh); if (s->s_blocksize != size) set_blocksize (s->s_dev, s->s_blocksize); bh = reiserfs_bread (s, offset / s->s_blocksize, s->s_blocksize); if (!bh) { printk("read_super_block: " "bread failed (dev %s, block %d, size %d)\n", kdevname (s->s_dev), offset / size, size); return 1; } rs = (struct reiserfs_super_block *)bh->b_data; if (!is_reiserfs_magic_string (rs) || sb_blocksize(rs) != s->s_blocksize) { printk ("read_super_block: " "can't find a reiserfs filesystem on (dev %s, block %lu, size %d)\n", kdevname(s->s_dev), bh->b_blocknr, size); brelse (bh); printk ("read_super_block: can't find a reiserfs filesystem on dev %s.\n", kdevname(s->s_dev)); return 1; } /* must check to be sure we haven't pulled an old format super out ** of the old format's log. This is a kludge of a check, but it ** will work. If block we've just read in is inside the ** journal for that super, it can't be valid. */ if (bh->b_blocknr >= sb_journal_block(rs) && bh->b_blocknr < (sb_journal_block(rs) + JOURNAL_BLOCK_COUNT)) { brelse(bh) ; printk("super-459: read_super_block: " "super found at block %lu is within its own log. " "It must not be of this format type.\n", bh->b_blocknr) ; return 1 ; } SB_BUFFER_WITH_SB (s) = bh; SB_DISK_SUPER_BLOCK (s) = rs; s->s_op = &reiserfs_sops; /* new format is limited by the 32 bit wide i_blocks field, want to ** be one full block below that. */ s->s_maxbytes = (512LL << 32) - s->s_blocksize ; return 0;}/* after journal replay, reread all bitmap and super blocks */static int reread_meta_blocks(struct super_block *s) { int i ; ll_rw_block(READ, 1, &(SB_BUFFER_WITH_SB(s))) ; wait_on_buffer(SB_BUFFER_WITH_SB(s)) ; if (!buffer_uptodate(SB_BUFFER_WITH_SB(s))) { printk("reread_meta_blocks, error reading the super\n") ; return 1 ; } for (i = 0; i < SB_BMAP_NR(s) ; i++) { ll_rw_block(READ, 1, &(SB_AP_BITMAP(s)[i])) ; wait_on_buffer(SB_AP_BITMAP(s)[i]) ; if (!buffer_uptodate(SB_AP_BITMAP(s)[i])) { printk("reread_meta_blocks, error reading bitmap block number %d at %ld\n", i, SB_AP_BITMAP(s)[i]->b_blocknr) ; return 1 ; } } return 0 ;}/////////////////////////////////////////////////////// hash detection stuff// if root directory is empty - we set default - Yura's - hash and// warn about it// FIXME: we look for only one name in a directory. If tea and yura// bith have the same value - we ask user to send report to the// mailing list__u32 find_hash_out (struct super_block * s)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -