Skip to content

Commit a9477a6

Browse files
authored
Merge pull request #74 from RoyWFHuang/Feature/directory_arch
Boost the remove operation
2 parents ec8c4bc + 0c50fb5 commit a9477a6

File tree

13 files changed

+491
-276
lines changed

13 files changed

+491
-276
lines changed

README.md

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -101,48 +101,53 @@ on the type of file:
101101
```
102102
inode
103103
+-----------------------+
104-
| i_mode = IFDIR | 0755 | block 123
105-
| ei_block = 123 ----|--------> +----------------+
106-
| i_size = 4 KiB | 0 | ee_block = 0 |
107-
| i_blocks = 1 | | ee_len = 8 | block 84
108-
+-----------------------+ | ee_start = 84 |---> +-----------+
109-
|----------------| 0 | 24 (foo) |
110-
1 | ee_block = 8 | |-----------|
111-
| ee_len = 8 | 1 | 45 (bar) |
112-
| ee_start = 16 | |-----------|
113-
|----------------| | ... |
114-
| ... | |-----------|
115-
|----------------| 14 | 0 |
116-
341 | ee_block = 0 | +-----------+
117-
| ee_len = 0 |
118-
| ee_start = 0 |
119-
+----------------+
104+
| i_mode = IFDIR | 0755 | block 123 (simplefs_file_ei_block)
105+
| ei_block = 123 ----|---> +----------------+
106+
| i_size = 4 KiB | | nr_files = 7 |
107+
| i_blocks = 1 | |----------------|
108+
+-----------------------+ 0 | ee_block = 0 |
109+
| ee_len = 8 | block 84(simplefs_dir_block)
110+
| ee_start = 84 |---> +-------------+
111+
| nr_file = 2 | |nr_files = 2 |
112+
|----------------| |-------------|
113+
1 | ee_block = 8 | 0 | inode = 24 |
114+
| ee_len = 8 | | nr_blk = 1 |
115+
| ee_start = 16 | | (foo) |
116+
| nr_file = 5 | |-------------|
117+
|----------------| 1 | inode = 45 |
118+
| ... | | nr_blk = 14 |
119+
|----------------| | (bar) |
120+
341 | ee_block = 0 | |-------------|
121+
| ee_len = 0 | | ... |
122+
| ee_start = 0 | |-------------|
123+
| nr_file = 12 | 14 | 0 |
124+
+----------------+ +-------------+
120125
121126
```
122127
- For a file, it lists the extents that hold the actual data of the file.
123128
Given that block IDs are stored as values of `sizeof(struct simplefs_extent)`
124129
bytes, a single block can accommodate up to 341 links. This limitation
125130
restricts the maximum size of a file to approximately 10.65 MiB (10,912 KiB).
126131
```
127-
inode
128-
+-----------------------+
129-
| i_mode = IFDIR | 0644 | block 93
130-
| ei_block = 93 ----|------> +----------------+
131-
| i_size = 10 KiB | 0 | ee_block = 0 |
132-
| i_blocks = 25 | | ee_len = 8 | extent 94
132+
inode
133+
+-----------------------+
134+
| i_mode = IFDIR | 0644 | block 93
135+
| ei_block = 93 ----|------> +----------------+
136+
| i_size = 10 KiB | 0 | ee_block = 0 |
137+
| i_blocks = 25 | | ee_len = 8 | extent 94
133138
+-----------------------+ | ee_start = 94 |---> +--------+
134-
|----------------| | |
139+
|----------------| | |
135140
1 | ee_block = 8 | +--------+
136141
| ee_len = 8 | extent 99
137-
| ee_start = 99 |---> +--------+
142+
| ee_start = 99 |---> +--------+
138143
|----------------| | |
139144
2 | ee_block = 16 | +--------+
140-
| ee_len = 8 | extent 66
145+
| ee_len = 8 | extent 66
141146
| ee_start = 66 |---> +--------+
142147
|----------------| | |
143148
| ... | +--------+
144-
|----------------|
145-
341 | ee_block = 0 |
149+
|----------------|
150+
341 | ee_block = 0 |
146151
| ee_len = 0 |
147152
| ee_start = 0 |
148153
+----------------+
@@ -158,8 +163,8 @@ comprises three members:
158163

159164
```
160165
struct simplefs_extent
161-
+----------------+
162-
| ee_block = 0 |
166+
+----------------+
167+
| ee_block = 0 |
163168
| ee_len = 200| extent
164169
| ee_start = 12 |-----------> +---------+
165170
+----------------+ block 12 | |
@@ -181,7 +186,7 @@ The journaling support in simplefs is implemented using the jbd2 subsystem, whic
181186

