コード例 #1
0
ファイル: super.c プロジェクト: nhanh0/hah
//
// 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;
}
コード例 #2
0
ファイル: super.c プロジェクト: chinnyannieb/empeg-hijack
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) 
  	reiserfs_resize(s, blocks);
	
  journal_begin(&th, s, 10) ;
  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 */
    journal_end(&th, s, 10) ;
    return 0;
  }
  if (*flags & MS_RDONLY) {
    /* try to remount file system with read-only permissions */
    if (le16_to_cpu (rs->s_state) == REISERFS_VALID_FS ||
	s->u.reiserfs_sb.s_mount_state != REISERFS_VALID_FS) {
      journal_end(&th, s, 10) ;
      return 0;
    }
    /* Mounting a rw partition read-only. */
    rs->s_state = cpu_to_le16 (s->u.reiserfs_sb.s_mount_state);
    /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); journal victim */
    journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
    s->s_dirt = 0;
  } else {
    /* Mount a partition which is read-only, read-write */
    s->u.reiserfs_sb.s_mount_state = le16_to_cpu (rs->s_state);
    s->s_flags &= ~MS_RDONLY;
    rs->s_state = cpu_to_le16 (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 ;
    if (test_bit(NOTAIL, &mount_options)) {
      set_bit(NOTAIL, &(s->u.reiserfs_sb.s_mount_opt)) ;
    }
    
    /* check state, which file system had when remounting read-write */
#if 0 /* journal victim */    
    if (s->u.reiserfs_sb.s_mount_state != REISERFS_VALID_FS)
      printk ("REISERFS: remounting unchecked fs, "
	      "running reiserfsck is recommended\n");
#endif
  }
  /* this will force a full flush of all journal lists */
  SB_JOURNAL(s)->j_must_wait = 1 ;
  journal_end(&th, s, 10) ;
  return 0;
}
コード例 #3
0
/* read super block and bitmaps. fixme: only 4k blocks, pre-journaled format
   is refused */
reiserfs_filsys_t reiserfs_open (char * filename, int flags, int *error, void * vp)
{
    reiserfs_filsys_t fs;
    struct buffer_head * bh;
    struct reiserfs_super_block * rs;
    int fd, i;
    
    fd = open (filename, flags | O_LARGEFILE);
    if (fd == -1) {
	if (error)
	    *error = errno;
	return 0;
    }

    fs = getmem (sizeof (*fs));
    fs->s_dev = fd;
    fs->s_vp = vp;
    asprintf (&fs->file_name, "%s", filename);

    /* reiserfs super block is either in 16-th or in 2-nd 4k block of the
       device */
    for (i = 16; i > 0; i -= 14) {
	bh = bread (fd, i, 4096);
	if (!bh) {
	    reiserfs_warning (stderr, "reiserfs_open: bread failed reading block %d\n", i);
	} else {
	    rs = (struct reiserfs_super_block *)bh->b_data;
	    
	    if (is_reiser2fs_magic_string (rs) || is_reiserfs_magic_string (rs))
		goto found;

	    /* reiserfs signature is not found at the i-th 4k block */
	    brelse (bh);
	}
    }

    reiserfs_warning (stderr, "reiserfs_open: neither new nor old reiserfs format "
		      "found on %s\n", filename);
    if (error)
	*error = 0;
    return fs;

 found:

    /* fixme: we could make some check to make sure that super block looks
       correctly */
    fs->s_version = is_reiser2fs_magic_string (rs) ? REISERFS_VERSION_2 :
	REISERFS_VERSION_1;
    fs->s_blocksize = rs_blocksize (rs);
    fs->s_hash_function = code2func (rs_hash (rs));
    SB_BUFFER_WITH_SB (fs) = bh;
    fs->s_rs = rs;
    fs->s_flags = flags; /* O_RDONLY or O_RDWR */
    fs->s_vp = vp;

    reiserfs_read_bitmap_blocks(fs);
	
    return fs;

}
コード例 #4
0
ファイル: super.c プロジェクト: niubl/camera_project
//
// 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 void reiserfs_write_super_lockfs (struct super_block * s)
{

  int dirty = 0 ;
  struct reiserfs_transaction_handle th ;
  lock_kernel() ;
  if (!(s->s_flags & MS_RDONLY)) {
    journal_begin(&th, s, 1) ;
    reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
    journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
    reiserfs_block_writes(&th) ;
    journal_end(&th, s, 1) ;
  }
  s->s_dirt = dirty;
  unlock_kernel() ;
}
コード例 #5
0
ファイル: super.c プロジェクト: chinnyannieb/empeg-hijack
void reiserfs_write_super (struct super_block * s)
{

  int dirty = 0 ;
  if (!(s->s_flags & MS_RDONLY)) {
#if 0 /* journal victim */
    rs = SB_DISK_SUPER_BLOCK (s);
    /*
     * if reiserfs was mounted with read-write permissions make file
     * system state not valid so that if we crash without doing a
     * clean umount we know that we must run file system
     * checker. umount will mark it valid if it does a clean umount
     */
    if (le16_to_cpu (rs->s_state) == REISERFS_VALID_FS) {
      rs->s_state = cpu_to_le16 (REISERFS_ERROR_FS);
      /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); */
      journal_begin(&th, s, 1) ;
      journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s)) ;
      journal_end(&th, s, 1) ;
    }
