1/*
2 * freefs.c --- free an ext2 filesystem
3 *
4 * Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
5 *
6 * %Begin-Header%
7 * This file may be redistributed under the terms of the GNU Public
8 * License.
9 * %End-Header%
10 */
11
12#include <stdio.h>
13#if HAVE_UNISTD_H
14#include <unistd.h>
15#endif
16
17#include "ext2_fs.h"
18#include "ext2fsP.h"
19
20static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache);
21
22void ext2fs_free(ext2_filsys fs)
23{
24	if (!fs || (fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS))
25		return;
26	if (fs->image_io != fs->io) {
27		if (fs->image_io)
28			io_channel_close(fs->image_io);
29	}
30	if (fs->io) {
31		io_channel_close(fs->io);
32	}
33	if (fs->device_name)
34		ext2fs_free_mem(&fs->device_name);
35	if (fs->super)
36		ext2fs_free_mem(&fs->super);
37	if (fs->orig_super)
38		ext2fs_free_mem(&fs->orig_super);
39	if (fs->group_desc)
40		ext2fs_free_mem(&fs->group_desc);
41	if (fs->block_map)
42		ext2fs_free_block_bitmap(fs->block_map);
43	if (fs->inode_map)
44		ext2fs_free_inode_bitmap(fs->inode_map);
45
46	if (fs->badblocks)
47		ext2fs_badblocks_list_free(fs->badblocks);
48	fs->badblocks = 0;
49
50	if (fs->dblist)
51		ext2fs_free_dblist(fs->dblist);
52
53	if (fs->icache)
54		ext2fs_free_inode_cache(fs->icache);
55
56	fs->magic = 0;
57
58	ext2fs_free_mem(&fs);
59}
60
61void ext2fs_free_generic_bitmap(ext2fs_inode_bitmap bitmap)
62{
63	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_GENERIC_BITMAP))
64		return;
65
66	bitmap->magic = 0;
67	if (bitmap->description) {
68		ext2fs_free_mem(&bitmap->description);
69		bitmap->description = 0;
70	}
71	if (bitmap->bitmap) {
72		ext2fs_free_mem(&bitmap->bitmap);
73		bitmap->bitmap = 0;
74	}
75	ext2fs_free_mem(&bitmap);
76}
77
78void ext2fs_free_inode_bitmap(ext2fs_inode_bitmap bitmap)
79{
80	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_INODE_BITMAP))
81		return;
82
83	bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
84	ext2fs_free_generic_bitmap(bitmap);
85}
86
87void ext2fs_free_block_bitmap(ext2fs_block_bitmap bitmap)
88{
89	if (!bitmap || (bitmap->magic != EXT2_ET_MAGIC_BLOCK_BITMAP))
90		return;
91
92	bitmap->magic = EXT2_ET_MAGIC_GENERIC_BITMAP;
93	ext2fs_free_generic_bitmap(bitmap);
94}
95
96/*
97 * Free the inode cache structure
98 */
99static void ext2fs_free_inode_cache(struct ext2_inode_cache *icache)
100{
101	if (--icache->refcount)
102		return;
103	if (icache->buffer)
104		ext2fs_free_mem(&icache->buffer);
105	if (icache->cache)
106		ext2fs_free_mem(&icache->cache);
107	icache->buffer_blk = 0;
108	ext2fs_free_mem(&icache);
109}
110
111/*
112 * This procedure frees a badblocks list.
113 */
114void ext2fs_u32_list_free(ext2_u32_list bb)
115{
116	if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
117		return;
118
119	if (bb->list)
120		ext2fs_free_mem(&bb->list);
121	bb->list = 0;
122	ext2fs_free_mem(&bb);
123}
124
125void ext2fs_badblocks_list_free(ext2_badblocks_list bb)
126{
127	ext2fs_u32_list_free((ext2_u32_list) bb);
128}
129
130
131/*
132 * Free a directory block list
133 */
134void ext2fs_free_dblist(ext2_dblist dblist)
135{
136	if (!dblist || (dblist->magic != EXT2_ET_MAGIC_DBLIST))
137		return;
138
139	if (dblist->list)
140		ext2fs_free_mem(&dblist->list);
141	dblist->list = 0;
142	if (dblist->fs && dblist->fs->dblist == dblist)
143		dblist->fs->dblist = 0;
144	dblist->magic = 0;
145	ext2fs_free_mem(&dblist);
146}
147
148