diff options
author | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2007-07-12 18:26:36 +0000 |
commit | 0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (patch) | |
tree | 2ea1f8305970753e4a657acb2ccc15ca3eec8e2c /sysdeps/posix/posix_fallocate.c | |
parent | 7d58530341304d403a6626d7f7a1913165fe2f32 (diff) | |
download | glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.gz glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.tar.xz glibc-0ecb606cb6cf65de1d9fc8a919bceb4be476c602.zip |
2.5-18.1
Diffstat (limited to 'sysdeps/posix/posix_fallocate.c')
-rw-r--r-- | sysdeps/posix/posix_fallocate.c | 43 |
1 files changed, 33 insertions, 10 deletions
diff --git a/sysdeps/posix/posix_fallocate.c b/sysdeps/posix/posix_fallocate.c index 838e7a004a..cbaeb49487 100644 --- a/sysdeps/posix/posix_fallocate.c +++ b/sysdeps/posix/posix_fallocate.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2003 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2003, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. The GNU C Library is free software; you can redistribute it and/or @@ -29,9 +29,8 @@ posix_fallocate (int fd, __off_t offset, __off_t len) { struct stat64 st; struct statfs f; - size_t step; - /* `off_tī is a signed type. Therefore we can determine whether + /* `off_t' is a signed type. Therefore we can determine whether OFFSET + LEN is too large if it is a negative value. */ if (offset < 0 || len < 0) return EINVAL; @@ -47,24 +46,48 @@ posix_fallocate (int fd, __off_t offset, __off_t len) if (! S_ISREG (st.st_mode)) return ENODEV; + if (len == 0) + { + if (st.st_size < offset) + { + int ret = __ftruncate (fd, offset); + + if (ret != 0) + ret = errno; + return ret; + } + return 0; + } + /* We have to know the block size of the filesystem to get at least some sort of performance. */ if (__fstatfs (fd, &f) != 0) return errno; - /* Align OFFSET to block size and adjust LEN. */ - step = (offset + f.f_bsize - 1) % ~f.f_bsize; - offset += step; + /* Try to play safe. */ + if (f.f_bsize == 0) + f.f_bsize = 512; /* Write something to every block. */ - while (len > step) + for (offset += (len - 1) % f.f_bsize; len > 0; offset += f.f_bsize) { - len -= step; + len -= f.f_bsize; + + if (offset < st.st_size) + { + unsigned char c; + ssize_t rsize = __pread (fd, &c, 1, offset); + + if (rsize < 0) + return errno; + /* If there is a non-zero byte, the block must have been + allocated already. */ + else if (rsize == 1 && c != 0) + continue; + } if (__pwrite (fd, "", 1, offset) != 1) return errno; - - offset += step; } return 0; |