resize.c
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

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