diff options
Diffstat (limited to 'sysdeps/posix/posix_fallocate.c')
-rw-r--r-- | sysdeps/posix/posix_fallocate.c | 43 |
1 files changed, 10 insertions, 33 deletions
diff --git a/sysdeps/posix/posix_fallocate.c b/sysdeps/posix/posix_fallocate.c index cbaeb49487..838e7a004a 100644 --- a/sysdeps/posix/posix_fallocate.c +++ b/sysdeps/posix/posix_fallocate.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000, 2003, 2005 Free Software Foundation, Inc. +/* Copyright (C) 2000, 2003 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,8 +29,9 @@ 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; @@ -46,48 +47,24 @@ 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; - /* Try to play safe. */ - if (f.f_bsize == 0) - f.f_bsize = 512; + /* Align OFFSET to block size and adjust LEN. */ + step = (offset + f.f_bsize - 1) % ~f.f_bsize; + offset += step; /* Write something to every block. */ - for (offset += (len - 1) % f.f_bsize; len > 0; offset += f.f_bsize) + while (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; - } + len -= step; if (__pwrite (fd, "", 1, offset) != 1) return errno; + + offset += step; } return 0; |