diff options
author | Jeremy Allison <jra@samba.org> | 2010-12-02 17:26:00 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2010-12-03 02:55:05 +0100 |
commit | b8d7de319980f9efade92dd0721ed02efcb7e48d (patch) | |
tree | a37aff4ab5ececbf0ec6b4a9ee67a1de29cb65f4 /source3/smbd | |
parent | 1f1491da5ae2a2b7fd3a195f950b9057a01db18c (diff) | |
download | samba-b8d7de319980f9efade92dd0721ed02efcb7e48d.tar.gz samba-b8d7de319980f9efade92dd0721ed02efcb7e48d.tar.bz2 samba-b8d7de319980f9efade92dd0721ed02efcb7e48d.zip |
Merge the two conflicting allocation codes into one function, vfs_slow_fallocate()
and use that from both the truncate and fill_sparse functions.
Jeremy.
Diffstat (limited to 'source3/smbd')
-rw-r--r-- | source3/smbd/vfs.c | 79 |
1 files changed, 45 insertions, 34 deletions
diff --git a/source3/smbd/vfs.c b/source3/smbd/vfs.c index 1829e3ae42..a35142eab1 100644 --- a/source3/smbd/vfs.c +++ b/source3/smbd/vfs.c @@ -558,22 +558,56 @@ int vfs_set_filelen(files_struct *fsp, SMB_OFF_T len) } /**************************************************************************** + A slow version of posix_fallocate. Fallback code if SMB_VFS_POSIX_FALLOCATE + fails. Needs to be outside of the default version of SMB_VFS_POSIX_FALLOCATE + as this is also called from the default SMB_VFS_FTRUNCATE code. + Returns 0 on success, errno on failure. +****************************************************************************/ + +#define SPARSE_BUF_WRITE_SIZE (32*1024) + +int vfs_slow_fallocate(files_struct *fsp, SMB_OFF_T offset, SMB_OFF_T len) +{ + ssize_t pwrite_ret; + size_t total = 0; + + if (!sparse_buf) { + sparse_buf = SMB_CALLOC_ARRAY(char, SPARSE_BUF_WRITE_SIZE); + if (!sparse_buf) { + errno = ENOMEM; + return ENOMEM; + } + } + + while (total < len) { + size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (len - total)); + + pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total); + if (pwrite_ret == -1) { + DEBUG(10,("vfs_slow_fallocate: SMB_VFS_PWRITE for file " + "%s failed with error %s\n", + fsp_str_dbg(fsp), strerror(errno))); + return errno; + } + total += pwrite_ret; + } + + return 0; +} + +/**************************************************************************** A vfs fill sparse call. Writes zeros from the end of file to len, if len is greater than EOF. Used only by strict_sync. Returns 0 on success, -1 on failure. ****************************************************************************/ -#define SPARSE_BUF_WRITE_SIZE (32*1024) - int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) { int ret; SMB_STRUCT_STAT st; SMB_OFF_T offset; - size_t total; size_t num_to_write; - ssize_t pwrite_ret; ret = SMB_VFS_FSTAT(fsp, &st); if (ret == -1) { @@ -616,47 +650,24 @@ int vfs_fill_sparse(files_struct *fsp, SMB_OFF_T len) goto out; } if (ret == 0) { - set_filelen_write_cache(fsp, len); goto out; } DEBUG(10,("vfs_fill_sparse: SMB_VFS_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) { - errno = ENOMEM; - ret = -1; - goto out; - } + ret = vfs_slow_fallocate(fsp, offset, num_to_write); + if (ret != 0) { + errno = ret; + ret = -1; } - total = 0; - - while (total < num_to_write) { - size_t curr_write_size = MIN(SPARSE_BUF_WRITE_SIZE, (num_to_write - total)); - - pwrite_ret = SMB_VFS_PWRITE(fsp, sparse_buf, curr_write_size, offset + total); - if (pwrite_ret == -1) { - DEBUG(10,("vfs_fill_sparse: SMB_VFS_PWRITE for file " - "%s failed with error %s\n", - fsp_str_dbg(fsp), strerror(errno))); - ret = -1; - goto out; - } - if (pwrite_ret == 0) { - ret = 0; - goto out; - } + out: - total += pwrite_ret; + if (ret == 0) { + set_filelen_write_cache(fsp, len); } - set_filelen_write_cache(fsp, len); - - ret = 0; - out: contend_level2_oplocks_end(fsp, LEVEL2_CONTEND_FILL_SPARSE); return ret; } |