#endif
    dirty = flush_old_commits(s, 1) ;
  }
  s->s_dirt = dirty;
}
コード例 #6
0
ファイル: super.c プロジェクト: muromec/linux-ezxdev
static void reiserfs_put_super (struct super_block * s)
{
  int i;
  struct reiserfs_transaction_handle th ;
  
  /* change file system state to current state if it was mounted with read-write permissions */
  if (!(s->s_flags & MS_RDONLY)) {
    journal_begin(&th, s, 10) ;
    reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
    set_sb_state( SB_DISK_SUPER_BLOCK(s), s->u.reiserfs_sb.s_mount_state );
    journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
  }

  /* note, journal_release checks for readonly mount, and can decide not
  ** to do a journal_end
  */
  journal_release(&th, s) ;

  for (i = 0; i < SB_BMAP_NR (s); i ++)
    brelse (SB_AP_BITMAP (s)[i].bh);

  vfree (SB_AP_BITMAP (s));

  brelse (SB_BUFFER_WITH_SB (s));

  print_statistics (s);

  if (s->u.reiserfs_sb.s_kmallocs != 0) {
    reiserfs_warning ("vs-2004: reiserfs_put_super: allocated memory left %d\n",
		      s->u.reiserfs_sb.s_kmallocs);
  }

  if (s->u.reiserfs_sb.reserved_blocks != 0) {
    reiserfs_warning ("green-2005: reiserfs_put_super: reserved blocks left %d\n",
		      s->u.reiserfs_sb.reserved_blocks);
  }

  reiserfs_proc_unregister( s, "journal" );
  reiserfs_proc_unregister( s, "oidmap" );
  reiserfs_proc_unregister( s, "on-disk-super" );
  reiserfs_proc_unregister( s, "bitmap" );
  reiserfs_proc_unregister( s, "per-level" );
  reiserfs_proc_unregister( s, "super" );
  reiserfs_proc_unregister( s, "version" );
  reiserfs_proc_info_done( s );
  return;
}
コード例 #7
0
ファイル: super.c プロジェクト: chinnyannieb/empeg-hijack
static int read_super_block (struct super_block * s, int size)
{
  struct buffer_head * bh;
  struct reiserfs_super_block * rs;
  int repeat ;

  repeat = 0 ;
  bh = bread (s->s_dev, (REISERFS_DISK_OFFSET_IN_BYTES / size), size);
  if (!bh) {
    printk("reiserfs_read_super: unable to read superblock on dev %s\n", kdevname(s->s_dev));
    return 1;
  }

  rs = (struct reiserfs_super_block *)bh->b_data;
  if (strncmp (rs->s_magic,  REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING))) {
    brelse (bh);
    printk ("reiserfs_read_super: can't find a reiserfs filesystem on dev %s.\n", kdevname(s->s_dev));
    return 1;
  }

  s->s_blocksize = le16_to_cpu (rs->s_blocksize);
  s->s_blocksize_bits = 0;
  while ((1 << s->s_blocksize_bits) != s->s_blocksize)
    s->s_blocksize_bits ++;

  if (size != rs->s_blocksize) {
    brelse (bh);
    set_blocksize (s->s_dev, s->s_blocksize);
    bh = reiserfs_bread (s->s_dev,  (REISERFS_DISK_OFFSET_IN_BYTES / s->s_blocksize), s->s_blocksize, &repeat);
    if (!bh) {
      printk("reiserfs_read_super: unable to read superblock on dev %s\n", kdevname(s->s_dev));
      return 1;
    }

    rs = (struct reiserfs_super_block *)bh->b_data;
    if (strncmp (rs->s_magic,  REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING)) ||
	le16_to_cpu (rs->s_blocksize) != s->s_blocksize) {
      brelse (bh);
      printk ("reiserfs_read_super: 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 >= rs->s_journal_block && 
      bh->b_blocknr < (rs->s_journal_block + JOURNAL_BLOCK_COUNT)) {
      brelse(bh) ;
      printk("super-459: reiserfs_read_super: 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;
  return 0;
}
コード例 #8
0
ファイル: super.c プロジェクト: muromec/linux-ezxdev
/* 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].bh)) ;
    wait_on_buffer(SB_AP_BITMAP(s)[i].bh) ;
    if (!buffer_uptodate(SB_AP_BITMAP(s)[i].bh)) {
      printk("reread_meta_blocks, error reading bitmap block number %d at
      %ld\n", i, SB_AP_BITMAP(s)[i].bh->b_blocknr) ;
      return 1 ;
    }
  }
コード例 #9
0
/* get unique object identifier */
__u32 reiserfs_get_unused_objectid(struct reiserfs_transaction_handle *th)
{
	struct super_block *s = th->t_super;
	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
	__le32 *map = objectid_map(s, rs);
	__u32 unused_objectid;

	BUG_ON(!th->t_trans_id);

	check_objectid_map(s, map);

	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
	/* comment needed -Hans */
	unused_objectid = le32_to_cpu(map[1]);
	if (unused_objectid == U32_MAX) {
		reiserfs_warning(s, "reiserfs-15100", "no more object ids");
		reiserfs_restore_prepared_buffer(s, SB_BUFFER_WITH_SB(s));
		return 0;
	}

	/* This incrementation allocates the first unused objectid. That
	   is to say, the first entry on the objectid map is the first
	   unused objectid, and by incrementing it we use it.  See below
	   where we check to see if we eliminated a sequence of unused
	   objectids.... */
	map[1] = cpu_to_le32(unused_objectid + 1);

	/* Now we check to see if we eliminated the last remaining member of
	   the first even sequence (and can eliminate the sequence by
	   eliminating its last objectid from oids), and can collapse the
	   first two odd sequences into one sequence.  If so, then the net
	   result is to eliminate a pair of objectids from oids.  We do this
	   by shifting the entire map to the left. */
	if (sb_oid_cursize(rs) > 2 && map[1] == map[2]) {
		memmove(map + 1, map + 3,
			(sb_oid_cursize(rs) - 3) * sizeof(__u32));
		set_sb_oid_cursize(rs, sb_oid_cursize(rs) - 2);
	}

	journal_mark_dirty(th, s, SB_BUFFER_WITH_SB(s));
	return unused_objectid;
}
コード例 #10
0
/* free all memory involved into manipulating with filesystem */
void reiserfs_free (reiserfs_filsys_t fs)
{
    reiserfs_free_bitmap_blocks(fs);
    
    /* release super block and memory used by filesystem handler */
    brelse (SB_BUFFER_WITH_SB (fs));
    
    free_buffers ();

    free (fs->file_name);
    freemem (fs);
}
コード例 #11
0
ファイル: super.c プロジェクト: chinnyannieb/empeg-hijack
/* support old disk layout */
static int read_old_super_block (struct super_block * s, int size)
{
  struct buffer_head * bh;
  struct reiserfs_super_block * rs;
  int repeat ;

  printk("reiserfs_read_super: try to find super block in old location\n");
  repeat = 0 ;
  /* there are only 4k-sized blocks in v3.5.10 */
  if (size != REISERFS_OLD_BLOCKSIZE)
	  set_blocksize(s->s_dev, REISERFS_OLD_BLOCKSIZE);
  bh = bread (s->s_dev, 
  			  REISERFS_OLD_DISK_OFFSET_IN_BYTES / REISERFS_OLD_BLOCKSIZE, 
 		      REISERFS_OLD_BLOCKSIZE);
  if (!bh) {
    printk("reiserfs_read_super: unable to read superblock on dev %s\n", kdevname(s->s_dev));
    return 1;
  }

  rs = (struct reiserfs_super_block *)bh->b_data;
  if (strncmp (rs->s_magic,  REISERFS_SUPER_MAGIC_STRING, strlen ( REISERFS_SUPER_MAGIC_STRING))) {
	  /* pre-journaling version check */
	  if(!strncmp((char*)rs + REISERFS_SUPER_MAGIC_STRING_OFFSET_NJ,
				  REISERFS_SUPER_MAGIC_STRING, strlen(REISERFS_SUPER_MAGIC_STRING))) {
		  printk("reiserfs_read_super: a pre-journaling reiserfs filesystem isn't suitable there.\n");
		  brelse(bh);
		  return 1;
	  }
	  
    brelse (bh);
    printk ("reiserfs_read_super: can't find a reiserfs filesystem on dev %s.\n", kdevname(s->s_dev));
    return 1;
  }

  if(REISERFS_OLD_BLOCKSIZE != le16_to_cpu (rs->s_blocksize)) {
  	printk("reiserfs_read_super: blocksize mismatch, super block corrupted\n");
	brelse(bh);
	return 1;
  }	

  s->s_blocksize = REISERFS_OLD_BLOCKSIZE;
  s->s_blocksize_bits = 0;
  while ((1 << s->s_blocksize_bits) != s->s_blocksize)
    s->s_blocksize_bits ++;

  SB_BUFFER_WITH_SB (s) = bh;
  SB_DISK_SUPER_BLOCK (s) = rs;
  s->s_op = &reiserfs_sops;
  return 0;
}
コード例 #12
0
/* the first one of the mainest functions */
int expand_fs (reiserfs_filsys_t fs, unsigned long block_count_new) {
    int block_r, block_r_new;
    unsigned int bmap_nr_new, bmap_nr_old;
    int i;

    reiserfs_bitmap_t bmp;
    struct reiserfs_super_block * rs = fs->s_rs;

    reiserfs_reopen(fs, O_RDWR);
    set_state (fs->s_rs, REISERFS_ERROR_FS);
    bwrite_cond(SB_BUFFER_WITH_SB(fs));

    bmp = reiserfs_create_bitmap(rs_block_count(rs));
    if (!bmp)
        die ("cannot create bitmap\n");
    reiserfs_fetch_disk_bitmap(bmp, fs);
    reiserfs_free_bitmap_blocks(fs);
    if (reiserfs_expand_bitmap(bmp, block_count_new))
        die ("cannot expand bitmap\n");

    /* clean bits in old bitmap tail */
    for (i = rs_block_count(rs);
            i < rs_bmap_nr(rs) * rs_blocksize(rs) * 8 && i < block_count_new;
            i++) {
        reiserfs_bitmap_clear_bit(bmp, i);
    }

    /* count used bits in last bitmap block */
    block_r = rs_block_count(rs) - ((rs_bmap_nr(rs) - 1) * rs_blocksize(rs) * 8);

    /* count bitmap blocks in new fs */
    bmap_nr_new = (block_count_new - 1) / (rs_blocksize(rs) * 8) + 1;
    block_r_new = block_count_new - (bmap_nr_new - 1) * rs_blocksize(rs) * 8;

    bmap_nr_old = rs_bmap_nr(rs);

    /* update super block buffer*/
    set_free_blocks (rs, rs_free_blocks(rs) + block_count_new
                     - rs_block_count(rs) - (bmap_nr_new - rs_bmap_nr(rs)));
    set_block_count (rs, block_count_new);
    set_bmap_nr (rs, bmap_nr_new);

    reiserfs_read_bitmap_blocks(fs);
    for (i = bmap_nr_old; i < bmap_nr_new; i++) /* fix new bitmap blocks */
        reiserfs_bitmap_set_bit(bmp, SB_AP_BITMAP(fs)[i]->b_blocknr);
    reiserfs_flush_bitmap(bmp, fs);

    return 0;
}
コード例 #13
0
ファイル: bitmap.c プロジェクト: Dronevery/JetsonTK1-kernel
static void _reiserfs_free_block (struct reiserfs_transaction_handle *th,
                                  struct inode *inode, b_blocknr_t block,
                                  int for_unformatted)
{
    struct super_block * s = th->t_super;
    struct reiserfs_super_block * rs;
    struct buffer_head * sbh;
    struct reiserfs_bitmap_info *apbi;
    int nr, offset;

    BUG_ON (!th->t_trans_id);

    PROC_INFO_INC( s, free_block );

    rs = SB_DISK_SUPER_BLOCK (s);
    sbh = SB_BUFFER_WITH_SB (s);
    apbi = SB_AP_BITMAP(s);

    get_bit_address (s, block, &nr, &offset);

    if (nr >= sb_bmap_nr (rs)) {
        reiserfs_warning (s, "vs-4075: reiserfs_free_block: "
                          "block %lu is out of range on %s",
                          block, reiserfs_bdevname (s));
        return;
    }

    reiserfs_prepare_for_journal(s, apbi[nr].bh, 1 ) ;

    /* clear bit for the given block in bit map */
    if (!reiserfs_test_and_clear_le_bit (offset, apbi[nr].bh->b_data)) {
        reiserfs_warning (s, "vs-4080: reiserfs_free_block: "
                          "free_block (%s:%lu)[dev:blocknr]: bit already cleared",
                          reiserfs_bdevname (s), block);
    }
    apbi[nr].free_count ++;
    journal_mark_dirty (th, s, apbi[nr].bh);

    reiserfs_prepare_for_journal(s, sbh, 1) ;
    /* update super block */
    set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 );

    journal_mark_dirty (th, s, sbh);
    if (for_unformatted)
        DQUOT_FREE_BLOCK_NODIRTY(inode, 1);
}
コード例 #14
0
/* read bitmap blocks */
void reiserfs_read_bitmap_blocks (reiserfs_filsys_t fs)
{
	struct reiserfs_super_block * rs = fs->s_rs;
	struct buffer_head * bh = SB_BUFFER_WITH_SB(fs);
	int fd = fs->s_dev;
	unsigned long block;
	int i;
	
	/* read bitmaps, and correct a bit if necessary */
	SB_AP_BITMAP (fs) = getmem (sizeof (void *) * rs_bmap_nr (rs));
	for (i = 0, block = bh->b_blocknr + 1;
	     i < rs_bmap_nr (rs); i ++) {
		SB_AP_BITMAP (fs)[i] = bread (fd, block, fs->s_blocksize);
		if (!SB_AP_BITMAP (fs)[i]) {
		    	reiserfs_warning (stderr, "reiserfs_open: bread failed reading bitmap #%d (%lu)\n", i, block);
			SB_AP_BITMAP (fs)[i] = getblk (fd, block, fs->s_blocksize);
			memset (SB_AP_BITMAP (fs)[i]->b_data, 0xff, fs->s_blocksize);
			set_bit (BH_Uptodate, &SB_AP_BITMAP (fs)[i]->b_state);
		}
		
		/* all bitmaps have to have itself marked used on it */
		if (bh->b_blocknr == 16) {
			if (!test_bit (block % (fs->s_blocksize * 8), SB_AP_BITMAP (fs)[i]->b_data)) {
				reiserfs_warning (stderr, "reiserfs_open: bitmap %d was marked free\n", i);
				/*set_bit (block % (fs->s_blocksize * 8), SB_AP_BITMAP (fs)[i]->b_data);*/
			}
		} else {
			/* bitmap not spread over partition: fixme: does not
			   work when number of bitmaps => 32768 */
			if (!test_bit (block, SB_AP_BITMAP (fs)[0]->b_data)) {
			    	reiserfs_warning (stderr, "reiserfs_open: bitmap %d was marked free\n", i);
				/*set_bit (block, SB_AP_BITMAP (fs)[0]->b_data);*/
			}
		}

		if (i == 0) {
			/* first bitmap has to have marked used super block
			   and journal areas */
			check_first_bitmap (fs, SB_AP_BITMAP (fs)[i]->b_data);
		}

		block = (bh->b_blocknr == 16 ? ((i + 1) * fs->s_blocksize * 8) : (block + 1));
    }
}
コード例 #15
0
static void _reiserfs_free_block (struct reiserfs_transaction_handle *th,
                                  b_blocknr_t block)
{
    struct super_block * s = th->t_super;
    struct reiserfs_super_block * rs;
    struct buffer_head * sbh;
    struct reiserfs_bitmap_info *apbi;
    int nr, offset;

    PROC_INFO_INC( s, free_block );

    rs = SB_DISK_SUPER_BLOCK (s);
    sbh = SB_BUFFER_WITH_SB (s);
    apbi = SB_AP_BITMAP(s);

    get_bit_address (s, block, &nr, &offset);

    if (nr >= sb_bmap_nr (rs)) {
        reiserfs_warning ("vs-4075: reiserfs_free_block: "
                          "block %lu is out of range on %s\n",
                          block, bdevname(s->s_dev));
        return;
    }

    reiserfs_prepare_for_journal(s, apbi[nr].bh, 1 ) ;

    /* clear bit for the given block in bit map */
    if (!reiserfs_test_and_clear_le_bit (offset, apbi[nr].bh->b_data)) {
        reiserfs_warning ("vs-4080: reiserfs_free_block: "
                          "free_block (%04x:%lu)[dev:blocknr]: bit already cleared\n",
                          s->s_dev, block);
    }
    if (offset < apbi[nr].first_zero_hint) {
        apbi[nr].first_zero_hint = offset;
    }
    apbi[nr].free_count ++;
    journal_mark_dirty (th, s, apbi[nr].bh);

    reiserfs_prepare_for_journal(s, sbh, 1) ;
    /* update super block */
    set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 );

    journal_mark_dirty (th, s, sbh);
}
コード例 #16
0
ファイル: bitmap.c プロジェクト: liexusong/Linux-2.4.16
				/* I wonder if it would be less modest
                                   now that we use journaling. -Hans */
