Mercurial > dovecot > original-hg > dovecot-1.2
annotate src/lib/file-set-size.c @ 9191:b340ecb24469 HEAD
Fix VPATH build of RQUOTA support.
Some rpcgen derive #include "..." paths from the infile argument.
This will be off for VPATH builds, as the generated rquota_xdr.c
code will look in $(srcdir), but we'll generate the rquota.h file in
$(builddir). Play safe and copy rquota.x to $(builddir) first.
This fixes the build on openSUSE 11.1.
author | Matthias Andree <matthias.andree@gmx.de> |
---|---|
date | Tue, 07 Jul 2009 21:01:36 +0200 |
parents | b9faf4db2a9f |
children | de52dfd93516 |
rev | line source |
---|---|
8590
b9faf4db2a9f
Updated copyright notices to include year 2009.
Timo Sirainen <tss@iki.fi>
parents:
8228
diff
changeset
|
1 /* Copyright (c) 2002-2009 Dovecot authors, see the included COPYING file */ |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
2 |
6623
dde1980eccae
We need to include config.h before checking HAVE_* macros.
Timo Sirainen <tss@iki.fi>
parents:
6622
diff
changeset
|
3 #ifdef HAVE_CONFIG_H |
dde1980eccae
We need to include config.h before checking HAVE_* macros.
Timo Sirainen <tss@iki.fi>
parents:
6622
diff
changeset
|
4 # include "config.h" |
dde1980eccae
We need to include config.h before checking HAVE_* macros.
Timo Sirainen <tss@iki.fi>
parents:
6622
diff
changeset
|
5 #endif |
dde1980eccae
We need to include config.h before checking HAVE_* macros.
Timo Sirainen <tss@iki.fi>
parents:
6622
diff
changeset
|
6 |
6622 | 7 #ifdef HAVE_POSIX_FALLOCATE |
8 # define _XOPEN_SOURCE 600 /* Required by glibc, breaks Solaris 9 */ | |
9 #endif | |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
10 #include "lib.h" |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
221
diff
changeset
|
11 #include "file-set-size.h" |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
12 |
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
13 #include <unistd.h> |
5456
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
14 #include <fcntl.h> |
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
15 #include <sys/stat.h> |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
16 |
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
17 int file_set_size(int fd, off_t size) |
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
18 { |
6585
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
19 #ifdef HAVE_POSIX_FALLOCATE |
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
20 static bool posix_fallocate_supported = TRUE; |
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
21 #endif |
5456
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
22 char block[4096]; |
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
23 off_t offset; |
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
24 ssize_t ret; |
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
25 struct stat st; |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
26 |
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
27 i_assert(size >= 0); |
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
28 |
6569
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
29 if (fstat(fd, &st) < 0) { |
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
30 i_error("fstat() failed: %m"); |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
31 return -1; |
6569
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
32 } |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
33 |
6569
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
34 if (size < st.st_size) { |
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
35 if (ftruncate(fd, size) < 0) { |
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
36 i_error("ftruncate() failed: %m"); |
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
37 return -1; |
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
38 } |
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
39 return 0; |
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
40 } |
5456
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
41 if (size == st.st_size) |
252
14bad0a48eb4
file_set_size() was buggy when it was supposed to shrink file
Timo Sirainen <tss@iki.fi>
parents:
222
diff
changeset
|
42 return 0; |
222
cf4d065f2f85
lots of cleanups. also index/datafile is now capable of staying in memory,
Timo Sirainen <tss@iki.fi>
parents:
221
diff
changeset
|
43 |
5456
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
44 #ifdef HAVE_POSIX_FALLOCATE |
6585
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
45 if (posix_fallocate_supported) { |
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
46 if (posix_fallocate(fd, st.st_size, size - st.st_size) == 0) |
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
47 return 0; |
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
48 |
8228
c9efd231a97f
Removed posix_fallocate() failure check for AIX.
Timo Sirainen <tss@iki.fi>
parents:
8207
diff
changeset
|
49 if (errno != EINVAL /* Solaris */) { |
6585
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
50 if (!ENOSPACE(errno)) |
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
51 i_error("posix_fallocate() failed: %m"); |
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
52 return -1; |
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
53 } |
8207
2442529e4cec
AIX: Silently ignore posix_fallocate() failures.
Timo Sirainen <tss@iki.fi>
parents:
7086
diff
changeset
|
54 /* Not supported by kernel, fallback to writing. */ |
6585
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
55 posix_fallocate_supported = FALSE; |
6569
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
56 } |
6585
a9dfe05dfadd
If posix_fallocate() returns EINVAL, fallback to writing.
Timo Sirainen <tss@iki.fi>
parents:
6569
diff
changeset
|
57 #endif |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
58 /* start growing the file */ |
5456
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
59 offset = st.st_size; |
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
60 memset(block, 0, I_MIN((ssize_t)sizeof(block), size - offset)); |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
61 |
5456
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
62 while (offset < size) { |
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
63 ret = pwrite(fd, block, |
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
64 I_MIN((ssize_t)sizeof(block), size - offset), |
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
65 offset); |
6569
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
66 if (ret < 0) { |
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
67 if (!ENOSPACE(errno)) |
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
68 i_error("pwrite() failed: %m"); |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
69 return -1; |
6569
b7d8695d864d
If file_set_size() fails for any other reason than "not enough disk
Timo Sirainen <tss@iki.fi>
parents:
6429
diff
changeset
|
70 } |
5456
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
71 offset += size; |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
72 } |
5456
3660736f8163
Use posix_fallocate() if possible. Also did minor optimizations to the
Timo Sirainen <tss@iki.fi>
parents:
1741
diff
changeset
|
73 return 0; |
221
ed0d5b17c7a4
Added extra functions for easier printing of error messages. Moved
Timo Sirainen <tss@iki.fi>
parents:
diff
changeset
|
74 } |