// // 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; }
/* return 1 if this is not super block */ static int print_super_block (struct buffer_head * bh) { struct reiserfs_super_block * rs = (struct reiserfs_super_block *)(bh->b_data); int skipped, data_blocks; char *version; if (strncmp (rs->s_magic, REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING)) == 0) { version = "3.5"; } else if( strncmp (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, strlen ( REISER2FS_SUPER_MAGIC_STRING)) == 0) { version = "3.6"; } else { return 1; } printk ("%s\'s super block in block %ld\n======================\n", kdevname (bh->b_dev), bh->b_blocknr); printk ("Reiserfs version %s\n", version ); printk ("Block count %u\n", sb_block_count(rs)); printk ("Blocksize %d\n", sb_blocksize(rs)); printk ("Free blocks %u\n", sb_free_blocks(rs)); // FIXME: this would be confusing if // someone stores reiserfs super block in some data block ;) // skipped = (bh->b_blocknr * bh->b_size) / sb_blocksize(rs); skipped = bh->b_blocknr; data_blocks = sb_block_count(rs) - skipped - 1 - sb_bmap_nr(rs) - (sb_orig_journal_size(rs) + 1) - sb_free_blocks(rs); printk ("Busy blocks (skipped %d, bitmaps - %d, journal blocks - %d\n" "1 super blocks, %d data blocks\n", skipped, sb_bmap_nr(rs), (sb_orig_journal_size(rs) + 1), data_blocks); printk ("Root block %u\n", sb_root_block(rs)); printk ("Journal block (first) %d\n", sb_journal_block(rs)); printk ("Journal dev %d\n", sb_journal_dev(rs)); printk ("Journal orig size %d\n", sb_orig_journal_size(rs)); printk ("Filesystem state %s\n", (sb_state(rs) == REISERFS_VALID_FS) ? "VALID" : "ERROR"); printk ("Hash function \"%s\"\n", sb_hash_function_code(rs) == TEA_HASH ? "tea" : ( sb_hash_function_code(rs) == YURA_HASH ? "rupasov" : (sb_hash_function_code(rs) == R5_HASH ? "r5" : "unknown"))); printk ("Tree height %d\n", sb_tree_height(rs)); return 0; }
// // 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 = 0; #ifdef CONFIG_REISERFS_IMMUTABLE_HACK int do_update_suidimmu; #endif rs = SB_DISK_SUPER_BLOCK (s); if (!parse_options(data, &mount_options, &blocks)) return 0; #ifdef CONFIG_REISERFS_IMMUTABLE_HACK if (reiserfs_suid_immutable(s) && !capable(CAP_LINUX_IMMUTABLE)) return -EPERM; do_update_suidimmu = 0; if (test_bit(SUID_IMMUTABLE, &mount_options)) { if (!capable(CAP_LINUX_IMMUTABLE)) return -EPERM; #ifdef CONFIG_REISERFS_IMMUTABLE_HACK_DEBUG printk("reiserfs: suidimmu ON\n"); #endif /* CONFIG_REISERFS_IMMUTABLE_HACK_DEBUG */ if (!reiserfs_suid_immutable(s)) do_update_suidimmu = 1; set_bit(SUID_IMMUTABLE, &(s->u.reiserfs_sb.s_mount_opt)); } else { #ifdef CONFIG_REISERFS_IMMUTABLE_HACK_DEBUG printk("reiserfs: suidimmu OFF\n"); #endif /* CONFIG_REISERFS_IMMUTABLE_HACK_DEBUG */ if (reiserfs_suid_immutable(s)) do_update_suidimmu = 1; clear_bit(SUID_IMMUTABLE, &(s->u.reiserfs_sb.s_mount_opt)); } /* * update S_IMMUTABLE bit on inode->i_flags */ if (do_update_suidimmu) update_suidimmu(s, reiserfs_suid_immutable(s)); #endif /* CONFIG_REISERFS_IMMUTABLE_HACK */ #define SET_OPT( opt, bits, super ) \ if( ( bits ) & ( 1 << ( opt ) ) ) \ ( super ) -> u.reiserfs_sb.s_mount_opt |= ( 1 << ( opt ) ) /* set options in the super-block bitmask */ SET_OPT( NOTAIL, mount_options, s ); SET_OPT( REISERFS_NO_BORDER, mount_options, s ); SET_OPT( REISERFS_NO_UNHASHED_RELOCATION, mount_options, s ); SET_OPT( REISERFS_HASHED_RELOCATION, mount_options, s ); SET_OPT( REISERFS_TEST4, mount_options, s ); #undef SET_OPT 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 reiserfs_remount (struct super_block * s, int * mount_flags, char * data) { struct reiserfs_super_block * rs; struct reiserfs_transaction_handle th ; unsigned long blocks; unsigned long mount_options = 0; rs = SB_DISK_SUPER_BLOCK (s); if (!reiserfs_parse_options(s, data, &mount_options, &blocks)) return 0; #define SET_OPT( opt, bits, super ) \ if( ( bits ) & ( 1 << ( opt ) ) ) \ ( super ) -> u.reiserfs_sb.s_mount_opt |= ( 1 << ( opt ) ) /* set options in the super-block bitmask */ SET_OPT( REISERFS_SMALLTAIL, mount_options, s ); SET_OPT( REISERFS_LARGETAIL, mount_options, s ); SET_OPT( REISERFS_NO_BORDER, mount_options, s ); SET_OPT( REISERFS_NO_UNHASHED_RELOCATION, mount_options, s ); SET_OPT( REISERFS_HASHED_RELOCATION, mount_options, s ); SET_OPT( REISERFS_TEST4, mount_options, s ); SET_OPT( REISERFS_ATTRS, mount_options, s ); #undef SET_OPT handle_attrs( s ); if(blocks) { int rc = reiserfs_resize(s, blocks); if (rc != 0) return rc; } if (*mount_flags & MS_RDONLY) { /* remount read-only */ if (s->s_flags & MS_RDONLY) /* it is read-only already */ return 0; /* 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 { /* remount read-write */ if (!(s->s_flags & MS_RDONLY)) return 0; /* We are read-write already */ 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 (!( *mount_flags & MS_RDONLY ) ) finish_unfinished( s ); return 0; }