-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdc2.c
91 lines (76 loc) · 2.66 KB
/
dc2.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <assert.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
#include <sys/time.h>
#define BUF_SIZE 1024
char* get_rand_data_buf();
// let "c1" is our mountpoint
// The test simulate the truncate call causes data corruption in block cache when truncate happened while other file handle is not closed.
// If you want to simulate the test, Set the timouts to zero for attribute cache for FUSE library cozz once truncate
// call returns success kernel updates its attribute cache with size set in truncate.
int main() {
int writeFD;
char* buffer = get_rand_data_buf(); // intialising the buffer with some garbage data
ssize_t bytesRead, bytesWritten;
// Open/Create the file for writing.
writeFD = open("c1/foo", O_WRONLY | O_TRUNC | O_CREAT, 0777);
if (writeFD == -1) {
perror("Failed to open file");
exit(EXIT_FAILURE);
}
// Write at the start of the file
bytesWritten = write(writeFD, buffer, BUF_SIZE);
printf("write fd: %d\n", writeFD);
// Truncate the file to 4096 bytes
if (ftruncate(writeFD, 4096) == -1) {
perror("Truncate failed\n");
} else {
printf("Truncate is Success\n");
}
// The above truncate call go directly to azure storage and modify the file to size 4096.
// Close the file handles
close(writeFD);
// Now when we are closing the file it dont have the context that truncate call happened.
// The handle only knows that file size is 1024 so it will again modify the filesize to 1024.
// lets check the size of the file.
struct stat st;
if (stat("c1/foo", &st) == 0) {
printf("Size of the file: %ld bytes\n", st.st_size);
assert(st.st_size == 4096);
// The above assertion would fail and the size it prints is 1024.
} else {
perror("stat failed");
}
return EXIT_SUCCESS;
}
char* get_rand_data_buf() {
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
long current_time = ts.tv_nsec;
srandom(current_time);
char* allocatedMemory = (char *) malloc(BUF_SIZE);
for (int bufferIndex = 0; bufferIndex < BUF_SIZE; bufferIndex++) {
uint8_t randomNumber = (uint8_t) random();
allocatedMemory[bufferIndex] = randomNumber;
}
return allocatedMemory;
}
/*
Output of the program by block cache:
write fd: 3
Truncate is Success
Size of the file: 1024 bytes
dc2: dc2.c:51: main: Assertion `st.st_size == 4096' failed.
Aborted (core dumped)
Output of the program by std file system:
write fd: 3
Truncate is Success
Size of the file: 4096 bytes
*/