closefs.c revision f3db3566b5e1342e49dffc5ec3f418a838584194
13839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o/* 23839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * closefs.c --- close an ext2 filesystem 33839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * 43839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Copyright (C) 1993, 1994 Theodore Ts'o. This file may be redistributed 53839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * under the terms of the GNU Public License. 63839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 73839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 83839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdio.h> 93839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <unistd.h> 103839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <stdlib.h> 113839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <time.h> 123839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 133839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include <linux/ext2_fs.h> 143839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 153839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o#include "ext2fs.h" 163839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 173839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oerrcode_t ext2fs_flush(ext2_filsys fs) 183839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 193839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int i,j; 203839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o int group_block; 213839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 223839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o char *group_ptr; 23f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o unsigned long fs_state; 243839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 25f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 26f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 273839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 283839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Write out master superblock. This has to be done 293839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * separately, since it is located at a fixed location 303839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * (SUPERBLOCK_OFFSET). 313839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 323839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fs->super->s_wtime = time(NULL); 333839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o io_channel_set_blksize(fs->io, SUPERBLOCK_OFFSET); 343839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = io_channel_write_blk(fs->io, 1, -SUPERBLOCK_SIZE, fs->super); 353839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) 363839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return retval; 373839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o io_channel_set_blksize(fs->io, fs->blocksize); 383839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 393839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 40f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * Save the state of the FS and set it to non valid for the 41f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o * backup superblocks 42f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o */ 43f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o fs_state = fs->super->s_state; 44f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o fs->super->s_state &= ~EXT2_VALID_FS; 45f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 46f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o /* 473839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * Write out the master group descriptors, and the backup 483839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * superblocks and group descriptors. 493839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 503839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o group_block = fs->super->s_first_data_block; 513839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o for (i = 0; i < fs->group_desc_count; i++) { 523839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (i !=0 ) { 533839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = io_channel_write_blk(fs->io, group_block, 543839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o -SUPERBLOCK_SIZE, 553839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o fs->super); 56f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (retval) { 57f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o fs->super->s_state = fs_state; 583839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return retval; 59f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 603839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 613839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o group_ptr = (char *) fs->group_desc; 623839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o for (j=0; j < fs->desc_blocks; j++) { 633839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = io_channel_write_blk(fs->io, 643839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o group_block+1+j, 1, 653839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o group_ptr); 66f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o if (retval) { 67f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o fs->super->s_state = fs_state; 683839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return retval; 69f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o } 703839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o group_ptr += fs->blocksize; 713839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 723839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o group_block += EXT2_BLOCKS_PER_GROUP(fs->super); 733839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 743839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 75f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o fs->super->s_state = fs_state; 76f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 773839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o /* 783839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * If the write_bitmaps() function is present, call it to 793839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * flush the bitmaps. This is done this way so that a simple 803839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * program that doesn't mess with the bitmaps doesn't need to 813839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o * drag in the bitmaps.c code. 823839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o */ 833839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (fs->write_bitmaps) { 843839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = fs->write_bitmaps(fs); 853839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) 863839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return retval; 873839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 883839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 893839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 903839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 913839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 923839e65723771b85975f4263102dd3ceec4523cTheodore Ts'oerrcode_t ext2fs_close(ext2_filsys fs) 933839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o{ 943839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o errcode_t retval; 953839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o 96f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS); 97f3db3566b5e1342e49dffc5ec3f418a838584194Theodore Ts'o 983839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (fs->flags & EXT2_FLAG_DIRTY) { 993839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o retval = ext2fs_flush(fs); 1003839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o if (retval) 1013839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return retval; 1023839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o } 1033839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o ext2fs_free(fs); 1043839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o return 0; 1053839e65723771b85975f4263102dd3ceec4523cTheodore Ts'o} 106