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