AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
block.c
Go to the documentation of this file.
1
5
6#include <ext2.h>
7#include <ds/bitmap.h>
8
19int ext2_io(struct ext2 *desc, int write, off_t off, size_t size, void *buf)
20{
21 ssize_t r = write ? vfs_write(desc->supernode, off, size, buf) :
22 vfs_read(desc->supernode, off, size, buf);
23
24 return r == (ssize_t) size ? 0 : r < 0 ? (int) r : -EIO;
25}
26
35{
36 uint32_t bgd_table = (desc->bs == 1024)? 2048 : desc->bs;
37 size_t bgds_size = desc->ngroups * sizeof(struct ext2_group);
38 return ext2_io(desc, 1, bgd_table, bgds_size, desc->groups);
39}
40
49int ext2_block_read(struct ext2 *desc, uint32_t number, void *buf)
50{
51 return ext2_io(desc, 0, (off_t) number * desc->bs, desc->bs, buf);
52}
53
62int ext2_block_write(struct ext2 *desc, uint32_t number, void *buf)
63{
64 return ext2_io(desc, 1, (off_t) number * desc->bs, desc->bs, buf);
65}
66
77int ext2_block_alloc(struct ext2 *desc, uint32_t *block)
78{
79 uint32_t *buf = kmalloc(desc->bs, &M_BUFFER, 0);
80 uint32_t idx = 0, group = 0;
81 struct bitmap bm = {0};
82 int err = -ENOSPC;
83
84 if (!buf)
85 return -ENOMEM;
86
87 for (unsigned i = 0; i < desc->ngroups; ++i) {
88 if (!desc->groups[i].free_blocks)
89 continue;
90
91 if ((err = ext2_block_read(desc, desc->groups[i].bmap, buf)))
92 goto done;
93
94 bm.map = buf;
95 bm.max_idx = desc->superblock->gblocks;
96
97 /* look for a free block in this group */
98 for (idx = 0; idx < bm.max_idx && bitmap_check(&bm, idx); ++idx);
99
100 if (idx < bm.max_idx) {
101 group = i;
102 err = 0;
103 break;
104 }
105
106 err = -ENOSPC;
107 }
108
109 if (err)
110 goto done;
111
112 bitmap_set(&bm, idx);
113
114 if ((err = ext2_block_write(desc, desc->groups[group].bmap, buf)))
115 goto done;
116
117 /* one block fewer free, in the group and the filesystem */
118 desc->groups[group].free_blocks--;
119 desc->superblock->free_blocks--;
120
121 if ((err = ext2_bgd_table_rewrite(desc)) || (err = ext2_superblock_rewrite(desc)))
122 goto done;
123
124 /* block bitmaps start at the first data block (1 for 1K blocks) */
125 *block = desc->superblock->dblock + idx + group * desc->superblock->gblocks;
126
127 /* a new block starts zeroed */
128 memset(buf, 0, desc->bs);
129 err = ext2_block_write(desc, *block, buf);
130
131done:
132 kfree(buf);
133 return err;
134}
135
145int ext2_block_free(struct ext2 *desc, uint32_t block)
146{
147 /* block bitmaps start at the first data block (1 for 1K blocks) */
148 if (block < desc->superblock->dblock || block >= desc->superblock->nblocks)
149 return -EINVAL;
150
151 uint32_t rel = block - desc->superblock->dblock;
152 uint32_t group = rel / desc->superblock->gblocks;
153
154 uint32_t *buf = kmalloc(desc->bs, &M_BUFFER, 0);
155 struct bitmap bm = {0};
156 int err;
157
158 if (!buf)
159 return -ENOMEM;
160
161 if ((err = ext2_block_read(desc, desc->groups[group].bmap, buf)))
162 goto done;
163
164 bm.map = buf;
165 uint32_t block_idx = rel % desc->superblock->gblocks;
166
167 bitmap_clear(&bm, block_idx);
168
169 if ((err = ext2_block_write(desc, desc->groups[group].bmap, buf)))
170 goto done;
171
172 /* one block more free, in the group and the filesystem */
173 desc->groups[group].free_blocks++;
174 desc->superblock->free_blocks++;
175
176 if (!(err = ext2_bgd_table_rewrite(desc)))
177 err = ext2_superblock_rewrite(desc);
178
179done:
180 kfree(buf);
181 return err;
182}
int ext2_block_free(struct ext2 *desc, uint32_t block)
Frees a block: its bit is cleared in its group's block bitmap, and the free counts go up.
Definition block.c:145
int ext2_block_write(struct ext2 *desc, uint32_t number, void *buf)
Writes a block to the disk.
Definition block.c:62
int ext2_io(struct ext2 *desc, int write, off_t off, size_t size, void *buf)
Reads or writes bytes of the filesystem's disk, all of them.
Definition block.c:19
int ext2_bgd_table_rewrite(struct ext2 *desc)
Writes the block group descriptor table back to the disk, after a change to a group's counts.
Definition block.c:34
int ext2_block_read(struct ext2 *desc, uint32_t number, void *buf)
Reads a block from the disk.
Definition block.c:49
int ext2_block_alloc(struct ext2 *desc, uint32_t *block)
Allocates a free block: its bit is set in its group's block bitmap, the free counts go down,...
Definition block.c:77
int ext2_superblock_rewrite(struct ext2 *desc)
Writes the in-memory copy of the superblock back to the disk, after a change to its counts of free bl...
Definition super.c:14
void * kmalloc(size_t size, struct malloc_type *type, int flags)
Allocates memory for one of the kernel's structures.
Definition kvmem.c:123
void kfree(void *)
Frees an object that kmalloc() gave.
Definition kvmem.c:146
void * memset(void *dst, int c, size_t n)
Sets n bytes to c.
Definition libc.c:23
ssize_t vfs_read(struct vnode *vnode, off_t off, size_t size, void *buf)
Reads from a vnode into a kernel buffer.
Definition read.c:52
unsigned int uint32_t
Definition stddef.h:22
A bitmap: its blocks, and its last bit's index.
Definition bitmap.h:17
size_t max_idx
Definition bitmap.h:19
bitmap_t * map
Definition bitmap.h:18
A block group descriptor, as it is on the disk.
Definition ext2.h:98
uint16_t free_blocks
number of unallocated blocks
Definition ext2.h:106
uint32_t bmap
blocks bitmap
Definition ext2.h:100
uint32_t nblocks
number of blocks
Definition ext2.h:38
uint32_t free_blocks
number of unallocated blocks
Definition ext2.h:42
uint32_t dblock
first data block
Definition ext2.h:46
uint32_t gblocks
number of blocks per block group
Definition ext2.h:52
A mounted ext2 filesystem.
Definition ext2.h:168
struct ext2_superblock * superblock
Definition ext2.h:170
struct ext2_group * groups
Definition ext2.h:171
size_t ngroups
number of block group descriptors
Definition ext2.h:174
struct vnode * supernode
Definition ext2.h:169
size_t bs
the block size
Definition ext2.h:177
long int ssize_t
Definition types.h:12
long int off_t
Definition types.h:10
ssize_t vfs_write(struct vnode *vnode, off_t off, size_t size, void *buf)
Writes to a vnode from a kernel buffer.
Definition write.c:60