2 * closefs.c --- close an ext2 filesystem
4 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
7 * This file may be redistributed under the terms of the GNU Public
21 #include <linux/ext2_fs.h>
25 errcode_t
ext2fs_flush(ext2_filsys fs
)
31 unsigned long fs_state
;
32 struct ext2_super_block
*super_shadow
= 0;
33 struct ext2_group_desc
*group_shadow
= 0;
34 struct ext2_group_desc
*s
, *t
;
36 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
38 fs_state
= fs
->super
->s_state
;
40 fs
->super
->s_wtime
= time(NULL
);
41 if (fs
->flags
& EXT2_FLAG_SWAP_BYTES
) {
43 if (!(super_shadow
= malloc(SUPERBLOCK_SIZE
)))
45 if (!(group_shadow
= malloc(fs
->blocksize
*fs
->desc_blocks
)))
47 memset(group_shadow
, 0, fs
->blocksize
*fs
->desc_blocks
);
49 /* swap the superblock */
50 *super_shadow
= *fs
->super
;
51 ext2fs_swap_super(super_shadow
);
53 /* swap the group descriptors */
54 for (j
=0, s
=fs
->group_desc
, t
=group_shadow
;
55 j
< fs
->group_desc_count
; j
++, t
++, s
++) {
57 ext2fs_swap_group_desc(t
);
60 super_shadow
= fs
->super
;
61 group_shadow
= fs
->group_desc
;
65 * Write out master superblock. This has to be done
66 * separately, since it is located at a fixed location
67 * (SUPERBLOCK_OFFSET).
69 io_channel_set_blksize(fs
->io
, SUPERBLOCK_OFFSET
);
70 retval
= io_channel_write_blk(fs
->io
, 1, -SUPERBLOCK_SIZE
,
74 io_channel_set_blksize(fs
->io
, fs
->blocksize
);
77 * Set the state of the FS to be non-valid. (The state has
78 * already been backed up earlier, and will be restored when
81 fs
->super
->s_state
&= ~EXT2_VALID_FS
;
82 if (fs
->flags
& EXT2_FLAG_SWAP_BYTES
) {
83 *super_shadow
= *fs
->super
;
84 ext2fs_swap_super(super_shadow
);
88 * Write out the master group descriptors, and the backup
89 * superblocks and group descriptors.
91 group_block
= fs
->super
->s_first_data_block
;
92 maxgroup
= (fs
->flags
& EXT2_FLAG_MASTER_SB_ONLY
) ? 1 :
94 for (i
= 0; i
< maxgroup
; i
++) {
96 retval
= io_channel_write_blk(fs
->io
, group_block
,
102 group_ptr
= (char *) group_shadow
;
103 for (j
=0; j
< fs
->desc_blocks
; j
++) {
104 retval
= io_channel_write_blk(fs
->io
,
109 group_ptr
+= fs
->blocksize
;
111 group_block
+= EXT2_BLOCKS_PER_GROUP(fs
->super
);
115 * If the write_bitmaps() function is present, call it to
116 * flush the bitmaps. This is done this way so that a simple
117 * program that doesn't mess with the bitmaps doesn't need to
118 * drag in the bitmaps.c code.
120 if (fs
->write_bitmaps
) {
121 retval
= fs
->write_bitmaps(fs
);
127 fs
->super
->s_state
= fs_state
;
128 if (fs
->flags
& EXT2_FLAG_SWAP_BYTES
) {
137 errcode_t
ext2fs_close(ext2_filsys fs
)
141 EXT2_CHECK_MAGIC(fs
, EXT2_ET_MAGIC_EXT2FS_FILSYS
);
143 if (fs
->flags
& EXT2_FLAG_DIRTY
) {
144 retval
= ext2fs_flush(fs
);
148 if (fs
->write_bitmaps
) {
149 retval
= fs
->write_bitmaps(fs
);
158 * This procedure frees a badblocks list.
160 void ext2fs_badblocks_list_free(ext2_badblocks_list bb
)
162 if (bb
->magic
!= EXT2_ET_MAGIC_BADBLOCKS_LIST
)
172 * Close a directory block list
174 void ext2fs_free_dblist(ext2_dblist dblist
)
176 if (!dblist
|| (dblist
->magic
!= EXT2_ET_MAGIC_DBLIST
))
182 if (dblist
->fs
&& dblist
->fs
->dblist
== dblist
)
183 dblist
->fs
->dblist
= 0;