182187
For a detailed introduction to journaling, please refer to these two websites:
183188
[Journal(jbd2) document](https://www.kernel.org/doc/html/latest/filesystems/ext4/journal.html)
184-
[Journal(jbd2) api](https://docs.kernel.org/filesystems/journalling.html)
189+
[Journal(jbd2) api](https://docs.kernel.org/filesystems/journalling.html)
185190

186191
External journal device disk layout:
187192

@@ -193,12 +198,12 @@ Hint:
193198
Each transaction starts with a descriptor block, followed by several metadata blocks or data blocks, and ends with a commit block. Every modified metadata (such as inode, bitmap, etc.) occupies its own block. Currently, simplefs primarily records "extent" metadata.
194199

195200

196-
How to Enable Journaling in simplefs:
201+
How to Enable Journaling in simplefs:
197202

198203
Step 1: Create the Journal Disk Image
199204
To create an 8MB disk image for the journal, use the following make command:
200205

201-
Note:
206+
Note:
202207
Assuming an 8 MB size for the external journal device, which is an arbitrary choice for now, I will set the journal block length to a fixed 2048, calculated by dividing the device size by the block size (4096 bytes).
203208

204209
```shell

bitmap.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,9 @@ static inline uint32_t get_free_blocks(struct super_block *sb, uint32_t len)
5252
return 0;
5353

5454
sbi->nr_free_blocks -= len;
55+
struct buffer_head *bh;
5556
for (i = 0; i < len; i++) {
56-
struct buffer_head *bh = sb_bread(sb, ret + i);
57+
bh = sb_bread(sb, ret + i);
5758
if (!bh) {
5859
pr_err("get_free_blocks: sb_bread failed for block %d\n", ret + i);
5960
sbi->nr_free_blocks += len;

dir.c

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ static int simplefs_iterate(struct file *dir, struct dir_context *ctx)
1919
struct buffer_head *bh = NULL, *bh2 = NULL;
2020
struct simplefs_file_ei_block *eblock = NULL;
2121
struct simplefs_dir_block *dblock = NULL;
22-
struct simplefs_file *f = NULL;
2322
int ei = 0, bi = 0, fi = 0;
2423
int ret = 0;
2524

@@ -43,36 +42,62 @@ static int simplefs_iterate(struct file *dir, struct dir_context *ctx)
4342
return -EIO;
4443
eblock = (struct simplefs_file_ei_block *) bh->b_data;
4544

46-
ei = (ctx->pos - 2) / SIMPLEFS_FILES_PER_EXT;
47-
bi = (ctx->pos - 2) % SIMPLEFS_FILES_PER_EXT / SIMPLEFS_FILES_PER_BLOCK;
48-
fi = (ctx->pos - 2) % SIMPLEFS_FILES_PER_BLOCK;
45+
if (ctx->pos - 2 == eblock->nr_files)
46+
goto release_bh;
4947

50-
/* Iterate over the index block and commit subfiles */
51-
for (; ei < SIMPLEFS_MAX_EXTENTS; ei++) {
48+
int remained_nr_files = eblock->nr_files - (ctx->pos - 2);
49+
50+
int offset = ctx->pos - 2;
51+
for (ei = 0; ei < SIMPLEFS_MAX_EXTENTS; ei++) {
5252
if (eblock->extents[ei].ee_start == 0)
53+
continue;
54+
if (offset > eblock->extents[ei].nr_files) {
55+
offset -= eblock->extents[ei].nr_files;
56+
} else {
5357
break;
58+
}
59+
}
60+
61+
/* Iterate over the index block and commit subfiles */
62+
for (; remained_nr_files && ei < SIMPLEFS_MAX_EXTENTS; ei++) {
63+
if (eblock->extents[ei].ee_start == 0)
64+
continue;
5465

5566
/* Iterate over blocks in one extent */
56-
for (; bi < eblock->extents[ei].ee_len; bi++) {
67+
for (bi = 0; bi < eblock->extents[ei].ee_len && remained_nr_files;
68+
bi++) {
5769
bh2 = sb_bread(sb, eblock->extents[ei].ee_start + bi);
5870
if (!bh2) {
5971
ret = -EIO;
6072
goto release_bh;
6173
}
6274
dblock = (struct simplefs_dir_block *) bh2->b_data;
63-
if (dblock->files[0].inode == 0) {
75+
76+
if (offset > dblock->nr_files) {
77+
offset -= dblock->nr_files;
6478
brelse(bh2);
6579
bh2 = NULL;
66-
break;
80+
continue;
6781
}
68-
/* Iterate every file in one block */
69-
for (; fi < SIMPLEFS_FILES_PER_BLOCK; fi++) {
70-
f = &dblock->files[fi];
71-
if (f->inode &&
72-
!dir_emit(ctx, f->filename, SIMPLEFS_FILENAME_LEN, f->inode,
73-
DT_UNKNOWN))
74-
break;
75-
ctx->pos++;
82+
83+
for (fi = 0; fi < SIMPLEFS_FILES_PER_BLOCK;) {
84+
if (dblock->files[fi].inode != 0) {
85+
if (offset) {
86+
offset--;
87+
} else {
88+
remained_nr_files--;
89+
if (!dir_emit(ctx, dblock->files[fi].filename,
90+
SIMPLEFS_FILENAME_LEN,
91+
dblock->files[fi].inode, DT_UNKNOWN)) {
92+
brelse(bh2);
93+
bh2 = NULL;
94+
goto release_bh;
95+
}
96+
97+
ctx->pos++;
98+
}
99+
}
100+
fi += dblock->files[fi].nr_blk;
76101
}
77102
brelse(bh2);
78103
bh2 = NULL;

file.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,14 @@ static int simplefs_file_get_block(struct inode *inode,
5151
ret = 0;
5252
goto brelse_index;
5353
}
54-
bno = get_free_blocks(sb, 8);
54+
bno = get_free_blocks(sb, SIMPLEFS_MAX_BLOCKS_PER_EXTENT);
5555
if (!bno) {
5656
ret = -ENOSPC;
5757
goto brelse_index;
5858
}
5959

6060
index->extents[extent].ee_start = bno;
61-
index->extents[extent].ee_len = 8;
61+
index->extents[extent].ee_len = SIMPLEFS_MAX_BLOCKS_PER_EXTENT;
6262
index->extents[extent].ee_block =
6363
extent ? index->extents[extent - 1].ee_block +
6464
index->extents[extent - 1].ee_len
@@ -386,13 +386,13 @@ static ssize_t simplefs_write(struct file *file,
386386
while (len > 0) {
387387
/* check if block is allocated */
388388
if (ei_block->extents[ei_index].ee_start == 0) {
389-
int bno = get_free_blocks(sb, 8);
389+
int bno = get_free_blocks(sb, SIMPLEFS_MAX_BLOCKS_PER_EXTENT);
390390
if (!bno) {
391391
bytes_write = -ENOSPC;
392392
break;
393393
}
394394
ei_block->extents[ei_index].ee_start = bno;
395-
ei_block->extents[ei_index].ee_len = 8;
395+
ei_block->extents[ei_index].ee_len = SIMPLEFS_MAX_BLOCKS_PER_EXTENT;
396396
ei_block->extents[ei_index].ee_block =
397397
ei_index ? ei_block->extents[ei_index - 1].ee_block +
398398
ei_block->extents[ei_index - 1].ee_len

0 commit comments

Comments
 (0)