forked from waleedmazhar/linux-ftools
-
Notifications
You must be signed in to change notification settings - Fork 0
/
linux-fallocate.c
126 lines (91 loc) · 3.18 KB
/
linux-fallocate.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
#include <linux/falloc.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <asm/unistd_64.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <linux-ftools.h>
/*
-
*/
/**
SYNTAX: fallocate file length
fallocate() allows the caller to directly manipulate the allocated disk space
for the file referred to by fd for the byte range starting at offset and
continuing for len bytes.
The mode argument determines the operation to be performed on the given
range. Currently only one flag is supported for mode:
FALLOC_FL_KEEP_SIZE
This flag allocates and initializes to zero the disk space within the range
specified by offset and len. After a successful call, subsequent writes into
this range are guaranteed not to fail because of lack of disk
space. Preallocating zeroed blocks beyond the end of the file is useful for
optimizing append workloads. Preallocating blocks does not change the file size
(as reported by stat(2)) even if it is less than offset+len.
If FALLOC_FL_KEEP_SIZE flag is not specified in mode, the default behavior is
almost same as when this flag is specified. The only difference is that on
success, the file size will be changed if offset + len is greater than the file
size. This default behavior closely resembles the behavior of the
posix_fallocate(3) library function, and is intended as a method of optimally
implementing that function.
Because allocation is done in block size chunks, fallocate() may allocate a
larger range than that which was specified.
*/
void logstats(int fd) {
struct stat fd_stat ;
if ( fstat( fd, &fd_stat ) < 0 ) {
perror( "Could not stat file" );
exit(1);
}
printf( "File stats: \n" );
printf( " Length: %ld\n", fd_stat.st_size );
printf( " Block size: %ld\n", fd_stat.st_blksize );
printf( " Blocks allocated: %ld\n" , fd_stat.st_blocks );
}
int main(int argc, char *argv[]) {
if ( argc != 3 ) {
fprintf( stderr, "%s version %s\n", argv[0], LINUX_FTOOLS_VERSION );
fprintf( stderr, "SYNTAX: fallocate file length\n" );
exit(1);
}
char* path = argv[1];
printf( "Going to fallocate %s\n", path );
int flags = O_RDWR;
int fd = open( path, flags );
if ( fd == -1 ) {
perror( "Unable to open file" );
exit(1);
}
logstats(fd);
loff_t len = atol( argv[2] );
printf( "Increasing file to: %ld\n", len );
if ( len <= 0 ) {
fprintf( stderr, "Unable to allocate size %ld\n", len );
exit( 1 );
}
loff_t offset = 0;
//TODO: make this a command line option.
int mode = FALLOC_FL_KEEP_SIZE;
long result = syscall( SYS_fallocate, fd, mode, offset, len );
if ( result != 0 ) {
//TODO: rework this error handling
if ( result != -1 ) {
errno=result;
perror( "Unable to fallocate" );
exit( 1 );
} else {
char buff[100];
sprintf( buff, "Unable to fallocate: %ld" , result );
perror( buff );
exit( 1 );
}
return 1;
}
logstats(fd);
close( fd );
return 0;
}