source: mainline/uspace/lib/ext2/libext2_filesystem.c@ d241aae

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since d241aae was d241aae, checked in by Martin Sucha <sucha14@…>, 14 years ago

Add support for reading ext2 block group descriptors

  • Property mode set to 100644
File size: 4.8 KB
Line 
1/*
2 * Copyright (c) 2011 Martin Sucha
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup libext2
30 * @{
31 */
32/**
33 * @file
34 */
35
36#include "libext2_filesystem.h"
37#include "libext2_superblock.h"
38#include "libext2_block_group.h"
39#include <errno.h>
40#include <libblock.h>
41#include <malloc.h>
42
43/**
44 * Initialize an instance of filesystem on the device.
45 * This function reads superblock from the device and
46 * initializes libblock cache with appropriate logical block size.
47 *
48 * @param fs Pointer to ext2_filesystem_t to initialize
49 * @param devmap_handle Device handle of the block device
50 *
51 * @return EOK on success or negative error code on failure
52 */
53int ext2_filesystem_init(ext2_filesystem_t *fs, devmap_handle_t devmap_handle)
54{
55 int rc;
56 ext2_superblock_t *temp_superblock;
57 size_t block_size;
58
59 fs->device = devmap_handle;
60
61 rc = block_init(fs->device, 2048);
62 if (rc != EOK) {
63 return rc;
64 }
65
66 rc = ext2_superblock_read_direct(fs->device, &temp_superblock);
67 if (rc != EOK) {
68 block_fini(fs->device);
69 return rc;
70 }
71
72 block_size = ext2_superblock_get_block_size(temp_superblock);
73
74 if (block_size > EXT2_MAX_BLOCK_SIZE) {
75 block_fini(fs->device);
76 return ENOTSUP;
77 }
78
79 rc = block_cache_init(devmap_handle, block_size, 0, CACHE_MODE_WT);
80 if (rc != EOK) {
81 block_fini(fs->device);
82 return rc;
83 }
84
85 fs->superblock = temp_superblock;
86
87 return EOK;
88}
89
90/**
91 * Check filesystem for sanity
92 *
93 * @param fs Pointer to ext2_filesystem_t to check
94 * @return EOK on success or negative error code on failure
95 */
96int ext2_filesystem_check_sanity(ext2_filesystem_t *fs)
97{
98 int rc;
99
100 rc = ext2_superblock_check_sanity(fs->superblock);
101 if (rc != EOK) {
102 return rc;
103 }
104
105 return EOK;
106}
107
108/**
109 * Get a reference to block descriptor
110 *
111 * @param fs Pointer to filesystem information
112 * @param bgid Index of block group to find
113 * @param ref Pointer where to store pointer to block group reference
114 *
115 * @return EOK on success or negative error code on failure
116 */
117int ext2_filesystem_get_block_group_ref(ext2_filesystem_t *fs, uint32_t bgid,
118 ext2_block_group_ref_t **ref)
119{
120 int rc;
121 aoff64_t block_id;
122 uint32_t descriptors_per_block;
123 size_t offset;
124 ext2_block_group_ref_t *newref;
125
126 newref = malloc(sizeof(ext2_block_group_ref_t));
127 if (newref == NULL) {
128 return ENOMEM;
129 }
130
131 descriptors_per_block = ext2_superblock_get_block_size(fs->superblock)
132 / EXT2_BLOCK_GROUP_DESCRIPTOR_SIZE;
133
134 // Block group descriptor table starts at the next block after superblock
135 block_id = ext2_superblock_get_first_block(fs->superblock) + 1;
136
137 // Find the block containing the descriptor we are looking for
138 block_id += bgid / descriptors_per_block;
139 offset = (bgid % descriptors_per_block) * EXT2_BLOCK_GROUP_DESCRIPTOR_SIZE;
140
141 rc = block_get(&newref->block, fs->device, block_id, 0);
142 if (rc != EOK) {
143 free(newref);
144 return rc;
145 }
146
147 newref->block_group = newref->block->data + offset;
148
149 *ref = newref;
150
151 return EOK;
152}
153
154/**
155 * Free a reference to block group
156 *
157 * @param ref Pointer to block group reference to free
158 *
159 * @return EOK on success or negative error code on failure
160 */
161int ext2_filesystem_put_block_group_ref(ext2_block_group_ref_t *ref)
162{
163 int rc;
164
165 rc = block_put(ref->block);
166 free(ref);
167
168 return rc;
169}
170
171/**
172 * Finalize an instance of filesystem
173 *
174 * @param fs Pointer to ext2_filesystem_t to finalize
175 */
176void ext2_filesystem_fini(ext2_filesystem_t *fs)
177{
178 free(fs->superblock);
179 block_fini(fs->device);
180}
181
182
183/** @}
184 */
Note: See TracBrowser for help on using the repository browser.