The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/fs/reiserfs/resize.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* 
    2  * Copyright 2000-2002 by Hans Reiser, licensing governed by reiserfs/README
    3  */
    4  
    5 /* 
    6  * Written by Alexander Zarochentcev.
    7  *
    8  * The kernel part of the (on-line) reiserfs resizer.
    9  */
   10 
   11 #include <linux/kernel.h>
   12 #include <linux/vmalloc.h>
   13 #include <linux/locks.h>
   14 #include <linux/string.h>
   15 #include <linux/errno.h>
   16 #include <linux/reiserfs_fs.h>
   17 #include <linux/reiserfs_fs_sb.h>
   18 
   19 int reiserfs_resize (struct super_block * s, unsigned long block_count_new)
   20 {
   21         struct reiserfs_super_block * sb;
   22         struct reiserfs_bitmap_info *bitmap;
   23         struct buffer_head * bh;
   24         struct reiserfs_transaction_handle th;
   25         unsigned int bmap_nr_new, bmap_nr;
   26         unsigned int block_r_new, block_r;
   27         
   28         struct reiserfs_list_bitmap * jb;
   29         struct reiserfs_list_bitmap jbitmap[JOURNAL_NUM_BITMAPS];
   30         
   31         unsigned long int block_count, free_blocks;
   32         int i;
   33         int copy_size ;
   34 
   35         sb = SB_DISK_SUPER_BLOCK(s);
   36 
   37         if (SB_BLOCK_COUNT(s) >= block_count_new) {
   38                 reiserfs_warning(s, "can\'t shrink filesystem on-line\n");
   39                 return -EINVAL;
   40         }
   41 
   42         /* check the device size */
   43         bh = sb_bread(s, block_count_new - 1);
   44         if (!bh) {
   45                 reiserfs_warning(s, "reiserfs_resize: can\'t read last block\n");
   46                 return -EINVAL;
   47         }       
   48         bforget(bh);
   49 
   50         /* old disk layout detection; those partitions can be mounted, but
   51          * cannot be resized */
   52         if (SB_BUFFER_WITH_SB(s)->b_blocknr *   SB_BUFFER_WITH_SB(s)->b_size 
   53                 != REISERFS_DISK_OFFSET_IN_BYTES ) {
   54                 reiserfs_warning(s, "reiserfs_resize: unable to resize a reiserfs without distributed bitmap (fs version < 3.5.12)\n");
   55                 return -ENOTSUPP;
   56         }
   57        
   58         /* count used bits in last bitmap block */
   59         block_r = SB_BLOCK_COUNT(s) -
   60                 (SB_BMAP_NR(s) - 1) * s->s_blocksize * 8;
   61         
   62         /* count bitmap blocks in new fs */
   63         bmap_nr_new = block_count_new / ( s->s_blocksize * 8 );
   64         block_r_new = block_count_new - bmap_nr_new * s->s_blocksize * 8;
   65         if (block_r_new) 
   66                 bmap_nr_new++;
   67         else
   68                 block_r_new = s->s_blocksize * 8;
   69 
   70         /* save old values */
   71         block_count = SB_BLOCK_COUNT(s);
   72         bmap_nr     = SB_BMAP_NR(s);
   73 
   74         /* resizing of reiserfs bitmaps (journal and real), if needed */
   75         if (bmap_nr_new > bmap_nr) {        
   76             /* reallocate journal bitmaps */
   77             if (reiserfs_allocate_list_bitmaps(s, jbitmap, bmap_nr_new) < 0) {
   78                 reiserfs_warning(s, "reiserfs_resize: unable to allocate memory for journal bitmaps\n");
   79                 unlock_super(s) ;
   80                 return -ENOMEM ;
   81             }
   82             /* the new journal bitmaps are zero filled, now we copy in the bitmap
   83             ** node pointers from the old journal bitmap structs, and then
   84             ** transfer the new data structures into the journal struct.
   85             **
   86             ** using the copy_size var below allows this code to work for
   87             ** both shrinking and expanding the FS.
   88             */
   89             copy_size = bmap_nr_new < bmap_nr ? bmap_nr_new : bmap_nr ;
   90             copy_size = copy_size * sizeof(struct reiserfs_list_bitmap_node *) ;
   91             for (i = 0 ; i < JOURNAL_NUM_BITMAPS ; i++) {
   92                 struct reiserfs_bitmap_node **node_tmp ;
   93                 jb = SB_JOURNAL(s)->j_list_bitmap + i ;
   94                 memcpy(jbitmap[i].bitmaps, jb->bitmaps, copy_size) ;
   95 
   96                 /* just in case vfree schedules on us, copy the new
   97                 ** pointer into the journal struct before freeing the 
   98                 ** old one
   99                 */
  100                 node_tmp = jb->bitmaps ;
  101                 jb->bitmaps = jbitmap[i].bitmaps ;
  102                 vfree(node_tmp) ;
  103             }   
  104         
  105             /* allocate additional bitmap blocks, reallocate array of bitmap
  106              * block pointers */
  107             bitmap = vmalloc(sizeof(struct reiserfs_bitmap_info) * bmap_nr_new);
  108             if (!bitmap) {
  109                 reiserfs_warning(s, "reiserfs_resize: unable to allocate memory.\n");
  110                 return -ENOMEM;
  111             }
  112             for (i = 0; i < bmap_nr; i++)
  113                 bitmap[i] = SB_AP_BITMAP(s)[i];
  114             for (i = bmap_nr; i < bmap_nr_new; i++) {
  115                 bitmap[i].bh = sb_getblk(s, i * s->s_blocksize * 8);
  116                 memset(bitmap[i].bh->b_data, 0, sb_blocksize(sb));
  117                 reiserfs_test_and_set_le_bit(0, bitmap[i].bh->b_data);
  118 
  119                 mark_buffer_dirty(bitmap[i].bh) ;
  120                 mark_buffer_uptodate(bitmap[i].bh, 1);
  121                 ll_rw_block(WRITE, 1, &bitmap[i].bh);
  122                 wait_on_buffer(bitmap[i].bh);
  123                 bitmap[i].first_zero_hint=1;
  124                 bitmap[i].free_count = s->s_blocksize * 8 - 1;
  125             }   
  126             /* free old bitmap blocks array */
  127             vfree(SB_AP_BITMAP(s)); 
  128                            
  129             SB_AP_BITMAP(s) = bitmap;
  130         }
  131         
  132         /* begin transaction */
  133         journal_begin(&th, s, 10);
  134 
  135         /* correct last bitmap blocks in old and new disk layout */
  136         reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr - 1].bh, 1);
  137         for (i = block_r; i < s->s_blocksize * 8; i++)
  138             reiserfs_test_and_clear_le_bit(i, 
  139                                            SB_AP_BITMAP(s)[bmap_nr - 1].bh->b_data);
  140         SB_AP_BITMAP(s)[bmap_nr - 1].free_count += s->s_blocksize * 8 - block_r;
  141         if ( !SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint)
  142             SB_AP_BITMAP(s)[bmap_nr - 1].first_zero_hint = block_r;
  143         journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr - 1].bh);
  144 
  145         reiserfs_prepare_for_journal(s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh, 1);
  146         for (i = block_r_new; i < s->s_blocksize * 8; i++)
  147             reiserfs_test_and_set_le_bit(i,
  148                                          SB_AP_BITMAP(s)[bmap_nr_new - 1].bh->b_data);
  149         journal_mark_dirty(&th, s, SB_AP_BITMAP(s)[bmap_nr_new - 1].bh);
  150 
  151         SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count -= s->s_blocksize * 8 - block_r_new;
  152         /* Extreme case where last bitmap is the only valid block in itself. */
  153         if ( !SB_AP_BITMAP(s)[bmap_nr_new - 1].free_count )
  154             SB_AP_BITMAP(s)[bmap_nr_new - 1].first_zero_hint = 0;
  155         /* update super */
  156         reiserfs_prepare_for_journal(s, SB_BUFFER_WITH_SB(s), 1) ;
  157         free_blocks = SB_FREE_BLOCKS(s);
  158         PUT_SB_FREE_BLOCKS(s, free_blocks + (block_count_new - block_count - (bmap_nr_new - bmap_nr)));
  159         PUT_SB_BLOCK_COUNT(s, block_count_new);
  160         PUT_SB_BMAP_NR(s, bmap_nr_new);
  161         s->s_dirt = 1;
  162 
  163         journal_mark_dirty(&th, s, SB_BUFFER_WITH_SB(s));
  164         
  165         SB_JOURNAL(s)->j_must_wait = 1;
  166         journal_end(&th, s, 10);
  167 
  168         return 0;
  169 }
  170 

Cache object: d3dca14f275d6ac89b87a2f744211bd6


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.