void reiserfs_free_block (struct reiserfs_transaction_handle *th, unsigned long block)
{
    struct super_block * s = th->t_super;
    struct reiserfs_super_block * rs;
    struct buffer_head * sbh;
    struct buffer_head ** apbh;
    int nr, offset;

  RFALSE(!s, "vs-4060: trying to free block on nonexistent device");
  RFALSE(is_reusable (s, block, 1) == 0, "vs-4070: can not free such block");

  PROC_INFO_INC( s, free_block );

  rs = SB_DISK_SUPER_BLOCK (s);
  sbh = SB_BUFFER_WITH_SB (s);
  apbh = SB_AP_BITMAP (s);

  get_bit_address (s, block, &nr, &offset);

  /* mark it before we clear it, just in case */
  journal_mark_freed(th, s, block) ;

  reiserfs_prepare_for_journal(s, apbh[nr], 1 ) ;

  /* clear bit for the given block in bit map */
  if (!reiserfs_test_and_clear_le_bit (offset, apbh[nr]->b_data)) {
      reiserfs_warning ("vs-4080: reiserfs_free_block: "
			"free_block (%04x:%lu)[dev:blocknr]: bit already cleared\n", 
	    s->s_dev, block);
  }
  journal_mark_dirty (th, s, apbh[nr]);

  reiserfs_prepare_for_journal(s, sbh, 1) ;
  /* update super block */
  set_sb_free_blocks( rs, sb_free_blocks(rs) + 1 );

  journal_mark_dirty (th, s, sbh);
  s->s_dirt = 1;
}
コード例 #17
0
ファイル: objectid.c プロジェクト: chinnyannieb/empeg-hijack
/* get unique object identifier */
unsigned long	reiserfs_get_unused_objectid (struct reiserfs_transaction_handle *th, struct super_block * s)
{
  unsigned long unused_objectid;
  struct reiserfs_super_block * disk_sb;
  unsigned long * objectid_map;


  disk_sb = SB_DISK_SUPER_BLOCK (s);
  objectid_map = (unsigned long *)(disk_sb + 1); /* The objectid map follows the superblock. */
  
                                /* comment needed -Hans */
  unused_objectid = objectid_map[1];
  if (unused_objectid == TYPE_INDIRECT) {
    printk ("REISERFS: get_objectid: no more object ids\n");
    return 0;
  }

  /* This incrementation allocates the first unused objectid. That is to say, the first entry on the
   objectid map is the first unused objectid, and by incrementing it we use it.  See below where we
   check to see if we eliminated a sequence of unused objectids.... */
  objectid_map[1] ++;

  /* Now we check to see if we eliminated the last remaining member of
     the first even sequence (and can eliminate the sequence by
     eliminating its last objectid from oids), and can collapse the
     first two odd sequences into one sequence.  If so, then the net
     result is to eliminate a pair of objectids from oids.  We do this
     by shifting the entire map to the left. */
  if (disk_sb->s_oid_cursize > 2 && objectid_map[1] == objectid_map[2]) {
    memmove (objectid_map + 1, objectid_map + 3, (disk_sb->s_oid_cursize - 3) * sizeof(unsigned long));
    disk_sb->s_oid_cursize -= 2;
  }

  /* super block has been changed. Non-atomic mark_buffer_dirty is allowed here */
  /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1); journal victim *//* no need to place buffer on preserve list */
  journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s));/* no need to place buffer on preserve list */
  s->s_dirt = 1;
  return unused_objectid;
}
コード例 #18
0
int reiserfs_convert_objectid_map_v1(struct super_block *s)
{
	struct reiserfs_super_block *disk_sb = SB_DISK_SUPER_BLOCK(s);
	int cur_size = sb_oid_cursize(disk_sb);
	int new_size = (s->s_blocksize - SB_SIZE) / sizeof(__u32) / 2 * 2;
	int old_max = sb_oid_maxsize(disk_sb);
	struct reiserfs_super_block_v1 *disk_sb_v1;
	__le32 *objectid_map, *new_objectid_map;
	int i;

	disk_sb_v1 =
	    (struct reiserfs_super_block_v1 *)(SB_BUFFER_WITH_SB(s)->b_data);
	objectid_map = (__le32 *) (disk_sb_v1 + 1);
	new_objectid_map = (__le32 *) (disk_sb + 1);

	if (cur_size > new_size) {
		/* mark everyone used that was listed as free at the end of the objectid
		 ** map
		 */
		objectid_map[new_size - 1] = objectid_map[cur_size - 1];
		set_sb_oid_cursize(disk_sb, new_size);
	}
	/* move the smaller objectid map past the end of the new super */
	for (i = new_size - 1; i >= 0; i--) {
		objectid_map[i + (old_max - new_size)] = objectid_map[i];
	}

	/* set the max size so we don't overflow later */
	set_sb_oid_maxsize(disk_sb, new_size);

	/* Zero out label and generate random UUID */
	memset(disk_sb->s_label, 0, sizeof(disk_sb->s_label));
	generate_random_uuid(disk_sb->s_uuid);

	/* finally, zero out the unused chunk of the new super */
	memset(disk_sb->s_unused, 0, sizeof(disk_sb->s_unused));
	return 0;
}
コード例 #19
0
int reiserfs_resize(struct super_block *s, unsigned long block_count_new)
{
	int err = 0;
	struct reiserfs_super_block *sb;
	struct reiserfs_bitmap_info *bitmap;
	struct reiserfs_bitmap_info *info;
	struct reiserfs_bitmap_info *old_bitmap = SB_AP_BITMAP(s);
	struct buffer_head *bh;
	struct reiserfs_transaction_handle th;
	unsigned int bmap_nr_new, bmap_nr;
	unsigned int block_r_new, block_r;

	struct reiserfs_list_bitmap *jb;
	struct reiserfs_list_bitmap jbitmap[JOURNAL_NUM_BITMAPS];

	unsigned long int block_count, free_blocks;
	int i;
	int copy_size;

	sb = SB_DISK_SUPER_BLOCK(s);

	if (SB_BLOCK_COUNT(s) >= block_count_new) {
		printk("can\'t shrink filesystem on-line\n");
		return -EINVAL;
	}

	/* check the device size */
	bh = sb_bread(s, block_count_new - 1);
	if (!bh) {
		printk("reiserfs_resize: can\'t read last block\n");
		return -EINVAL;
	}
	bforget(bh);

	/* old disk layout detection; those partitions can be mounted, but
	 * cannot be resized */
	if (SB_BUFFER_WITH_SB(s)->b_blocknr * SB_BUFFER_WITH_SB(s)->b_size
	    != REISERFS_DISK_OFFSET_IN_BYTES) {
		printk
		    ("reiserfs_resize: unable to resize a reiserfs without distributed bitmap (fs version < 3.5.12)\n");
		return -ENOTSUPP;
	}

	/* count used bits in last bitmap block */
	block_r = SB_BLOCK_COUNT(s) -
			(reiserfs_bmap_count(s) - 1) * s->s_blocksize * 8;

	/* count bitmap blocks in new fs */
	bmap_nr_new = block_count_new / (s->s_blocksize * 8);
	block_r_new = block_count_new - bmap_nr_new * s->s_blocksize * 8;
	if (block_r_new)
		bmap_nr_new++;
	else
		block_r_new = s->s_blocksize * 8;

	/* save old values */
	block_count = SB_BLOCK_COUNT(s);
	bmap_nr = reiserfs_bmap_count(s);

	/* resizing of reiserfs bitmaps (journal and real), if needed */
	if (bmap_nr_new > bmap_nr) {
		/* reallocate journal bitmaps */
		if (reiserfs_allocate_list_bitmaps(s, jbitmap, bmap_nr_new) < 0) {
			printk
			    ("reiserfs_resize: unable to allocate memory for journal bitmaps\n");
			return -ENOMEM;
		}
		/* the new journal bitmaps are zero filled, now we copy in the bitmap
		 ** node pointers from the old journal bitmap structs, and then
		 ** transfer the new data structures into the journal struct.
		 **
		 ** using the copy_size var below allows this code to work for
		 ** both shrinking and expanding the FS.
		 */
		copy_size = bmap_nr_new < bmap_nr ? bmap_nr_new : bmap_nr;
		copy_size =
		    copy_size * sizeof(struct reiserfs_list_bitmap_node *);
		for (i = 0; i < JOURNAL_NUM_BITMAPS; i++) {
			struct reiserfs_bitmap_node **node_tmp;
			jb = SB_JOURNAL(s)->j_list_bitmap + i;
			memcpy(jbitmap[i].bitmaps, jb->bitmaps, copy_size);

			/* just in case vfree schedules on us, copy the new
			 ** pointer into the journal struct before freeing the
			 ** old one
			 */
			node_tmp = jb->bitmaps;
			jb->bitmaps = jbitmap[i].bitmaps;
			vfree(node_tmp);
		}

		/* allocate additional bitmap blocks, reallocate array of bitmap
		 * block pointers */
		bitmap =
		    vzalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
		if (!bitmap) {
			/* Journal bitmaps are still supersized, but the memory isn't
			 * leaked, so I guess it's ok */
			printk("reiserfs_resize: unable to allocate memory.\n");
			return -ENOMEM;
		}
		for (i = 0; i < bmap_nr; i++)
			bitmap[i] = old_bitmap[i];

		/* This doesn't go through the journal, but it doesn't have to.
		 * The changes are still atomic: We're synced up when the journal
		 * transaction begins, and the new bitmaps don't matter if the
		 * transaction fails. */
		for (i = bmap_nr; i < bmap_nr_new; i++) {
			/* don't use read_bitmap_block since it will cache
			 * the uninitialized bitmap */
			bh = sb_bread(s, i * s->s_blocksize * 8);
			if (!bh) {
				vfree(bitmap);
				return -EIO;
			}
			memset(bh->b_data, 0, sb_blocksize(sb));
			reiserfs_set_le_bit(0, bh->b_data);
			reiserfs_cache_bitmap_metadata(s, bh, bitmap + i);

			set_buffer_uptodate(bh);
			mark_buffer_dirty(bh);
			reiserfs_write_unlock(s);
			sync_dirty_buffer(bh);
			reiserfs_write_lock(s);
			// update bitmap_info stuff
			bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
			brelse(bh);
		}
		/* free old bitmap blocks array */
		SB_AP_BITMAP(s) = bitmap;
		vfree(old_bitmap);
	}

	/* begin transaction, if there was an error, it's fine. Yes, we have
	 * incorrect bitmaps now, but none of it is ever going to touch the
	 * disk anyway. */
	err = journal_begin(&th, s, 10);
	if (err)
		return err;

	/* Extend old last bitmap block - new blocks have been made available */
	info = SB_AP_BITMAP(s) + bmap_nr - 1;
	bh = reiserfs_read_bitmap_block(s, bmap_nr - 1);
	if (!bh) {
		int jerr = journal_end(&th, s, 10);
		if (jerr)
			return jerr;
		return -EIO;
	}

	reiserfs_prepare_for_journal(s, bh, 1);
	for (i = block_r; i < s->s_blocksize * 8; i++)
		reiserfs_clear_le_bit(i, bh->b_data);
	info->free_count += s->s_blocksize * 8 - block_r;

	journal_mark_dirty(&th, s, bh);
	brelse(bh);

	/* Correct new last bitmap block - It may not be full */
	info = SB_AP_BITMAP(s) + bmap_nr_new - 1;
	bh = reiserfs_read_bitmap_block(s, bmap_nr_new - 1);
	if (!bh) {
		int jerr = journal_end(&th, s, 10);
		if (jerr)
			return jerr;
		return -EIO;
	}

	reiserfs_prepare_for_journal(s, bh, 1);
	for (i = block_r_new; i < s->s_blocksize * 8; i++)
		reiserfs_set_le_bit(i, bh->b_data);
	journal_mark_dirty(&th, s, bh);
	brelse(bh);

	info->free_count -= s->s_blocksize * 8 - block_r_new;
	/* update super */
	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
	free_blocks = SB_FREE_BLOCKS(s);
	PUT_SB_FREE_BLOCKS(s,
			   free_blocks + (block_count_new - block_count -
					  (bmap_nr_new - bmap_nr)));
	PUT_SB_BLOCK_COUNT(s, block_count_new);
	PUT_SB_BMAP_NR(s, bmap_would_wrap(bmap_nr_new) ? : bmap_nr_new);

	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));

	SB_JOURNAL(s)->j_must_wait = 1;
	return journal_end(&th, s, 10);
}
コード例 #20
0
ファイル: bitmap.c プロジェクト: Dronevery/JetsonTK1-kernel
/* it searches for a window of zero bits with given minimum and maximum lengths in one bitmap
 * block; */
