Skip to content

Commit 6035a76

Browse files
committed
Reclaim extent block when removing non-root dir
When removing a directory, the extent block was not reclaimed properly. This fix ensures that extent blocks for non-root directories are reclaimed during removal. The root directory is excluded from this process, as it serves as the mount point and cannot be removed. The reclaim mechanism is designed to run when a directory is actually removed, not just when it becomes empty. close #65
1 parent 4645f7a commit 6035a76

File tree

3 files changed

+45
-22
lines changed

3 files changed

+45
-22
lines changed

inode.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -603,8 +603,6 @@ static int simplefs_unlink(struct inode *dir, struct dentry *dentry)
603603
if (!bh)
604604
goto clean_inode;
605605
file_block = (struct simplefs_file_ei_block *) bh->b_data;
606-
if (S_ISDIR(inode->i_mode))
607-
goto scrub;
608606

609607
for (ei = 0; ei < SIMPLEFS_MAX_EXTENTS; ei++) {
610608
char *block;
@@ -627,7 +625,6 @@ static int simplefs_unlink(struct inode *dir, struct dentry *dentry)
627625
}
628626
}
629627

630-
scrub:
631628
/* Scrub index block */
632629
memset(file_block, 0, SIMPLEFS_BLOCK_SIZE);
633630
mark_buffer_dirty(bh);

script/test.sh

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#!/usr/bin/env bash
22

3+
. script/test_large_file.sh
4+
35
SIMPLEFS_MOD=simplefs.ko
46
IMAGE=$1
57
IMAGESIZE=$2
@@ -47,13 +49,6 @@ dd if=/dev/zero of=$IMAGE bs=1M count=$IMAGESIZE status=none && \
4749
sudo mount -t simplefs -o loop $IMAGE test && \
4850
pushd test >/dev/null
4951

50-
# mkdir
51-
test_op 'mkdir dir'
52-
test_op 'mkdir dir' # expected to fail
53-
54-
# create file
55-
test_op 'touch file'
56-
5752
# create 40920 files
5853
for ((i=0; i<=$MAXFILES; i++))
5954
do
@@ -98,6 +93,21 @@ do
9893
fi
9994
done
10095
find . -name 'file_[0-9]*.txt' | xargs sudo rm || { echo "Failed to delete files"; exit 1; }
96+
sync
97+
98+
popd >/dev/null || { echo "popd failed"; exit 1; }
99+
ls test -laR
100+
rm test/* -rf
101+
nr_free_blk=$(($(dd if=$IMAGE bs=1 skip=28 count=4 2>/dev/null | hexdump -v -e '1/4 "0x%08x\n"')))
102+
echo "$nr_free_blk"
103+
pushd test >/dev/null || { echo "pushd failed"; exit 1; }
104+
105+
# mkdir
106+
test_op 'mkdir dir'
107+
test_op 'mkdir dir' # expected to fail
108+
109+
# create file
110+
test_op 'touch file'
101111

102112
# hard link
103113
test_op 'ln file hdlink'
@@ -119,21 +129,11 @@ test_op 'echo abc > file'
119129
test $(cat file) = "abc" || echo "Failed to write"
120130

121131
# file too large
122-
test_op 'dd if=/dev/zero of=file bs=1M count=12 status=none'
123-
filesize=$(sudo ls -lR | grep -e "$F_MOD 2".*file | awk '{print $5}')
124-
test $filesize -le $MAXFILESIZE || echo "Failed, file size over the limit"
132+
test_too_large_file
125133

126134
# Write the file size larger than BLOCK_SIZE
127135
# test serial to write
128-
test_op 'printf \"%.0s123456789\" {1..1600} > file.txt'
129-
count=$(awk '{count += gsub(/123456789/, "")} END {print count}' "file.txt")
130-
echo "test $count"
131-
test "$count" -eq 1600 || echo "Failed, file size not matching"
132-
# test block to write
133-
test_op 'cat file.txt > checkfile.txt'
134-
count=$(awk '{count += gsub(/123456789/, "")} END {print count}' "checkfile.txt")
135-
echo "test $count"
136-
test "$count" -eq 1600 || echo "Failed, file size not matching"
136+
test_file_size_larger_than_block_size
137137

138138
# test remove symbolic link
139139
test_op 'ln -s file symlink_fake'
@@ -152,7 +152,13 @@ check_exist $S_MOD 1 symlink
152152
check_exist $F_MOD 1 symlink_fake
153153
check_exist $F_MOD 1 symlink_hard_fake
154154

155+
# clean all files and directories
156+
test_op 'rm -rf ./*'
157+
155158
sleep 1
156159
popd >/dev/null
157160
sudo umount test
158161
sudo rmmod simplefs
162+
163+
af_nr_free_blk=$(($(dd if=$IMAGE bs=1 skip=28 count=4 2>/dev/null | hexdump -v -e '1/4 "0x%08x\n"')))
164+
test $nr_free_blk -eq $af_nr_free_blk || echo "Failed, some blocks are not be reclaimed"

script/test_large_file.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# file too large
2+
test_too_large_file() {
3+
test_op 'dd if=/dev/zero of=file bs=1M count=12 status=none'
4+
filesize=$(sudo ls -lR | grep -e "$F_MOD 2".*file | awk '{print $5}')
5+
test $filesize -le $MAXFILESIZE || echo "Failed, file size over the limit"
6+
}
7+
8+
# Write the file size larger than BLOCK_SIZE
9+
# test serial to write
10+
test_file_size_larger_than_block_size() {
11+
test_op 'yes 123456789 | head -n 1600 | tr -d "\n" > file.txt'
12+
count=$(awk '{count += gsub(/123456789/, "")} END {print count}' "file.txt")
13+
echo "test $count"
14+
test "$count" -eq 1600 || echo "Failed, file size not matching"
15+
# test block to write
16+
test_op 'cat file.txt > checkfile.txt'
17+
count=$(awk '{count += gsub(/123456789/, "")} END {print count}' "checkfile.txt")
18+
echo "test $count"
19+
test "$count" -eq 1600 || echo "Failed, file size not matching"
20+
}

0 commit comments

Comments
 (0)