mirror of
https://github.com/linux-apfs/apfstests.git
synced 2026-05-01 15:01:44 -07:00
Add a test program to exercise a specific bug - racing unlink/write on a full filesystem
This commit is contained in:
+1
-1
@@ -37,7 +37,7 @@ TARGETS = alloc acl_get bstat devzero dirstress fault feature \
|
||||
fill fill2 getpagesize holes xfsctl loggen lstat64 \
|
||||
nametest permname randholes runas truncfile usemem \
|
||||
fstest mmapcat append_reader append_writer \
|
||||
dirperf metaperf
|
||||
dirperf metaperf enospc_unlink
|
||||
ifeq ($(ENABLE_DBM), yes)
|
||||
TARGETS += dbtest
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Write a file until filesystem full is reached and then unlink it.
|
||||
* Demonstrates a particular deadlock that Kaz hit in testing. Run
|
||||
* several iterations of this in parallel on a near-full filesystem.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <malloc.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int fd, sz, done;
|
||||
void *ptr;
|
||||
size_t written;
|
||||
unsigned int i, count = 0;
|
||||
unsigned long long bytes = 0;
|
||||
|
||||
if (argc < 2) {
|
||||
fprintf(stderr, "Insufficient arguments\n");
|
||||
exit(1);
|
||||
}
|
||||
if (argc < 3) {
|
||||
count = (unsigned int)atoi(argv[2]);
|
||||
}
|
||||
|
||||
sz = 1024 * 1024;
|
||||
|
||||
ptr = memalign(sz, sz);
|
||||
if (!ptr) {
|
||||
perror("memalign");
|
||||
exit(1);
|
||||
}
|
||||
memset(ptr, 0xffffffff, sz);
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
fd = open(argv[1], O_CREAT|O_WRONLY);
|
||||
if (fd < 0) {
|
||||
perror(argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
done = 0;
|
||||
while (!done) {
|
||||
written = write(fd, ptr, sz);
|
||||
if (written == -1) {
|
||||
if (errno == ENOSPC) {
|
||||
close(fd);
|
||||
unlink(argv[1]);
|
||||
printf("Unlinked %s\n", argv[1]);
|
||||
done = 1;
|
||||
}
|
||||
else {
|
||||
printf("Skipped unlink %s (%s)\n",
|
||||
argv[1], strerror(errno));
|
||||
done = -1;
|
||||
}
|
||||
}
|
||||
if (written == 0) {
|
||||
printf("Wrote zero bytes?\n");
|
||||
done = -1;
|
||||
}
|
||||
bytes += written;
|
||||
}
|
||||
if (done > 0)
|
||||
printf("Wrote %llu bytes total.\n", bytes);
|
||||
else
|
||||
exit(1);
|
||||
}
|
||||
printf("Completed %u iterations of unlink/out-of-space test.\n", i);
|
||||
exit(0);
|
||||
}
|
||||
Reference in New Issue
Block a user