static int scan_bitmap_block (struct reiserfs_transaction_handle *th,
                              int bmap_n, int *beg, int boundary, int min, int max, int unfm)
{
    struct super_block *s = th->t_super;
    struct reiserfs_bitmap_info *bi=&SB_AP_BITMAP(s)[bmap_n];
    int end, next;
    int org = *beg;

    BUG_ON (!th->t_trans_id);

    RFALSE(bmap_n >= SB_BMAP_NR (s), "Bitmap %d is out of range (0..%d)",bmap_n, SB_BMAP_NR (s) - 1);
    PROC_INFO_INC( s, scan_bitmap.bmap );
    /* this is unclear and lacks comments, explain how journal bitmaps
       work here for the reader.  Convey a sense of the design here. What
       is a window? */
    /* - I mean `a window of zero bits' as in description of this function - Zam. */

    if ( !bi ) {
        reiserfs_warning (s, "NULL bitmap info pointer for bitmap %d", bmap_n);
        return 0;
    }
    if (buffer_locked (bi->bh)) {
        PROC_INFO_INC( s, scan_bitmap.wait );
        __wait_on_buffer (bi->bh);
    }

    while (1) {
cont:
        if (bi->free_count < min)
            return 0; // No free blocks in this bitmap

        /* search for a first zero bit -- beggining of a window */
        *beg = reiserfs_find_next_zero_le_bit
               ((unsigned long*)(bi->bh->b_data), boundary, *beg);

        if (*beg + min > boundary) {
            /* search for a zero bit fails or the rest of bitmap block
            			      * cannot contain a zero window of minimum size */
            return 0;
        }

        if (unfm && is_block_in_journal(s,bmap_n, *beg, beg))
            continue;
        /* first zero bit found; we check next bits */
        for (end = *beg + 1;; end ++) {
            if (end >= *beg + max || end >= boundary || reiserfs_test_le_bit (end, bi->bh->b_data)) {
                next = end;
                break;
            }
            /* finding the other end of zero bit window requires looking into journal structures (in
             * case of searching for free blocks for unformatted nodes) */
            if (unfm && is_block_in_journal(s, bmap_n, end, &next))
                break;
        }

        /* now (*beg) points to beginning of zero bits window,
         * (end) points to one bit after the window end */
        if (end - *beg >= min) { /* it seems we have found window of proper size */
            int i;
            reiserfs_prepare_for_journal (s, bi->bh, 1);
            /* try to set all blocks used checking are they still free */
            for (i = *beg; i < end; i++) {
                /* It seems that we should not check in journal again. */
                if (reiserfs_test_and_set_le_bit (i, bi->bh->b_data)) {
                    /* bit was set by another process
                     * while we slept in prepare_for_journal() */
                    PROC_INFO_INC( s, scan_bitmap.stolen );
                    if (i >= *beg + min)	{
                        /* we can continue with smaller set of allocated blocks,
                        		   * if length of this set is more or equal to `min' */
                        end = i;
                        break;
                    }
                    /* otherwise we clear all bit were set ... */
                    while (--i >= *beg)
                        reiserfs_test_and_clear_le_bit (i, bi->bh->b_data);
                    reiserfs_restore_prepared_buffer (s, bi->bh);
                    *beg = org;
                    /* ... and search again in current block from beginning */
                    goto cont;
                }
            }
            bi->free_count -= (end - *beg);
            journal_mark_dirty (th, s, bi->bh);

            /* free block count calculation */
            reiserfs_prepare_for_journal (s, SB_BUFFER_WITH_SB(s), 1);
            PUT_SB_FREE_BLOCKS(s, SB_FREE_BLOCKS(s) - (end - *beg));
            journal_mark_dirty (th, s, SB_BUFFER_WITH_SB(s));

            return end - (*beg);
        } else {
            *beg = next;
        }
    }
}
コード例 #21
0
int reiserfs_resize (struct super_block * s, unsigned long block_count_new)
{
	struct reiserfs_super_block * sb;
        struct reiserfs_bitmap_info *bitmap;
	struct buffer_head * bh;
	struct reiserfs_transaction_handle th;
	unsigned int bmap_nr_new, bmap_nr;
	unsigned int block_r_new, block_r;
	
	struct reiserfs_list_bitmap * jb;
	struct reiserfs_list_bitmap jbitmap[JOURNAL_NUM_BITMAPS];
	
	unsigned long int block_count, free_blocks;
	int i;
	int copy_size ;

	sb = SB_DISK_SUPER_BLOCK(s);

	if (SB_BLOCK_COUNT(s) >= block_count_new) {
		printk("can\'t shrink filesystem on-line\n");
		return -EINVAL;
	}

	/* check the device size */
	bh = sb_bread(s, block_count_new - 1);
	if (!bh) {
		printk("reiserfs_resize: can\'t read last block\n");
		return -EINVAL;
	}	
	bforget(bh);

	/* old disk layout detection; those partitions can be mounted, but
	 * cannot be resized */
	if (SB_BUFFER_WITH_SB(s)->b_blocknr *	SB_BUFFER_WITH_SB(s)->b_size 
		!= REISERFS_DISK_OFFSET_IN_BYTES ) {
		printk("reiserfs_resize: unable to resize a reiserfs without distributed bitmap (fs version < 3.5.12)\n");
		return -ENOTSUPP;
	}
       
	/* count used bits in last bitmap block */
	block_r = SB_BLOCK_COUNT(s) -
	        (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8;
	
	/* count bitmap blocks in new fs */
	bmap_nr_new = block_count_new / ( s->s_blocksize * 8 );
	block_r_new = block_count_new - bmap_nr_new * s->s_blocksize * 8;
	if (block_r_new) 
		bmap_nr_new++;
	else
		block_r_new = s->s_blocksize * 8;

	/* save old values */
	block_count = SB_BLOCK_COUNT(s);
	bmap_nr     = SB_BMAP_NR(s);

	/* resizing of reiserfs bitmaps (journal and real), if needed */
	if (bmap_nr_new > bmap_nr) {	    
	    /* reallocate journal bitmaps */
	    if (reiserfs_allocate_list_bitmaps(s, jbitmap, bmap_nr_new) < 0) {
		printk("reiserfs_resize: unable to allocate memory for journal bitmaps\n");
		unlock_super(s) ;
		return -ENOMEM ;
	    }
	    /* the new journal bitmaps are zero filled, now we copy in the bitmap
	    ** node pointers from the old journal bitmap structs, and then
	    ** transfer the new data structures into the journal struct.
	    **
	    ** using the copy_size var below allows this code to work for
	    ** both shrinking and expanding the FS.
	    */
	    copy_size = bmap_nr_new < bmap_nr ? bmap_nr_new : bmap_nr ;
	    copy_size = copy_size * sizeof(struct reiserfs_list_bitmap_node *) ;
	    for (i = 0 ; i < JOURNAL_NUM_BITMAPS ; i++) {
		struct reiserfs_bitmap_node **node_tmp ;
		jb = SB_JOURNAL(s)->j_list_bitmap + i ;
		memcpy(jbitmap[i].bitmaps, jb->bitmaps, copy_size) ;

		/* just in case vfree schedules on us, copy the new
		** pointer into the journal struct before freeing the 
		** old one
		*/
		node_tmp = jb->bitmaps ;
		jb->bitmaps = jbitmap[i].bitmaps ;
		vfree(node_tmp) ;
	    }	
	
	    /* allocate additional bitmap blocks, reallocate array of bitmap
	     * block pointers */
	    bitmap = vmalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
	    if (!bitmap) {
		printk("reiserfs_resize: unable to allocate memory.\n");
		return -ENOMEM;
	    }
	    memset (bitmap, 0, sizeof (struct reiserfs_bitmap_info) * SB_BMAP_NR(s));
	    for (i = 0; i < bmap_nr; i++)
		bitmap[i] = SB_AP_BITMAP(s)[i];
	    for (i = bmap_nr; i < bmap_nr_new; i++) {
		bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8);
		memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
		reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data);

		set_buffer_uptodate(bitmap[i].bh);
		mark_buffer_dirty(bitmap[i].bh) ;
		sync_dirty_buffer(bitmap[i].bh);
		// update bitmap_info stuff
		bitmap[i].first_zero_hint=1;
		bitmap[i].free_count = sb_blocksize(sb) * 8 - 1;
	    }	
	    /* free old bitmap blocks array */
	    vfree(SB_AP_BITMAP(s));
	    SB_AP_BITMAP(s) = bitmap;
	}
	
	/* begin transaction */
	journal_begin(&th, s, 10);

	/* correct last bitmap blocks in old and new disk layout */
	reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1);
	for (i = block_r; i < s->s_blocksize * 8; i++)
	    reiserfs_test_and_clear_le_bit(i, 
					   SB_AP_BITMAP(s)[bmap_nr - 1].bh->b_data);
	SB_AP_BITMAP(s)[bmap_nr - 1].free_count += s->s_blocksize * 8 - block_r;
	if ( !SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint)
	    SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r;

	journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh);

	reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1);
	for (i = block_r_new; i < s->s_blocksize * 8; i++)
	    reiserfs_test_and_set_le_bit(i,
					 SB_AP_BITMAP(s)[bmap_nr_new - 1].bh->b_data);
	journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh);
 
	SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -= s->s_blocksize * 8 - block_r_new;
	/* Extreme case where last bitmap is the only valid block in itself. */
	if ( !SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count )
	    SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0;
 	/* update super */
	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
	free_blocks = SB_FREE_BLOCKS(s);
	PUT_SB_FREE_BLOCKS(s, free_blocks + (block_count_new - block_count - (bmap_nr_new - bmap_nr)));
	PUT_SB_BLOCK_COUNT(s, block_count_new);
	PUT_SB_BMAP_NR(s, bmap_nr_new);
	s->s_dirt = 1;

	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
	
	SB_JOURNAL(s)->j_must_wait = 1;
	journal_end(&th, s, 10);

	return 0;
}
コード例 #22
0
/* makes object identifier unused */
void reiserfs_release_objectid(struct reiserfs_transaction_handle *th,
			       __u32 objectid_to_release)
{
	struct super_block *s = th->t_super;
	struct reiserfs_super_block *rs = SB_DISK_SUPER_BLOCK(s);
	__le32 *map = objectid_map(s, rs);
	int i = 0;

	BUG_ON(!th->t_trans_id);
	//return;
	check_objectid_map(s, map);

	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1);
	journal_mark_dirty(th, s, SB_BUFFER_WITH_SB(s));

	/* start at the beginning of the objectid map (i = 0) and go to
	   the end of it (i = disk_sb->s_oid_cursize).  Linear search is
	   what we use, though it is possible that binary search would be
	   more efficient after performing lots of deletions (which is
	   when oids is large.)  We only check even i's. */
	while (i < sb_oid_cursize(rs)) {
		if (objectid_to_release == le32_to_cpu(map[i])) {
			/* This incrementation unallocates the objectid. */
			//map[i]++;
			le32_add_cpu(&map[i], 1);

			/* Did we unallocate the last member of an odd sequence, and can shrink oids? */
			if (map[i] == map[i + 1]) {
				/* shrink objectid map */
				memmove(map + i, map + i + 2,
					(sb_oid_cursize(rs) - i -
					 2) * sizeof(__u32));
				//disk_sb->s_oid_cursize -= 2;
				set_sb_oid_cursize(rs, sb_oid_cursize(rs) - 2);

				RFALSE(sb_oid_cursize(rs) < 2 ||
				       sb_oid_cursize(rs) > sb_oid_maxsize(rs),
				       "vs-15005: objectid map corrupted cur_size == %d (max == %d)",
				       sb_oid_cursize(rs), sb_oid_maxsize(rs));
			}
			return;
		}

		if (objectid_to_release > le32_to_cpu(map[i]) &&
		    objectid_to_release < le32_to_cpu(map[i + 1])) {
			/* size of objectid map is not changed */
			if (objectid_to_release + 1 == le32_to_cpu(map[i + 1])) {
				//objectid_map[i+1]--;
				le32_add_cpu(&map[i + 1], -1);
				return;
			}

			/* JDM comparing two little-endian values for equality -- safe */
			if (sb_oid_cursize(rs) == sb_oid_maxsize(rs)) {
				/* objectid map must be expanded, but there is no space */
				PROC_INFO_INC(s, leaked_oid);
				return;
			}

			/* expand the objectid map */
			memmove(map + i + 3, map + i + 1,
				(sb_oid_cursize(rs) - i - 1) * sizeof(__u32));
			map[i + 1] = cpu_to_le32(objectid_to_release);
			map[i + 2] = cpu_to_le32(objectid_to_release + 1);
			set_sb_oid_cursize(rs, sb_oid_cursize(rs) + 2);
			return;
		}
		i += 2;
	}

	reiserfs_error(s, "vs-15011", "tried to free free object id (%lu)",
		       (long unsigned)objectid_to_release);
}
コード例 #23
0
int main (int argc, char * argv[])
{
    char * file_name;
    int dev, i;

#if 1
    if (1) {
	/* ???? */
	schedule ();
	iput (0);
    }
#endif

    fprintf (stderr, "\n<-----------dumpreiserfs, version 0.99, 2000----------->\n"); 
    file_name = parse_options (argc, argv);


    dev = open (file_name, O_RDONLY);
    if (dev == -1)
	die ("dumpreiserfs: Can not open device %s: %s\n", file_name, strerror (errno));
    g_sb.s_dev = dev;

    if (uread_super_block (&g_sb))
	die ("dumpreiserfs: no reiserfs found on %s", file_name);
    if (uread_bitmaps (&g_sb))
	die ("dumpreiserfs: read_bitmap failed");

    if (opt_pack || opt_pack_all) {
	pack_partition (&g_sb);
    } else {
	/* dump file system to stdout */
	if (opt_block_to_print != -1) {
	    print_one_block (opt_block_to_print);
	    goto end;
	}

	print_block (SB_BUFFER_WITH_SB (&g_sb));

	if (opt_print_journal)
	    print_journal (&g_sb);
    
	if (opt_print_objectid_map == 1)
	    print_objectid_map (&g_sb);
    
	if (opt_print_block_map) {
	    print_bmap (&g_sb, opt_print_block_map == 1 ? 1 : 0);
	}

	if (opt_print_regular_file_content || opt_print_directory_contents ||
	    opt_print_leaf_items) {
	    print_disk_tree (SB_ROOT_BLOCK (&g_sb));

	    /* print the statistic */
	    printf ("File system uses %d internal + %d leaves + %d unformatted nodes = %d blocks\n", 
		    g_stat_info.nr_internals, g_stat_info.nr_leaves, g_stat_info.nr_unformatted, 
		    g_stat_info.nr_internals + g_stat_info.nr_leaves + g_stat_info.nr_unformatted);
	}
    }


 end:
    /* brelse bitmaps */
    if (SB_AP_BITMAP (&g_sb)) {
	for (i = 0; i < SB_BMAP_NR (&g_sb); i ++) {
	    brelse (SB_AP_BITMAP (&g_sb)[i]);
	}
	freemem (SB_AP_BITMAP (&g_sb));
    }

    /* brelse buffer containing super block */
    brelse (SB_BUFFER_WITH_SB (&g_sb));

    check_and_free_buffer_mem ();

    return 0;
}
コード例 #24
0
ファイル: super.c プロジェクト: niubl/camera_project
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 ;
    }

    if ( rs->s_root_block == -1 ) {
	brelse(bh) ;
	printk("dev %s: Unfinished reiserfsck --rebuild-tree run detected. Please run\n"
	       "reiserfsck --rebuild-tree and wait for a completion. If that fails\n"
	       "get newer reiserfsprogs package\n", kdevname (s->s_dev));
	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;
}
コード例 #25
0
ファイル: super.c プロジェクト: niubl/camera_project
//
// 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 struct super_block * reiserfs_read_super (struct super_block * s, void * data, int silent)
{
    int size;
    struct inode *root_inode;
    kdev_t dev = s->s_dev;
    int j;
    extern int *blksize_size[];
    struct reiserfs_transaction_handle th ;
    int old_format = 0;
    unsigned long blocks;
    int jinit_done = 0 ;
    struct reiserfs_iget4_args args ;
    int old_magic;
    struct reiserfs_super_block * rs;


    memset (&s->u.reiserfs_sb, 0, sizeof (struct reiserfs_sb_info));

    if (parse_options ((char *) data, &(s->u.reiserfs_sb.s_mount_opt), &blocks) == 0) {
	return NULL;
    }

    if (blocks) {
  	printk("reserfs: resize option for remount only\n");
	return NULL;
    }	

    if (blksize_size[MAJOR(dev)] && blksize_size[MAJOR(dev)][MINOR(dev)] != 0) {
	/* as blocksize is set for partition we use it */
	size = blksize_size[MAJOR(dev)][MINOR(dev)];
    } else {
	size = BLOCK_SIZE;
	set_blocksize (s->s_dev, BLOCK_SIZE);
    }

    /* read block (64-th 1k block), which can contain reiserfs super block */
    if (read_super_block (s, size, REISERFS_DISK_OFFSET_IN_BYTES)) {
	// try old format (undistributed bitmap, super block in 8-th 1k block of a device)
	if (read_super_block (s, size, REISERFS_OLD_DISK_OFFSET_IN_BYTES)) 
	    goto error;
	else
	    old_format = 1;
    }

    rs = SB_DISK_SUPER_BLOCK (s);

    s->u.reiserfs_sb.s_mount_state = SB_REISERFS_STATE(s);
    s->u.reiserfs_sb.s_mount_state = REISERFS_VALID_FS ;

    if (old_format ? read_old_bitmaps(s) : read_bitmaps(s)) { 
	printk ("reiserfs_read_super: unable to read bitmap\n");
	goto error;
    }
#ifdef CONFIG_REISERFS_CHECK
    printk("reiserfs:warning: CONFIG_REISERFS_CHECK is set ON\n");
    printk("reiserfs:warning: - it is slow mode for debugging.\n");
#endif

    // set_device_ro(s->s_dev, 1) ;
    if (journal_init(s)) {
	printk("reiserfs_read_super: unable to initialize journal space\n") ;
	goto error ;
    } else {
	jinit_done = 1 ; /* once this is set, journal_release must be called
			 ** if we error out of the mount 
			 */
    }
    if (reread_meta_blocks(s)) {
	printk("reiserfs_read_super: unable to reread meta blocks after journal init\n") ;
	goto error ;
    }

    if (replay_only (s))
	goto error;

    if (is_read_only(s->s_dev) && !(s->s_flags & MS_RDONLY)) {
        printk("clm-7000: Detected readonly device, marking FS readonly\n") ;
	s->s_flags |= MS_RDONLY ;
    }
    args.objectid = REISERFS_ROOT_PARENT_OBJECTID ;
    root_inode = iget4 (s, REISERFS_ROOT_OBJECTID, 0, (void *)(&args));
    if (!root_inode) {
	printk ("reiserfs_read_super: get root inode failed\n");
	goto error;
    }

    s->s_root = d_alloc_root(root_inode);  
    if (!s->s_root) {
	iput(root_inode);
	goto error;
    }

    // define and initialize hash function
    s->u.reiserfs_sb.s_hash_function = hash_function (s);
    if (s->u.reiserfs_sb.s_hash_function == NULL) {
      dput(s->s_root) ;
      s->s_root = NULL ;
      goto error ;
    }

    rs = SB_DISK_SUPER_BLOCK (s);
    old_magic = strncmp (rs->s_magic,  REISER2FS_SUPER_MAGIC_STRING,
                           strlen ( REISER2FS_SUPER_MAGIC_STRING));
    if (!old_magic)
	set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties));
    else
	set_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties));

    if (!(s->s_flags & MS_RDONLY)) {

	journal_begin(&th, s, 1) ;
	reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;

        set_sb_state( rs, REISERFS_ERROR_FS );

        if ( old_magic ) {
	    // filesystem created under 3.5.x found
	    if (convert_reiserfs (s)) {
		reiserfs_warning("reiserfs: converting 3.5.x filesystem to the new format\n") ;
		// after this 3.5.x will not be able to mount this partition
		memcpy (rs->s_magic, REISER2FS_SUPER_MAGIC_STRING, 
			sizeof (REISER2FS_SUPER_MAGIC_STRING));

		reiserfs_convert_objectid_map_v1(s) ;
		set_bit(REISERFS_3_6, &(s->u.reiserfs_sb.s_properties));
		clear_bit(REISERFS_3_5, &(s->u.reiserfs_sb.s_properties));
	    } else {
		reiserfs_warning("reiserfs: using 3.5.x disk format\n") ;
	    }
	}

	journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB (s));
	journal_end(&th, s, 1) ;
	
	/* look for files which were to be removed in previous session */
	finish_unfinished (s);

	s->s_dirt = 0;
    } else {
	if ( old_magic ) {
	    reiserfs_warning("reiserfs: using 3.5.x disk format\n") ;
	}
    }
    // mark hash in super block: it could be unset. overwrite should be ok
    set_sb_hash_function_code( rs, function2code(s->u.reiserfs_sb.s_hash_function ) );

    handle_attrs( s );

    reiserfs_proc_info_init( s );
    reiserfs_proc_register( s, "version", reiserfs_version_in_proc );
    reiserfs_proc_register( s, "super", reiserfs_super_in_proc );
    reiserfs_proc_register( s, "per-level", reiserfs_per_level_in_proc );
    reiserfs_proc_register( s, "bitmap", reiserfs_bitmap_in_proc );
    reiserfs_proc_register( s, "on-disk-super", reiserfs_on_disk_super_in_proc );
    reiserfs_proc_register( s, "oidmap", reiserfs_oidmap_in_proc );
    reiserfs_proc_register( s, "journal", reiserfs_journal_in_proc );
    init_waitqueue_head (&(s->u.reiserfs_sb.s_wait));

    printk("%s\n", reiserfs_get_version_string()) ;
    return s;

 error:
    if (jinit_done) { /* kill the commit thread, free journal ram */
	journal_release_error(NULL, s) ;
    }
    if (SB_DISK_SUPER_BLOCK (s)) {
	for (j = 0; j < SB_BMAP_NR (s); j ++) {
	    if (SB_AP_BITMAP (s))
		brelse (SB_AP_BITMAP (s)[j]);
	}
	if (SB_AP_BITMAP (s))
	    reiserfs_kfree (SB_AP_BITMAP (s), sizeof (struct buffer_head *) * SB_BMAP_NR (s), s);
    }
    if (SB_BUFFER_WITH_SB (s))
	brelse(SB_BUFFER_WITH_SB (s));

    return NULL;
}
コード例 #26
0
ファイル: objectid.c プロジェクト: chinnyannieb/empeg-hijack
/* makes object identifier unused */
void	reiserfs_release_objectid (struct reiserfs_transaction_handle *th, 
				   unsigned long objectid_to_release, struct super_block * s)
{
  struct reiserfs_super_block * disk_sb;
  unsigned long * objectid_map;
  int i = 0;


  /* return; */

  /* mark_buffer_dirty (SB_BUFFER_WITH_SB (s), 1);  journal victim */
  journal_mark_dirty(th, s, SB_BUFFER_WITH_SB (s)); 
  s->s_dirt = 1;

  /* let disk_sb serve as a convenient shorthand pointing to the Reiserfs
     Specific portion of the super_block */
  disk_sb = SB_DISK_SUPER_BLOCK (s);

  /* This means/assumes that the objectid map immediately follows
     the superblock in memory. */
  objectid_map = (unsigned long *)(disk_sb + 1);

  /* start at the beginning of the objectid map (i = 0) and go to the
     end of it (i = disk_sb->s_oid_cursize).  Linear search is what we use,
     though it is possible that binary search would be more efficient
     after performing lots of deletions (which is when oids is large.)
     We only check even i's. */
  while (i < disk_sb->s_oid_cursize) {
    if (objectid_to_release == objectid_map[i]) {
      if (i == 0)
	reiserfs_panic (s, "vs-15000: reiserfs_release_objectid: trying to free root object id (%lu)",
			    objectid_to_release);
      /* This incrementation unallocates the objectid. */
      objectid_map[i]++;
      /* Did we unallocate the last member of an odd sequence, and can shrink oids? */
      if (objectid_map[i] == objectid_map[i+1]) {
	/* shrink objectid map */
	memmove (objectid_map + i, objectid_map + i + 2, 
		 (disk_sb->s_oid_cursize - i - 2)*sizeof(unsigned long));
	disk_sb->s_oid_cursize -= 2;
#ifdef REISERFS_CHECK
	if (disk_sb->s_oid_cursize < 2 || disk_sb->s_oid_cursize > disk_sb->s_oid_maxsize)
	  reiserfs_panic (s, "vs-15005: reiserfs_release_objectid: "
			  "objectid map corrupted cur_size == %d (max == %d)",
			  disk_sb->s_oid_cursize, disk_sb->s_oid_maxsize);
#endif
      }
      return;
    }

    if (objectid_to_release > objectid_map[i] && objectid_to_release < objectid_map[i+1]) {
      /* size of objectid map is not changed */
      if (objectid_to_release + 1 == objectid_map[i+1]) {
	objectid_map[i+1]--;
	return;
      }

      if (disk_sb->s_oid_cursize == disk_sb->s_oid_maxsize)
	/* objectid map must be expanded, but there is no space */
	return;

      /* expand the objectid map*/
      memmove (objectid_map+i+3, objectid_map+i+1, (disk_sb->s_oid_cursize-i-1) * sizeof(unsigned long));
      objectid_map[i+1] = objectid_to_release;
      objectid_map[i+2] = objectid_to_release + 1;
      disk_sb->s_oid_cursize += 2;
      return;
    }
    i += 2;
  }

  reiserfs_panic (0, "vs-15010: reiserfs_release_objectid: trying to free free object id (%lu)", objectid_to_release);
}
コード例 #27
0
ファイル: super.c プロジェクト: muromec/linux-ezxdev
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;
}
コード例 #28
0
int main(int argc, char *argv[]) {
    char * bytes_count_str = NULL;
    char * devname;
    reiserfs_filsys_t fs;
    struct reiserfs_super_block * rs;

    int c;
    int error;

    struct reiserfs_super_block *sb_old;

    unsigned long block_count_new;

    print_banner ("resize_reiserfs");

    while ((c = getopt(argc, argv, "fvcqs:")) != EOF) {
        switch (c) {
        case 's' :
            if (!optarg)
                die("%s: Missing argument to -s option", argv[0]);
            bytes_count_str = optarg;
            break;
        case 'f':
            opt_force = 1;
            break;
        case 'v':
            opt_verbose++;
            break;
        case 'n':
            /* no nowrite option at this moment */
            /* opt_nowrite = 1; */
            break;
        case 'c':
            opt_safe = 1;
            break;
        case 'q':
            opt_verbose = 0;
            break;
        default:
            print_usage_and_exit ();
        }
    }

    if (optind == argc )
        print_usage_and_exit();
    devname = argv[optind];

    fs = reiserfs_open(devname, O_RDONLY, &error, 0);
    if (!fs)
        die ("%s: can not open '%s': %s", argv[0], devname, strerror(error));

    if (no_reiserfs_found (fs)) {
        die ("resize_reiserfs: no reiserfs found on the device");
    }
    if (!spread_bitmaps (fs)) {
        die ("resize_reiserfs: cannot resize reiserfs in old (not spread bitmap) format.\n");
    }

    rs = fs->s_rs;

    if(bytes_count_str) {	/* new fs size is specified by user */
        block_count_new = calc_new_fs_size(rs_block_count(rs), fs->s_blocksize, bytes_count_str);
    } else {		/* use whole device */
        block_count_new = count_blocks(devname, fs->s_blocksize, -1);
    }

    if (is_mounted (devname)) {
        reiserfs_close(fs);
        return resize_fs_online(devname, block_count_new);
    }

    if (rs_state(rs) != REISERFS_VALID_FS)
        die ("%s: the file system isn't in valid state\n", argv[0]);

    if(!valid_offset(fs->s_dev, (loff_t) block_count_new * fs->s_blocksize - 1))
        die ("%s: %s too small", argv[0], devname);

    sb_old = 0;		/* Needed to keep idiot compiler from issuing false warning */
    /* save SB for reporting */
    if(opt_verbose) {
        sb_old = getmem(SB_SIZE);
        memcpy(sb_old, SB_DISK_SUPER_BLOCK(fs), SB_SIZE);
    }

    if (block_count_new == SB_BLOCK_COUNT(fs))
        die ("%s: Calculated fs size is the same as the previous one.", argv[0]);

    if (block_count_new > SB_BLOCK_COUNT(fs))
        expand_fs(fs, block_count_new);
    else
        shrink_fs(fs, block_count_new);

    if(opt_verbose) {
        sb_report(rs, sb_old);
        freemem(sb_old);
    }

    set_state (rs, REISERFS_VALID_FS);
    bwrite_cond(SB_BUFFER_WITH_SB(fs));

    if (opt_verbose) {
        printf("\nSyncing..");
        fflush(stdout);
    }
    reiserfs_close (fs);
    if (opt_verbose)
        printf("done\n");

    return 0;
}
コード例 #29
0
int shrink_fs(reiserfs_filsys_t reiserfs, unsigned long blocks)
{
	unsigned long n_root_block;
	unsigned int bmap_nr_new;
	unsigned long int i;
	
	fs = reiserfs;
	rs = fs->s_rs;
	
	/* warn about alpha version */
	{
		int c;

		printf(
			"You are running BETA version of reiserfs shrinker.\n"
			"This version is only for testing or VERY CAREFUL use.\n"
			"Backup of you data is recommended.\n\n"
			"Do you want to continue? [y/N]:"
			);
		c = getchar();
		if (c != 'y' && c != 'Y')
			exit(1);
	}

	bmap_nr_new = (blocks - 1) / (8 * fs->s_blocksize) + 1;
	
	/* is shrinking possible ? */
	if (rs_block_count(rs) - blocks > rs_free_blocks(rs) + rs_bmap_nr(rs) - bmap_nr_new) {
	    fprintf(stderr, "resize_reiserfs: can\'t shrink fs; too many blocks already allocated\n");
	    return -1;
	}

	reiserfs_reopen(fs, O_RDWR);
	set_state (fs->s_rs, REISERFS_ERROR_FS);
	mark_buffer_uptodate(SB_BUFFER_WITH_SB(fs), 1);
	mark_buffer_dirty(SB_BUFFER_WITH_SB(fs));
	bwrite(SB_BUFFER_WITH_SB(fs));

	/* calculate number of data blocks */		
	blocks_used = 
	    SB_BLOCK_COUNT(fs)
	    - SB_FREE_BLOCKS(fs)
	    - SB_BMAP_NR(fs)
	    - SB_JOURNAL_SIZE(fs)
	    - REISERFS_DISK_OFFSET_IN_BYTES / fs->s_blocksize
	    - 2; /* superblock itself and 1 descriptor after the journal */

	bmp = reiserfs_create_bitmap(rs_block_count(rs));
	reiserfs_fetch_disk_bitmap(bmp, fs);

	unused_block = 1;

	if (opt_verbose) {
		printf("Processing the tree: ");
		fflush(stdout);
	}

	n_root_block = move_formatted_block(rs_root_block(rs), blocks, 0);
	if (n_root_block) {
		set_root_block (rs, n_root_block);
	}

	if (opt_verbose)
	    printf ("\n\nnodes processed (moved):\n"
		    "int        %lu (%lu),\n"
		    "leaves     %lu (%lu),\n" 
		    "unfm       %lu (%lu),\n"
		    "total      %lu (%lu).\n\n",
		    int_node_cnt, int_moved_cnt,
		    leaf_node_cnt, leaf_moved_cnt, 
		    unfm_node_cnt, unfm_moved_cnt,
		    (unsigned long)total_node_cnt, total_moved_cnt);

	if (block_count_mismatch) {
	    fprintf(stderr, "resize_reiserfs: data block count %lu"
		    " doesn\'t match data block count %lu from super block\n",
		    (unsigned long)total_node_cnt, blocks_used);
	}
#if 0
	printf("check for used blocks in truncated region\n");
	{
		unsigned long l;
		for (l = blocks; l < rs_block_count(rs); l++)
			if (is_block_used(bmp, l))
				printf("<%lu>", l);
		printf("\n");
	}
#endif /* 0 */

	reiserfs_free_bitmap_blocks(fs);
	
	set_free_blocks (rs, rs_free_blocks(rs) - (rs_block_count(rs) - blocks) + (rs_bmap_nr(rs) - bmap_nr_new));
	set_block_count (rs, blocks);
	set_bmap_nr (rs, bmap_nr_new);

	reiserfs_read_bitmap_blocks(fs);
	
	for (i = blocks; i < bmap_nr_new * fs->s_blocksize; i++)
		reiserfs_bitmap_set_bit(bmp, i);
#if 0
	PUT_SB_FREE_BLOCKS(s, SB_FREE_BLOCKS(s) - (SB_BLOCK_COUNT(s) - blocks) + (SB_BMAP_NR(s) - bmap_nr_new));
	PUT_SB_BLOCK_COUNT(s, blocks);
	PUT_SB_BMAP_NR(s, bmap_nr_new);
#endif
	reiserfs_flush_bitmap(bmp, fs);

	return 0;
}
コード例 #30
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;
}