From 0cdf4dacf5cf451d8d9379b50a0ce75f92e31b7d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 2 Dec 2010 12:30:55 -0800 Subject: [PATCH] Fix bug #7835 - vfs_fill_sparse() doesn't use posix_fallocate when strict allocate is on Tries posix_fallocate() and then falls back to old code. Jeremy. --- source3/smbd/vfs.c | 31 +++++++++++++++++++++++++++++-- 1 files changed, 29 insertions(+), 2 deletions(-) diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 00cf1e5..ee34706 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -582,6 +582,12 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) return 0; } +#ifdef S_ISFIFO + if (S_ISFIFO(st.st_ex_mode)) { + return 0; + } +#endif + DEBUG(10,("vfs_fill_sparse: write zeros in file %s from len %.0f to " "len %.0f (%.0f bytes)\n", fsp_str_dbg(fsp), (double)st.st_ex_size, (double)len, @@ -591,6 +597,29 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) flush_write_cache(fsp, SIZECHANGE_FLUSH); + + offset = st.st_ex_size; + num_to_write = len - st.st_ex_size; + + /* for allocation try posix_fallocate first. This can fail on some + * platforms e.g. when the filesystem doesn't support it and no + * emulation is being done by the libc (like on AIX with JFS1). In that + * case we do our own emulation. posix_fallocate implementations can + * return ENOTSUP or EINVAL in cases like that. */ + ret = sys_posix_fallocate(fsp->fh->fd, offset, num_to_write); + if (ret == ENOSPC) { + errno = ENOSPC; + ret = -1; + goto out; + } + if (ret == 0) { + set_filelen_write_cache(fsp, len); + goto out; + } + + DEBUG(10,("vfs_fill_sparse: sys_posix_fallocate failed with " + "error %d. Falling back to slow manual allocation\n", ret)); + if (!sparse_buf) { sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE); if (!sparse_buf) { @@ -600,8 +629,6 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) } } - offset = st.st_ex_size; - num_to_write = len - st.st_ex_size; total = 0; while (total < num_to_write) { -- 1.7.3.1