home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1998 February / PCOnline_02_1998.iso / filesbbs / win95 / ext2tool.exe / EXT2FS / EXPANDIR.C < prev    next >
C/C++ Source or Header  |  1995-05-10  |  3KB  |  120 lines

  1. /*
  2.  * expand.c --- expand an ext2fs directory
  3.  * 
  4.  * Copyright (C) 1993 Theodore Ts'o.  This file may be redistributed
  5.  * under the terms of the GNU Public License.
  6.  */
  7.  
  8. #include <stdio.h>
  9. #include <string.h>
  10. #include <unistd.h>
  11. #include <stdlib.h>
  12. #include <errno.h>
  13.  
  14. #include <linux/ext2_fs.h>
  15.  
  16. #include "ext2fs.h"
  17.  
  18. struct expand_dir_struct {
  19.     int    done;
  20.     errcode_t    err;
  21. };
  22.  
  23. static int expand_dir_proc(ext2_filsys fs,
  24.                blk_t    *blocknr,
  25.                int    blockcnt,
  26.                void    *private)
  27. {
  28.     struct expand_dir_struct *es = (struct expand_dir_struct *) private;
  29.     blk_t    new_blk;
  30.     static blk_t    last_blk = 0;
  31.     char        *block;
  32.     errcode_t    retval;
  33.     int        group;
  34.     
  35.     if (*blocknr) {
  36.         last_blk = *blocknr;
  37.         return 0;
  38.     }
  39.     retval = ext2fs_new_block(fs, last_blk, 0, &new_blk);
  40.     if (retval) {
  41.         es->err = retval;
  42.         return BLOCK_ABORT;
  43.     }
  44.     if (blockcnt > 0) {
  45.         retval = ext2fs_new_dir_block(fs, 0, 0, &block);
  46.         if (retval) {
  47.             es->err = retval;
  48.             return BLOCK_ABORT;
  49.         }
  50.         es->done = 1;
  51.     } else {
  52.         block = malloc(fs->blocksize);
  53.         if (!block) {
  54.             es->err = ENOMEM;
  55.             return BLOCK_ABORT;
  56.         }
  57.         memset(block, 0, fs->blocksize);
  58.     }    
  59.     retval = io_channel_write_blk(fs->io, new_blk, 1, block);
  60.     if (retval) {
  61.         es->err = retval;
  62.         return BLOCK_ABORT;
  63.     }
  64.     free(block);
  65.     *blocknr = new_blk;
  66.     ext2fs_mark_block_bitmap(fs->block_map, new_blk);
  67.     ext2fs_mark_bb_dirty(fs);
  68.     group = ext2fs_group_of_blk(fs, new_blk);
  69.     fs->group_desc[group].bg_free_blocks_count--;
  70.     fs->super->s_free_blocks_count--;
  71.     ext2fs_mark_super_dirty(fs);
  72.     if (es->done)
  73.         return (BLOCK_CHANGED | BLOCK_ABORT);
  74.     else
  75.         return BLOCK_CHANGED;
  76. }
  77.  
  78. errcode_t ext2fs_expand_dir(ext2_filsys fs, ino_t dir)
  79. {
  80.     errcode_t    retval;
  81.     struct expand_dir_struct es;
  82.     struct ext2_inode    inode;
  83.     
  84.     EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
  85.  
  86.     if (!(fs->flags & EXT2_FLAG_RW))
  87.         return EXT2_ET_RO_FILSYS;
  88.  
  89.     retval = ext2fs_check_directory(fs, dir);
  90.     if (retval)
  91.         return retval;
  92.     
  93.     es.done = 0;
  94.     es.err = 0;
  95.     
  96.     retval = ext2fs_block_iterate(fs, dir, BLOCK_FLAG_APPEND,
  97.                       0, expand_dir_proc, &es);
  98.  
  99.     if (es.err)
  100.         return es.err;
  101.     if (!es.done)
  102.         return EXT2_ET_EXPAND_DIR_ERR;
  103.  
  104.     /*
  105.      * Update the size and block count fields in the inode.
  106.      */
  107.     retval = ext2fs_read_inode(fs, dir, &inode);
  108.     if (retval)
  109.         return retval;
  110.     
  111.     inode.i_size += fs->blocksize;
  112.     inode.i_blocks += fs->blocksize / 512;
  113.  
  114.     retval = ext2fs_write_inode(fs, dir, &inode);
  115.     if (retval)
  116.         return retval;
  117.  
  118.     return 0;
  119. }
  120.