/* * closefs.c --- close an ext2 filesystem * * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be redistributed * under the terms of the GNU Public License. */ #include #include #include #include #include #include #include "ext2fs.h" errcode_t ext2fs_flush(ext2_filsys fs) { int i,j; int group_block; errcode_t retval; char *group_ptr; unsigned long fs_state; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); /* * Write out master superblock. This has to be done * separately, since it is located at a fixed location * (SUPERBLOCK_OFFSET). */ fs->super->s_wtime = time(NULL); io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET); retval = io_channel_write_blk(fs->io, 1, -SUPERBLOCK_SIZE, fs->super); if (retval) return retval; io_channel_set_blksize(fs->io, fs->blocksize); /* * Save the state of the FS and set it to non valid for the * backup superblocks */ fs_state = fs->super->s_state; fs->super->s_state &= ~EXT2_VALID_FS; /* * Write out the master group descriptors, and the backup * superblocks and group descriptors. */ group_block = fs->super->s_first_data_block; for (i = 0; i < fs->group_desc_count; i++) { if (i !=0 ) { retval = io_channel_write_blk(fs->io, group_block, -SUPERBLOCK_SIZE, fs->super); if (retval) { fs->super->s_state = fs_state; return retval; } } group_ptr = (char *) fs->group_desc; for (j=0; j < fs->desc_blocks; j++) { retval = io_channel_write_blk(fs->io, group_block+1+j, 1, group_ptr); if (retval) { fs->super->s_state = fs_state; return retval; } group_ptr += fs->blocksize; } group_block += EXT2_BLOCKS_PER_GROUP(fs->super); } fs->super->s_state = fs_state; /* * If the write_bitmaps() function is present, call it to * flush the bitmaps. This is done this way so that a simple * program that doesn't mess with the bitmaps doesn't need to * drag in the bitmaps.c code. */ if (fs->write_bitmaps) { retval = fs->write_bitmaps(fs); if (retval) return retval; } return 0; } errcode_t ext2fs_close(ext2_filsys fs) { errcode_t retval; EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); if (fs->flags & EXT2_FLAG_DIRTY) { retval = ext2fs_flush(fs); if (retval) return retval; } ext2fs_free(fs); return 0; }